Search in sources :

Example 11 with Constant

use of gov.sandia.n2a.language.Constant in project n2a by frothga.

the class JobC method prepareDynamicObjects.

/**
 *        Build complex sub-expressions into a single local variable that can be referenced by the equation.
 */
public void prepareDynamicObjects(Operator op, final CRenderer context, final boolean init, final String pad) throws Exception {
    // Pass 1 -- Strings and matrix expressions
    Visitor visitor1 = new Visitor() {

        public boolean visit(Operator op) {
            if (op instanceof BuildMatrix) {
                BuildMatrix m = (BuildMatrix) op;
                int rows = m.getRows();
                int cols = m.getColumns();
                String matrixName = "Matrix" + matrixNames.size();
                matrixNames.put(m, matrixName);
                if (rows == 3 && cols == 1)
                    context.result.append(pad + "Vector3 " + matrixName + ";\n");
                else
                    context.result.append(pad + "Matrix<float> " + matrixName + " (" + rows + ", " + cols + ");\n");
                for (int r = 0; r < rows; r++) {
                    if (cols == 1) {
                        context.result.append(pad + matrixName + "[" + r + "] = ");
                        m.operands[0][r].render(context);
                        context.result.append(";\n");
                    } else {
                        for (int c = 0; c < cols; c++) {
                            context.result.append(pad + matrixName + "(" + r + "," + c + ") = ");
                            m.operands[c][r].render(context);
                            context.result.append(";\n");
                        }
                    }
                }
                return false;
            }
            if (op instanceof Add) {
                Add a = (Add) op;
                String stringName = stringNames.get(a);
                if (stringName != null) {
                    context.result.append(pad + "String " + stringName + ";\n");
                    for (Operator o : flattenAdd(a)) {
                        context.result.append(pad + stringName + " += ");
                        o.render(context);
                        context.result.append(";\n");
                    }
                    return false;
                }
            }
            return true;
        }
    };
    op.visit(visitor1);
    // Pass 2 -- Input functions
    Visitor visitor2 = new Visitor() {

        public boolean visit(Operator op) {
            if (op instanceof ReadMatrix) {
                ReadMatrix r = (ReadMatrix) op;
                if (!(r.operands[0] instanceof Constant)) {
                    String matrixName = matrixNames.get(r);
                    String stringName = stringNames.get(r.operands[0]);
                    context.result.append(pad + "MatrixInput * " + matrixName + " = matrixHelper (" + stringName + ");\n");
                }
                return false;
            }
            if (op instanceof Input) {
                Input i = (Input) op;
                if (!(i.operands[0] instanceof Constant)) {
                    String inputName = inputNames.get(i);
                    String stringName = stringNames.get(i.operands[0]);
                    context.result.append(pad + "InputHolder * " + inputName + " = inputHelper (" + stringName + ");\n");
                    if (!context.global) {
                        context.result.append(pad + inputName + "->epsilon = " + resolve(context.bed.dt.reference, context, false) + " / 1000;\n");
                    }
                    // Detect time flag
                    String mode = "";
                    if (i.operands.length > 3) {
                        // just assuming it's a constant string
                        mode = i.operands[3].toString();
                    } else if (i.operands[1] instanceof Constant) {
                        Constant c = (Constant) i.operands[1];
                        if (c.value instanceof Text)
                            mode = c.toString();
                    }
                    if (mode.contains("time")) {
                        context.result.append(pad + inputName + "->time = true;\n");
                    }
                }
                // I/O functions can be nested
                return true;
            }
            if (op instanceof Output) {
                Output o = (Output) op;
                if (!(o.operands[0] instanceof Constant)) {
                    String outputName = outputNames.get(o);
                    String stringName = stringNames.get(o.operands[0]);
                    context.result.append(pad + "OutputHolder * " + outputName + " = outputHelper (" + stringName + ");\n");
                    // Detect raw flag
                    if (o.operands.length > 3) {
                        Operator op3 = o.operands[3];
                        if (op3 instanceof Constant) {
                            if (op3.toString().contains("raw")) {
                                context.result.append(pad + outputName + "->raw = true;\n");
                            }
                        }
                    }
                }
                return true;
            }
            return true;
        }
    };
    op.visit(visitor2);
}
Also used : Operator(gov.sandia.n2a.language.Operator) Add(gov.sandia.n2a.language.operator.Add) Input(gov.sandia.n2a.language.function.Input) Visitor(gov.sandia.n2a.language.Visitor) Constant(gov.sandia.n2a.language.Constant) BuildMatrix(gov.sandia.n2a.language.BuildMatrix) Output(gov.sandia.n2a.language.function.Output) Text(gov.sandia.n2a.language.type.Text) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix)

Example 12 with Constant

use of gov.sandia.n2a.language.Constant in project n2a by frothga.

the class EquationSet method findInitOnlyRecursive.

