use of gov.sandia.n2a.eqset.EquationSet.ConnectionBinding in project n2a by frothga.
the class JobC method generateDeclarationsLocal.
public void generateDeclarationsLocal(EquationSet s, StringBuilder result) {
BackendDataC bed = (BackendDataC) s.backendData;
// Unit class
result.append("class " + prefix(s) + " : public PartTime<" + T + ">\n");
result.append("{\n");
result.append("public:\n");
// Unit buffers
if (bed.needLocalDerivative) {
result.append(" class Derivative\n");
result.append(" {\n");
result.append(" public:\n");
for (Variable v : bed.localDerivative) {
result.append(" " + type(v) + " " + mangle(v) + ";\n");
}
result.append(" Derivative * next;\n");
result.append(" };\n");
result.append("\n");
}
if (bed.needLocalPreserve) {
result.append(" class Preserve\n");
result.append(" {\n");
result.append(" public:\n");
for (Variable v : bed.localIntegrated) {
result.append(" " + type(v) + " " + mangle(v) + ";\n");
}
for (Variable v : bed.localDerivativePreserve) {
result.append(" " + type(v) + " " + mangle(v) + ";\n");
}
for (Variable v : bed.localBufferedExternalWriteDerivative) {
result.append(" " + type(v) + " " + mangle("next_", v) + ";\n");
}
result.append(" };\n");
result.append("\n");
}
// Unit variables
if (bed.needLocalDerivative) {
result.append(" Derivative * stackDerivative;\n");
}
if (bed.needLocalPreserve) {
result.append(" Preserve * preserve;\n");
}
if (bed.pathToContainer == null) {
result.append(" " + prefix(s.container) + " * container;\n");
}
if (s.connectionBindings != null) {
for (ConnectionBinding c : s.connectionBindings) {
// we should be able to assume that s.container is non-null; ie: a connection should always operate in some larger container
result.append(" " + prefix(c.endpoint) + " * " + mangle(c.alias) + ";\n");
}
}
if (s.accountableConnections != null) {
for (EquationSet.AccountableConnection ac : s.accountableConnections) {
result.append(" int " + prefix(ac.connection) + "_" + mangle(ac.alias) + "_count;\n");
}
}
if (bed.refcount) {
result.append(" int refcount;\n");
}
if (bed.index != null) {
result.append(" int __24index;\n");
}
if (bed.lastT) {
// $lastT is for internal use only, so no need for __24 prefix.
result.append(" " + T + " lastT;\n");
}
for (Variable v : bed.localMembers) {
result.append(" " + type(v) + " " + mangle(v) + ";\n");
}
for (Variable v : bed.localBufferedExternal) {
result.append(" " + type(v) + " " + mangle("next_", v) + ";\n");
}
for (EquationSet p : s.parts) {
result.append(" " + prefix(p) + "_Population " + mangle(p.name) + ";\n");
}
for (String columnName : bed.localColumns) {
result.append(" String " + columnName + ";\n");
}
for (EventSource es : bed.eventSources) {
String eventMonitor = "eventMonitor_" + prefix(es.target.container);
if (es.monitorIndex > 0)
eventMonitor += "_" + es.monitorIndex;
result.append(" std::vector<Part<" + T + "> *> " + eventMonitor + ";\n");
}
for (EventTarget et : bed.eventTargets) {
if (!et.trackOne && et.edge != EventTarget.NONZERO) {
result.append(" " + T + " " + mangle(et.track.name) + ";\n");
}
if (et.timeIndex >= 0) {
result.append(" " + T + " eventTime" + et.timeIndex + ";\n");
}
}
if (!bed.localFlagType.isEmpty()) {
result.append(" " + bed.localFlagType + " flags;\n");
}
int i = 0;
for (Delay d : bed.delays) {
d.index = i++;
result.append(" DelayBuffer<" + T + "> delay" + d.index + ";\n");
}
result.append("\n");
// Unit functions
if (bed.needLocalCtor) {
result.append(" " + prefix(s) + " ();\n");
}
if (bed.needLocalDtor) {
result.append(" virtual ~" + prefix(s) + " ();\n");
}
if (bed.localMembers.size() > 0) {
result.append(" virtual void clear ();\n");
}
if (s.container == null) {
result.append(" virtual void setPeriod (" + T + " dt);\n");
}
if (bed.needLocalDie) {
result.append(" virtual void die ();\n");
}
if (bed.localReference.size() > 0) {
result.append(" virtual void enterSimulation ();\n");
}
result.append(" virtual void leaveSimulation ();\n");
if (bed.refcount) {
result.append(" virtual bool isFree ();\n");
}
if (bed.needLocalInit) {
result.append(" virtual void init ();\n");
}
if (bed.needLocalIntegrate) {
result.append(" virtual void integrate ();\n");
}
if (bed.needLocalUpdate) {
result.append(" virtual void update ();\n");
}
if (bed.needLocalFinalize) {
result.append(" virtual bool finalize ();\n");
}
if (bed.needLocalUpdateDerivative) {
result.append(" virtual void updateDerivative ();\n");
}
if (bed.needLocalFinalizeDerivative) {
result.append(" virtual void finalizeDerivative ();\n");
}
if (bed.needLocalPreserve) {
result.append(" virtual void snapshot ();\n");
result.append(" virtual void restore ();\n");
}
if (bed.needLocalDerivative) {
result.append(" virtual void pushDerivative ();\n");
result.append(" virtual void multiplyAddToStack (" + T + " scalar);\n");
result.append(" virtual void multiply (" + T + " scalar);\n");
result.append(" virtual void addToMembers ();\n");
}
if (bed.live != null && !bed.live.hasAttribute("constant")) {
result.append(" virtual " + T + " getLive ();\n");
}
if (bed.xyz != null && s.connected) {
result.append(" virtual void getXYZ (MatrixFixed<" + T + ",3,1> & xyz);\n");
}
if (s.connectionBindings != null) {
if (bed.p != null) {
result.append(" virtual " + T + " getP ();\n");
}
if (bed.hasProject) {
result.append(" virtual void getProject (int i, MatrixFixed<" + T + ",3,1> & xyz);\n");
}
result.append(" virtual void setPart (int i, Part<" + T + "> * part);\n");
result.append(" virtual Part<" + T + "> * getPart (int i);\n");
}
if (bed.newborn >= 0) {
result.append(" virtual bool getNewborn ();\n");
}
if (s.connectionMatrix != null && s.connectionMatrix.needsMapping) {
result.append(" virtual int mapIndex (int i, int rc);\n");
}
if (bed.eventTargets.size() > 0) {
result.append(" virtual bool eventTest (int i);\n");
if (bed.needLocalEventDelay) {
result.append(" virtual " + T + " eventDelay (int i);\n");
}
result.append(" virtual void setLatch (int i);\n");
if (bed.eventReferences.size() > 0) {
result.append(" virtual void finalizeEvent ();\n");
}
}
if (bed.accountableEndpoints.size() > 0) {
result.append(" virtual int getCount (int i);\n");
}
if (bed.needLocalPath) {
result.append(" virtual void path (String & result);\n");
}
// Conversions
Set<Conversion> conversions = s.getConversions();
for (Conversion pair : conversions) {
EquationSet source = pair.from;
EquationSet dest = pair.to;
result.append(" void " + mangle(source.name) + "_2_" + mangle(dest.name) + " (" + mangle(source.name) + " * from, int " + mangle("$type") + ");\n");
}
// Unit class trailer
result.append("};\n");
result.append("\n");
}
use of gov.sandia.n2a.eqset.EquationSet.ConnectionBinding in project n2a by frothga.
the class InternalBackendData method analyze.
public void analyze(final EquationSet s) {
boolean headless = AppData.properties.getBoolean("headless");
if (!headless)
System.out.println(s.name);
if (s.connectionBindings != null) {
// Note that populations have already been allocated in the constructor.
endpoints = countLocalObject;
countLocalObject += s.connectionBindings.size();
}
fastExit = s.metadata.getFlag("backend", "all", "fastExit");
for (// we want the sub-lists to be ordered correctly
Variable v : // we want the sub-lists to be ordered correctly
s.ordered) {
if (!headless) {
String className = "null";
if (v.type != null)
className = v.type.getClass().getSimpleName();
String dimensionName = "";
if (v.unit != null)
dimensionName = v.unit.toString();
System.out.println(" " + v.nameString() + " " + v.attributeString() + " " + className + " " + dimensionName);
}
if (v.name.equals("$connect"))
connect = v;
else if (v.name.equals("$index"))
index = v;
else if (v.name.equals("$init"))
init = v;
else if (v.name.equals("$live"))
live = v;
else if (v.name.equals("$n") && v.order == 0)
n = v;
else if (v.name.equals("$p") && v.order == 0)
p = v;
else if (v.name.equals("$type"))
type = v;
else if (v.name.equals("$xyz") && v.order == 0)
xyz = v;
else if (v.name.equals("$t")) {
if (v.order == 0)
t = v;
else if (v.order == 1)
dt = v;
}
boolean initOnly = v.hasAttribute("initOnly");
boolean emptyCombiner = v.isEmptyCombiner();
boolean updates = !initOnly && v.equations.size() > 0 && !emptyCombiner && (v.derivative == null || v.hasAttribute("updates"));
boolean temporary = v.hasAttribute("temporary");
boolean unusedTemporary = temporary && !v.hasUsers();
if (v.hasAttribute("externalWrite"))
v.externalWrite = true;
if (v.hasAttribute("global")) {
v.global = true;
v.visit(new Visitor() {
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
if (av.reference.resolution.size() > 0)
addReferenceGlobal(av.reference, s);
return false;
}
if (op instanceof Output) {
Output o = (Output) op;
if (!o.hasColumnName) {
o.index = countGlobalObject++;
namesGlobalObject.add("columnName" + o.index);
}
// Continue descent, because parameters of output() may contain variable references
return true;
}
return true;
}
});
if (// eliminate non-computed values, unless they refer to a variable outside the immediate equation set
!v.hasAny(new String[] { "constant", "accessor", "readOnly" }) || v.hasAll(new String[] { "constant", "reference" })) {
if (updates)
globalUpdate.add(v);
if (!unusedTemporary && !emptyCombiner)
globalInit.add(v);
if (v.hasAttribute("reference")) {
addReferenceGlobal(v.reference, s);
} else if (!temporary && !v.hasAttribute("dummy")) {
if (!v.hasAttribute("preexistent"))
globalMembers.add(v);
boolean external = false;
if (v.externalWrite || v.assignment != Variable.REPLACE) {
external = true;
globalBufferedExternalWrite.add(v);
}
if (external || (v.hasAttribute("externalRead") && updates)) {
external = true;
globalBufferedExternal.add(v);
}
if (!external && v.hasAttribute("cycle")) {
globalBufferedInternal.add(v);
if (!initOnly)
globalBufferedInternalUpdate.add(v);
}
}
}
} else // local
{
v.visit(new Visitor() {
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
if (av.reference.resolution.size() > 0)
addReferenceLocal(av.reference, s);
return false;
}
if (op instanceof Output) {
Output o = (Output) op;
if (!o.hasColumnName) {
o.index = countLocalObject++;
namesLocalObject.add("columnName" + o.index);
}
// Continue descent, because parameters of output() may contain variable references
return true;
}
return true;
}
});
if (!v.hasAny(new String[] { "constant", "accessor", "readOnly" }) || v.hasAll(new String[] { "constant", "reference" })) {
if (updates)
localUpdate.add(v);
if (!unusedTemporary && !emptyCombiner && !forbiddenLocalInit.contains(v.name))
localInit.add(v);
if (v.hasAttribute("reference")) {
addReferenceLocal(v.reference, s);
} else if (!temporary && !v.hasAttribute("dummy")) {
if (!v.hasAttribute("preexistent"))
localMembers.add(v);
boolean external = false;
if (v.externalWrite || v.assignment != Variable.REPLACE) {
external = true;
localBufferedExternalWrite.add(v);
}
if (external || (v.hasAttribute("externalRead") && updates)) {
external = true;
localBufferedExternal.add(v);
}
if (!external && v.hasAttribute("cycle")) {
localBufferedInternal.add(v);
if (!initOnly)
localBufferedInternalUpdate.add(v);
}
}
}
}
}
for (// we need these to be in order by differential level, not by dependency
Variable v : // we need these to be in order by differential level, not by dependency
s.variables) {
if (v.derivative != null && !v.hasAny(new String[] { "constant", "initOnly" })) {
if (v.hasAttribute("global"))
globalIntegrated.add(v);
else
localIntegrated.add(v);
}
}
if (dt != null && dt.hasAttribute("constant")) {
setDt = true;
// However, if the nearest container that defines $t' matches our value, then don't set $t'.
if (s.container != null) {
Variable pdt = s.container.findDt();
if (pdt != null && pdt.hasAttribute("constant")) {
double value = dt.equations.first().expression.getDouble();
double pvalue = pdt.equations.first().expression.getDouble();
setDt = value != pvalue;
}
}
}
determineOrderInit("$init", s, localInit);
determineOrderInit("$init", s, globalInit);
singleton = s.isSingleton(true);
populationCanGrowOrDie = s.lethalP || s.lethalType || s.canGrow();
if (n != null && !singleton) {
populationCanResize = globalMembers.contains(n);
// See EquationSet.forceTemporaryStorageForSpecials() for a related issue.
if (!populationCanResize && populationCanGrowOrDie && n.hasUsers()) {
Backend.err.get().println("WARNING: $n can change (due to structural dynamics) but it was detected as a constant. Equations that depend on $n may give incorrect results.");
}
}
if (index != null && !singleton) {
indexNext = allocateGlobalFloat("indexNext");
indexAvailable = allocateGlobalObject("indexAvailable");
}
if (// track instances
singleton || s.connected || s.needInstanceTracking || populationCanResize) {
// The reason populationCanResize forces use of the instances array is to enable pruning of parts when $n decreases.
// The reason to "track instances" for a singleton is to allocate a slot for direct storage of the single instance in valuesObject.
instances = allocateGlobalObject("instances");
if (// in addition, track newly created instances
s.connected) {
if (!singleton)
firstborn = allocateGlobalFloat("firstborn");
newborn = allocateLocalFloat("newborn");
}
}
// Just give name of connection part itself.
if (s.connectionBindings != null) {
singleConnection = true;
for (ConnectionBinding cb : s.connectionBindings) {
if (cb.endpoint.container != s.container || !cb.endpoint.isSingleton(true)) {
singleConnection = false;
break;
}
}
}
if (p != null) {
Pdependencies = new ArrayList<Variable>();
PdependenciesTemp = new ArrayList<Variable>();
for (Variable t : s.ordered) {
boolean temporary = t.hasAttribute("temporary");
if ((temporary || localMembers.contains(t)) && p.dependsOn(t) != null) {
Pdependencies.add(t);
if (temporary)
PdependenciesTemp.add(t);
}
}
determineOrderInit("$connect", s, Pdependencies);
// determineOrderInit() is not needed for PdepenciesTemp, because temps are already in the correct order.
// Default is no polling
String pollString = "-1";
if (p.metadata != null)
pollString = p.metadata.getOrDefault(pollString, "poll");
poll = new UnitValue(pollString).get();
if (poll >= 0) {
pollDeadline = allocateGlobalFloat("pollDeadline");
pollSorted = allocateGlobalObject("pollSorted");
}
}
if (type != null) {
for (EquationEntry e : type.equations) {
Split split = (Split) e.expression;
split.index = type.reference.variable.container.splits.indexOf(split.parts);
}
}
if (xyz != null) {
XYZdependencies = new ArrayList<Variable>();
XYZdependenciesTemp = new ArrayList<Variable>();
for (Variable t : s.ordered) {
boolean temporary = t.hasAttribute("temporary");
if ((temporary || localMembers.contains(t)) && xyz.dependsOn(t) != null) {
XYZdependencies.add(t);
if (temporary)
XYZdependenciesTemp.add(t);
}
}
}
populationIndex = 0;
if (// check for null specifically to guard against the Wrapper equation set (which is not fully constructed)
s.container != null && s.container.parts != null) {
populationIndex = s.container.parts.indexOf(s);
}
if (// connection-specific stuff
s.connectionBindings != null) {
int size = s.connectionBindings.size();
// endpoints is allocated at the top of this function, because it is needed for reference handling in the variable analysis loop
projectDependencies = new Object[size];
projectReferences = new Object[size];
count = new int[size];
k = new Variable[size];
max = new Variable[size];
min = new Variable[size];
project = new Variable[size];
radius = new Variable[size];
for (int i = 0; i < s.connectionBindings.size(); i++) {
ConnectionBinding c = s.connectionBindings.get(i);
count[i] = -1;
k[i] = s.find(new Variable(c.alias + ".$k"));
max[i] = s.find(new Variable(c.alias + ".$max"));
min[i] = s.find(new Variable(c.alias + ".$min"));
project[i] = s.find(new Variable(c.alias + ".$project"));
radius[i] = s.find(new Variable(c.alias + ".$radius"));
if (c.endpoint.accountableConnections != null) {
AccountableConnection query = new AccountableConnection(s, c.alias);
AccountableConnection ac = c.endpoint.accountableConnections.floor(query);
if (// Only true if this endpoint is accountable.
ac.equals(query)) {
// Allocate space for counter in target part
InternalBackendData endpointBed = (InternalBackendData) c.endpoint.backendData;
count[i] = endpointBed.allocateLocalFloat(s.prefix() + ".$count");
if (// $count is referenced explicitly, so need to finish setting it up
ac.count != null) {
ac.count.readIndex = ac.count.writeIndex = count[i];
}
}
}
// Note that countLocalObject has already been incremented above
namesLocalObject.add(c.alias);
if (project[i] != null) {
ArrayList<Variable> dependencies = new ArrayList<Variable>();
// Always assign, even if empty.
projectDependencies[i] = dependencies;
for (Variable t : s.ordered) {
if (project[i].dependsOn(t) != null) {
dependencies.add(t);
}
}
final TreeSet<VariableReference> references = new TreeSet<VariableReference>();
class ProjectVisitor implements Visitor {
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
if (av.reference.resolution.size() > 0)
references.add(av.reference);
return false;
}
return true;
}
}
ProjectVisitor visitor = new ProjectVisitor();
project[i].visit(visitor);
for (Variable v : dependencies) v.visit(visitor);
if (references.size() > 0)
projectReferences[i] = references;
}
c.resolution = translateResolution(c.resolution, s);
}
}
// Locals
for (Variable v : localMembers) {
// in the object array rather than the float array.
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateLocalFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateLocalObject(v.nameString());
}
}
for (Variable v : localBufferedExternal) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateLocalFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateLocalObject("next_" + v.nameString());
}
}
for (Variable v : localBufferedInternal) {
v.writeTemp = true;
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateLocalTempFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateLocalTempObject("next_" + v.nameString());
}
}
// Globals
for (Variable v : globalMembers) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateGlobalFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateGlobalObject(v.nameString());
}
}
for (Variable v : globalBufferedExternal) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateGlobalFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateGlobalObject("next_" + v.nameString());
}
}
for (Variable v : globalBufferedInternal) {
v.writeTemp = true;
if (v.type instanceof Scalar && v.reference.variable == v) {
v.writeIndex = allocateGlobalTempFloat("next_" + v.nameString());
} else {
v.writeIndex = allocateGlobalTempObject("next_" + v.nameString());
}
}
// fully temporary values
for (Variable v : s.variables) {
if (!v.hasAttribute("temporary"))
continue;
v.readTemp = v.writeTemp = true;
if (v.hasAttribute("global")) {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateGlobalTempFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateGlobalTempObject(v.nameString());
}
} else {
if (v.type instanceof Scalar && v.reference.variable == v) {
v.readIndex = v.writeIndex = allocateLocalTempFloat(v.nameString());
} else {
v.readIndex = v.writeIndex = allocateLocalTempObject(v.nameString());
}
}
}
if (live.hasAttribute("constant"))
liveStorage = LIVE_CONSTANT;
else if (live.hasAttribute("accessor"))
liveStorage = LIVE_ACCESSOR;
else
// $live is "initOnly"
liveStorage = LIVE_STORED;
for (VariableReference r : localReference) r.resolution = translateResolution(r.resolution, s);
for (VariableReference r : globalReference) r.resolution = translateResolution(r.resolution, s);
}
use of gov.sandia.n2a.eqset.EquationSet.ConnectionBinding in project n2a by frothga.
the class InternalBackendData method translateResolution.
/**
* Convert resolution to a form that can be processed quickly at runtime.
*/
public ArrayList<Object> translateResolution(ArrayList<Object> resolution, EquationSet current) {
ArrayList<Object> result = new ArrayList<Object>();
for (Object o : resolution) {
if (// We are following the containment hierarchy.
o instanceof EquationSet) {
EquationSet next = (EquationSet) o;
if (// ascend to our container
next == current.container) {
result.add(new ResolveContainer());
} else // descend to one of our contained populations
{
int i = current.parts.indexOf(next);
if (i < 0) {
PrintStream ps = Backend.err.get();
ps.println("Could not find resolution target '" + next.name + "' in '" + current.name + "'");
ps.println("This indicates a bug in the compiler. Please report it to the support email address given on the Settings:About page.");
throw new Backend.AbortRun();
}
result.add(new ResolvePart(i));
}
current = next;
} else if (// We are following a part reference, which means "current" is a connection.
o instanceof ConnectionBinding) {
ConnectionBinding c = (ConnectionBinding) o;
InternalBackendData bed = (InternalBackendData) current.backendData;
result.add(new ResolvePart(bed.endpoints + c.index));
current = c.endpoint;
}
}
return result;
}
use of gov.sandia.n2a.eqset.EquationSet.ConnectionBinding in project n2a by frothga.
the class ChangeVariable method prepareConnections.
/**
* Tags dependencies between connection binding variables.
* Also prepares the variable held in each connection binding so it can be emitted by changeExpression()
* and associated functions.
*/
public static void prepareConnections(EquationSet s) {
for (EquationSet p : s.parts) prepareConnections(p);
if (s.connectionBindings == null)
return;
for (ConnectionBinding cb : s.connectionBindings) {
cb.addDependencies();
// Re-attach variable to container, so we can use Variable.getKeyPath()
cb.variable.container = s;
cb.variable.addAttribute("instance");
// Hack to make cb.variable look as if it has been resolved ...
AccessVariable av = (AccessVariable) cb.variable.equations.first().expression;
av.reference = new VariableReference();
av.reference.variable = cb.variable;
// must not be modified after this
av.reference.resolution = cb.resolution;
}
}
use of gov.sandia.n2a.eqset.EquationSet.ConnectionBinding in project n2a by frothga.
the class VariableReference method convertToGlobal.
/**
* Ensure the path does not rely on a connection endpoint as its first step.
* This is needed when a reference within a connection part is executed at
* the global scope, but also uses a connection binding to find the target population.
* The connection binding is not available at the global scope and also not necessary.
* @param v The variable where the path starts. We remove the connection as
* a dependency of this variable. See removeDependencies(Variable)
*/
public void convertToGlobal(Variable v) {
int count = resolution.size();
if (count == 0)
return;
Object o = resolution.get(0);
if (!(o instanceof ConnectionBinding))
return;
ConnectionBinding cb = (ConnectionBinding) o;
removeDependencies(v);
ArrayList<Object> newResolution = new ArrayList<Object>(cb.resolution);
if (count > 1)
mergeResolutionPaths(newResolution, resolution.subList(1, count));
resolution = newResolution;
addDependencies(v);
}
Aggregations