use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.
the class EquationSet method dumpMedians.
/**
* @return true if we should abort the run. false if it is OK to proceed.
*/
public boolean dumpMedians(PrintStream ps, ExponentContext context) {
boolean result = false;
class VisitorExponentSanity implements Visitor {
boolean sane = true;
boolean warningExp = false;
boolean warningPow = false;
public boolean visit(Operator op) {
if (op instanceof AccessVariable)
return sane;
String name = op.toString();
if (op instanceof Function)
name += "()";
else
name = "operator" + name;
if (op.center < 0 || op.center > Operator.MSB) {
sane = false;
String flow = op.center < 0 ? "underflow" : "overflow";
ps.println("\t\t ERROR: " + name + " produces " + flow + " (center = " + op.center + ")");
} else if (Math.abs(op.exponent) > 128) {
ps.println("\t\t WARNING: " + name + " produces large exponent (" + op.exponent + ")");
} else if (op instanceof Exp) {
Exp e = (Exp) op;
if (!warningExp && (e.operands.length < 2 || !e.operands[1].getString().contains("median"))) {
ps.println("\t\t WARNING: exp() is very sensitive. If input values vary far from 0, provide a hint for median output value.");
warningExp = true;
}
} else if (op instanceof Power) {
Power p = (Power) op;
if (!warningPow && (p.hint == null || !p.hint.contains("median"))) {
if (p.hint == null)
ps.println("\t\t WARNING: operator^ is very sensitive. For best results, use pow() and provide a hint for median output value.");
else
ps.println("\t\t WARNING: pow() is very sensitive. For best results, provide a hint for median output value.");
warningPow = true;
}
}
return sane;
}
}
;
VisitorExponentSanity visitor = new VisitorExponentSanity();
for (Variable v : variables) {
if (v.hasAttribute("dummy"))
continue;
// Must abort run, because numbers will almost certainly go out of range.
if (v.center < 0 || v.center > Operator.MSB)
result = true;
// No need to warn about large v.exponent, because the user will be able to view the list.
// Convert center power to an approximate decimal value.
int centerPower = v.exponent - Operator.MSB + v.center;
int base10 = (int) Math.floor(centerPower / b2d);
ps.println(" " + base10 + "\t" + v.exponent + "\t" + v.fullName());
if (context.overflows.contains(v))
ps.println("\t\t WARNING: Magnitude did not converge. Add hint (median=median_absolute_value).");
visitor.sane = true;
visitor.warningExp = false;
visitor.warningPow = false;
v.visit(visitor);
if (!visitor.sane)
result = true;
}
for (EquationSet s : parts) if (s.dumpMedians(ps, context))
result = true;
return result;
}
use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.
the class EquationSet method determineTypesEval.
public boolean determineTypesEval() {
boolean changed = false;
for (final Variable v : variables) {
if (v.hasAttribute("constant"))
continue;
// Don't change type for certain $variables.
if (v.name.equals("$init") || v.name.equals("$live") || v.name.equals("$p") || v.name.equals("$n") || (v.name.equals("$t") && v.order == 1))
continue;
Type value = null;
Instance instance = new Instance() {
// all AccessVariable objects will reach here first, and get back the Variable.type field
public Type get(VariableReference r) throws EvaluationException {
return r.variable.type;
}
};
for (EquationEntry e : v.equations) {
// However, scanning them all increase our chance of propagating correct values.
try {
Type temp = e.expression.eval(instance);
if (value == null || temp.betterThan(value))
value = temp;
}// This can happen due to type mismatch, and may be a temporary condition while values are propagating.
catch (Exception x) {
}
}
if (v.derivative != null) {
if (value == null) {
value = v.derivative.type;
} else if (v.derivative.type == null || value.betterThan(v.derivative.type)) {
v.derivative.type = value;
changed = true;
}
}
if (value == null) {
value = v.reference.variable.type;
} else if (v.reference.variable.type == null || value.betterThan(v.reference.variable.type)) {
v.reference.variable.type = value;
changed = true;
}
if (v != v.reference.variable && value != null && value.betterThan(v.type)) {
v.type = value;
changed = true;
}
}
for (EquationSet s : parts) {
if (s.determineTypesEval())
changed = true;
}
return changed;
}
use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.
the class EquationSet method isConnectionBinding.
/**
* Given a variable v from this equation set, determine if it meets the heuristics for a connection
* binding. The only way to be 100% certain is to resolve it.
* @return The AccessVariable object that contains the actual reference to the desired endpoint.
* If this is not a connection binding, then the result is null.
*/
public AccessVariable isConnectionBinding(Variable v) {
if (v.order > 0)
return null;
if (v.name.contains("$") || v.name.contains("\\."))
return null;
if (v.equations.size() != 1)
return null;
if (v.assignment != Variable.REPLACE)
return null;
EquationEntry ee = v.equations.first();
if (ee.condition != null)
return null;
if (!(ee.expression instanceof AccessVariable))
return null;
AccessVariable av = (AccessVariable) ee.expression;
if (av.getOrder() > 0)
return null;
// Not a binding if matching variable of any order exists.
if (find(new Variable(av.getName(), -1)) != null)
return null;
return av;
}
use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.
the class EquationSet method purgeInitOnlyTemporary.
/**
* findInitOnly() propagates the "initOnly" attribute through temporaries, but the final
* attribute set of a variable cannot contain both, as they are mutually contradictory.
* "initOnly" requires storage, while "temporary" forbids it. We give "temporary"
* precedence, because we prioritize memory efficiency over time efficiency.
*/
public void purgeInitOnlyTemporary() {
for (EquationSet p : parts) p.purgeInitOnlyTemporary();
for (Variable v : variables) {
if (v.hasAll("temporary", "initOnly")) {
v.removeAttribute("initOnly");
// If there are no regular update equations, then convert init equations into
// regular update equations, because their values would continue to hold if the
// variable were stored.
// Test for presence of regular update equations.
// See findInitOnlyRecursive() for similar code.
boolean firesDuringUpdate = false;
ReplacePhaseIndicators replacePhase = new ReplacePhaseIndicators();
replacePhase.init = 0;
for (EquationEntry e : v.equations) {
if (e.condition == null) {
firesDuringUpdate = true;
break;
} else {
Operator test = e.condition.deepCopy().transform(replacePhase).simplify(v, true);
if (!test.isScalar() || test.getDouble() != 0) {
firesDuringUpdate = true;
break;
}
}
}
// See Variable.simplify() for similar code.
if (!firesDuringUpdate) {
class ReplaceInit implements Transformer {
public Operator transform(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
if (av.name.equals("$init"))
return new Constant(1);
}
return null;
}
}
;
ReplaceInit replaceInit = new ReplaceInit();
TreeSet<EquationEntry> nextEquations = new TreeSet<EquationEntry>();
for (EquationEntry e : v.equations) {
e.condition = e.condition.transform(replaceInit).simplify(v, false);
e.ifString = e.condition.render();
if (e.condition.isScalar()) {
// but only one will remain after adding to nextEquations.
if (// Will always fire.
e.condition.getDouble() != 0) {
e.condition = null;
e.ifString = "";
nextEquations.add(e);
}
} else {
nextEquations.add(e);
}
}
v.equations = nextEquations;
}
}
}
}
use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.
the class EquationSet method findExternal.
/**
* Marks variables with "externalRead" and "externalWrite", as needed.
* Determines whether an external write should be evaluated in the local or global context.
* Depends on results of:
* resolveLHS(), resolveRHS() -- Establishes references and dependencies between variables.
* flatten() -- Changes references and dependencies. In some cases, folds expressions together so dependencies go away.
*/
public void findExternal() {
for (EquationSet p : parts) p.findExternal();
class Externalizer implements Visitor {
Variable v;
boolean allGlobal;
public boolean visit(Operator op) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
Variable target = av.reference.variable;
if (// v references something other than itself, which implies that the target is outside this equation set.
target.container != v.container) {
target.addAttribute("externalRead");
target.removeAttribute("temporary");
}
if (!target.hasAny("global", "constant"))
allGlobal = false;
}
return true;
}
}
Externalizer externalizer = new Externalizer();
for (Variable v : variables) {
externalizer.v = v;
externalizer.allGlobal = true;
v.visit(externalizer);
// for convenience
Variable vr = v.reference.variable;
if (vr != v) {
v.addAttribute("reference");
vr.addAttribute("externalWrite");
vr.removeAttribute("temporary");
if (externalizer.allGlobal && !v.hasAttribute("local") && vr.hasAttribute("global")) {
v.addAttribute("global");
v.convertToGlobal();
}
}
}
}
Aggregations