public boolean findInitOnlyRecursive() {
    boolean changed = false;
    for (EquationSet s : parts) {
        if (s.findInitOnlyRecursive())
            changed = true;
    }
    ReplaceInit replaceInit = new ReplaceInit();
    for (final Variable v : variables) {
        // Note: some variables get tagged "initOnly" by other means, so don't re-process
        if (v.hasAny(new String[] { "initOnly", "constant", "dummy" }))
            continue;
        // Count equations
        int firesDuringInit = 0;
        int firesDuringUpdate = 0;
        // If we have a single update equation, then we may still be initOnly if it depends only on constants or other initOnly variables. Save the update equation for analysis.
        EquationEntry update = null;
        for (EquationEntry e : v.equations) {
            if (e.condition == null) {
                firesDuringInit++;
                firesDuringUpdate++;
                update = e;
            } else {
                // init
                replaceInit.init = 1;
                replaceInit.live = 1;
                Operator test = e.condition.deepCopy().transform(replaceInit).simplify(v);
                boolean fires = true;
                if (test instanceof Constant) {
                    Constant c = (Constant) test;
                    if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
                        fires = false;
                }
                if (fires)
                    firesDuringInit++;
                // update
                replaceInit.init = 0;
                replaceInit.live = 1;
                test = e.condition.deepCopy().transform(replaceInit).simplify(v);
                fires = true;
                if (test instanceof Constant) {
                    Constant c = (Constant) test;
                    if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
                        fires = false;
                }
                if (fires) {
                    firesDuringUpdate++;
                    update = e;
                }
            }
        }
        if (firesDuringUpdate == 0) {
            if (firesDuringInit > 0 && v.derivative == null) {
                v.addAttribute("initOnly");
                changed = true;
            }
        } else if (// last chance to be "initOnly": must be exactly one equation that is not a combining operator
        firesDuringUpdate == 1 && v.assignment == Variable.REPLACE) {
            // Determine if our single update equation depends only on constants and initOnly variables
            class VisitInitOnly extends Visitor {

                // until something falsifies it
                boolean isInitOnly = true;

                public boolean visit(Operator op) {
                    if (isInitOnly) {
                        if (op instanceof AccessVariable) {
                            AccessVariable av = (AccessVariable) op;
                            // constant has already been replaced. Therefore, only the "initOnly" attribute matters here.
                            if (av.reference == null || av.reference.variable == null)
                                isInitOnly = false;
                            Variable r = av.reference.variable;
                            if (!r.hasAttribute("initOnly"))
                                isInitOnly = false;
                            // Also verify that the variables we depend on are available during the appropriate phase of init
                            if (// Note that temporaries are always available.
                            isInitOnly && !r.hasAttribute("temporary")) {
                                if (// we are a $variable, so we can only depend on $index and $init
                                v.name.startsWith("$")) {
                                    if (!"$index,$init,$live".contains(r.name))
                                        isInitOnly = false;
                                } else // we are a regular variable, so can only depend on $variables
                                {
                                    if (!r.name.startsWith("$"))
                                        isInitOnly = false;
                                }
                            }
                        } else if (op instanceof Function) {
                            Function f = (Function) op;
                            if (!f.canBeInitOnly())
                                isInitOnly = false;
                        }
                    }
                    return isInitOnly;
                }
            }
            VisitInitOnly visitor = new VisitInitOnly();
            if (update.condition != null)
                update.condition.visit(visitor);
            if (visitor.isInitOnly) {
                update.expression.visit(visitor);
                if (visitor.isInitOnly) {
                    v.addAttribute("initOnly");
                    changed = true;
                }
            }
        }
        if (firesDuringUpdate > 0 && v.derivative != null && !v.hasAttribute("initOnly"))
            v.addAttribute("updates");
        else
            v.removeAttribute("updates");
    }
    return changed;
}
Also used : Operator(gov.sandia.n2a.language.Operator) Function(gov.sandia.n2a.language.Function) AccessVariable(gov.sandia.n2a.language.AccessVariable) AccessVariable(gov.sandia.n2a.language.AccessVariable) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 13 with Constant

use of gov.sandia.n2a.language.Constant in project n2a by frothga.

the class EquationSet method findLethalVariables.

public void findLethalVariables() {
    for (EquationSet s : parts) {
        s.findLethalVariables();
    }
    // Determine if $n can decrease
    Variable n = find(new Variable("$n"));
    if (n != null) {
        for (EquationEntry e : n.equations) {
            // Even if each expression is constant, $n could still change during operation if it is a multi-conditional.
            if (e.condition != null && !(e.condition instanceof Constant)) {
                lethalN = true;
                break;
            }
            if (!(e.expression instanceof Constant)) {
                lethalN = true;
                break;
            }
        }
    }
    // Determine if $p has an assignment less than 1
    Variable p = find(new Variable("$p"));
    if (p != null) {
        // Determine if any equation is capable of setting $p to something besides 1
        ReplaceInit replaceInit = new ReplaceInit();
        for (EquationEntry e : p.equations) {
            if (e.expression instanceof Constant) {
                Type value = ((Constant) e.expression).value;
                if (value instanceof Scalar) {
                    if (((Scalar) value).value == 1.0)
                        continue;
                }
            }
            // Check if condition fires during init phase
            if (e.condition != null) {
                replaceInit.init = 1;
                replaceInit.live = 1;
                Operator test = e.condition.deepCopy().transform(replaceInit).simplify(p);
                if (test instanceof Constant) {
                    Constant c = (Constant) test;
                    if (// Does not fire during init phase
                    c.value instanceof Scalar && ((Scalar) c.value).value == 0) {
                        // Check if condition fires during update phase
                        replaceInit.init = 0;
                        test = e.condition.deepCopy().transform(replaceInit).simplify(p);
                        if (test instanceof Constant) {
                            c = (Constant) test;
                            // Does not fire during update phase
                            if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
                                continue;
                        }
                    }
                }
            }
            lethalP = true;
            break;
        }
    }
    // Determine if any splits kill this part
    for (// my splits are the parts I can split into
    ArrayList<EquationSet> split : // my splits are the parts I can split into
    splits) {
        if (!split.contains(this)) {
            lethalType = true;
            break;
        }
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) Type(gov.sandia.n2a.language.Type) AccessVariable(gov.sandia.n2a.language.AccessVariable) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 14 with Constant

use of gov.sandia.n2a.language.Constant in project n2a by frothga.

the class EquationSet method findConstantsEval.

protected boolean findConstantsEval() {
    boolean changed = false;
    for (EquationSet s : parts) {
        if (s.findConstantsEval())
            changed = true;
    }
    for (Variable v : variables) {
        if (v.simplify())
            changed = true;
        // If this already has a "constant" tag, it was specially added so presumably correct.
        if (v.hasAttribute("constant"))
            continue;
        // Regardless of the local math, a variable that gets written is not constant.
        if (v.hasAttribute("externalWrite"))
            continue;
        if (v.equations.size() != 1)
            continue;
        EquationEntry e = v.equations.first();
        if (e.condition != null)
            continue;
        if (e.expression instanceof Constant) {
            v.addAttribute("constant");
            changed = true;
        }
    }
    return changed;
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) Constant(gov.sandia.n2a.language.Constant)

Example 15 with Constant

use of gov.sandia.n2a.language.Constant in project n2a by frothga.

the class Variable method simplify.

public boolean simplify() {
    if (equations == null)
        return false;
    changed = false;
    TreeSet<EquationEntry> nextEquations = new TreeSet<EquationEntry>();
    TreeSet<EquationEntry> alwaysTrue = new TreeSet<EquationEntry>();
    for (EquationEntry e : equations) {
        if (e.expression != null) {
            e.expression = e.expression.simplify(this);
        }
        if (e.condition != null) {
            e.condition = e.condition.simplify(this);
            e.ifString = e.condition.render();
        }
        if (e.condition instanceof Constant) {
            Constant c = (Constant) e.condition;
            if (c.value instanceof Scalar) {
                double value = ((Scalar) c.value).value;
                if (value == 0) {
                    // Drop equation because it will never fire.
                    changed = true;
                    continue;
                }
                alwaysTrue.add(e);
            }
        } else if (e.ifString.isEmpty() && e.expression instanceof AccessVariable && ((AccessVariable) e.expression).reference.variable == this) {
            // Drop this default equation because it is redundant. Simulator always copies value to next cycle when no equation fires.
            changed = true;
            continue;
        }
        nextEquations.add(e);
    }
    if (// Default equation will never be included in alwaysTrue.
    alwaysTrue.size() == 1) {
        changed = true;
        equations = alwaysTrue;
        // Make the equation unconditional, since it always fires anyway.
        EquationEntry e = equations.first();
        e.condition = null;
        e.ifString = "";
    } else {
        equations = nextEquations;
    }
    return changed;
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) TreeSet(java.util.TreeSet) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Aggregations

Constant (gov.sandia.n2a.language.Constant)19 Operator (gov.sandia.n2a.language.Operator)14 AccessVariable (gov.sandia.n2a.language.AccessVariable)11 Scalar (gov.sandia.n2a.language.type.Scalar)10 Type (gov.sandia.n2a.language.Type)9 Text (gov.sandia.n2a.language.type.Text)6 Visitor (gov.sandia.n2a.language.Visitor)5 EquationSet (gov.sandia.n2a.eqset.EquationSet)4 Variable (gov.sandia.n2a.eqset.Variable)4 ParseException (gov.sandia.n2a.language.ParseException)3 Input (gov.sandia.n2a.language.function.Input)3 Output (gov.sandia.n2a.language.function.Output)3 BuildMatrix (gov.sandia.n2a.language.BuildMatrix)2 Function (gov.sandia.n2a.language.Function)2 ReadMatrix (gov.sandia.n2a.language.function.ReadMatrix)2 Add (gov.sandia.n2a.language.operator.Add)2 TreeSet (java.util.TreeSet)2 MNode (gov.sandia.n2a.db.MNode)1 ConnectionBinding (gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)1 MPart (gov.sandia.n2a.eqset.MPart)1