Search in sources :

Example 11 with Operator

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

the class Multiply method simplify.

public Operator simplify(Variable from) {
    Operator result = super.simplify(from);
    if (result != this)
        return result;
    // This will be reversed below if we don't actually make a change.
    from.changed = true;
    if (operand0 instanceof Constant) {
        Type c0 = ((Constant) operand0).value;
        if (c0 instanceof Scalar) {
            double value = ((Scalar) c0).value;
            if (value == 1)
                return operand1;
            if (value == 0) {
                operand1.releaseDependencies(from);
                return new Constant(new Scalar(0));
            }
        }
    } else if (operand1 instanceof Constant) {
        Type c1 = ((Constant) operand1).value;
        if (c1 instanceof Scalar) {
            double value = ((Scalar) c1).value;
            if (value == 1)
                return operand0;
            if (value == 0) {
                operand0.releaseDependencies(from);
                return new Constant(new Scalar(0));
            }
        }
    }
    from.changed = false;
    return this;
}
Also used : Operator(gov.sandia.n2a.language.Operator) Type(gov.sandia.n2a.language.Type) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 12 with Operator

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

the class MultiplyElementwise method simplify.

public Operator simplify(Variable from) {
    Operator result = super.simplify(from);
    if (result != this)
        return result;
    // This will be reversed below if we don't actually make a change.
    from.changed = true;
    if (operand0 instanceof Constant) {
        Type c0 = ((Constant) operand0).value;
        if (c0 instanceof Scalar) {
            double value = ((Scalar) c0).value;
            if (value == 1)
                return operand1;
        }
    } else if (operand1 instanceof Constant) {
        Type c1 = ((Constant) operand1).value;
        if (c1 instanceof Scalar) {
            double value = ((Scalar) c1).value;
            if (value == 1)
                return operand0;
        }
    }
    from.changed = false;
    return this;
}
Also used : Operator(gov.sandia.n2a.language.Operator) Type(gov.sandia.n2a.language.Type) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 13 with Operator

use of gov.sandia.n2a.language.Operator 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 14 with Operator

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

the class XyceBackend method generateNetlist.

public void generateNetlist(MNode job, Simulator simulator, FileWriter writer) throws Exception {
    Population toplevel = (Population) simulator.wrapper.valuesObject[0];
    XyceRenderer renderer = new XyceRenderer(simulator);
    // Header
    writer.append(toplevel.equations.name + "\n");
    writer.append("\n");
    writer.append("* seed: " + job.get("$metadata", "seed") + "\n");
    writer.append(".tran 0 " + job.get("$metadata", "duration") + "\n");
    // Equations
    for (Instance i : simulator) {
        if (i == simulator.wrapper)
            continue;
        writer.append("\n");
        writer.append("* " + i + "\n");
        renderer.pi = i;
        renderer.exceptions = null;
        XyceBackendData bed = (XyceBackendData) i.equations.backendData;
        if (bed.deviceSymbol != null) {
            writer.append(bed.deviceSymbol.getDefinition(renderer));
        }
        InstanceTemporaries temp = new InstanceTemporaries(i, simulator, false, bed.internal);
        for (final Variable v : i.equations.variables) {
            // Compute variable v
            // TODO: how to switch between multiple conditions that can be true during normal operation? IE: how to make Xyce code conditional?
            // Perhaps gate each condition (through a transistor?) and sum them at a single node.
            // e can be null
            EquationEntry e = v.select(temp);
            Symbol def = bed.equationSymbols.get(e);
            if (def == null)
                continue;
            writer.append(def.getDefinition(renderer));
            // Trace
            class TraceFinder extends Visitor {

                List<Operator> traces = new ArrayList<Operator>();

                public boolean visit(Operator op) {
                    if (op instanceof Output) {
                        traces.add(((Output) op).operands[0]);
                        return false;
                    }
                    return true;
                }
            }
            TraceFinder traceFinder = new TraceFinder();
            e.expression.visit(traceFinder);
            for (Operator trace : traceFinder.traces) {
                // We don't know if contents is .func, expression or a node, so always wrap in braces.
                writer.append(".print tran {");
                if (trace instanceof AccessVariable) {
                    AccessVariable av = (AccessVariable) trace;
                    writer.append(renderer.change(av.reference));
                } else // trace is an expression
                {
                    if (// this trace wraps the entire equation
                    e.expression instanceof Output && ((Output) e.expression).operands[0] == trace) {
                        // simply print the LHS variable, similar to the AccessVariable case above
                        writer.append(renderer.change(v.reference));
                    } else {
                        // arbitrary expression
                        writer.append(renderer.change(trace));
                    }
                }
                // one .print line per variable
                writer.append("}\n");
            }
        }
    }
    // Trailer
    writer.append(".end\n");
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Variable(gov.sandia.n2a.eqset.Variable) Visitor(gov.sandia.n2a.language.Visitor) AccessVariable(gov.sandia.n2a.language.AccessVariable) Instance(gov.sandia.n2a.language.type.Instance) Symbol(gov.sandia.n2a.backend.xyce.netlist.Symbol) InstanceTemporaries(gov.sandia.n2a.backend.internal.InstanceTemporaries) XyceRenderer(gov.sandia.n2a.backend.xyce.netlist.XyceRenderer) Output(gov.sandia.n2a.language.function.Output) Population(gov.sandia.n2a.backend.internal.Population) ArrayList(java.util.ArrayList) List(java.util.List) EquationEntry(gov.sandia.n2a.eqset.EquationEntry)

Example 15 with Operator

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

the class XyceBackendData method analyze.

public void analyze(EquationSet s) {
    if (Device.isXyceDevice(s)) {
        deviceSymbol = new Device(s);
    }
    class ContainsOperator extends Visitor {

        @SuppressWarnings("rawtypes")
        public Class targetClass;

        boolean found;

        public boolean visit(Operator op) {
            if (found)
                return false;
            if (op.getClass().equals(targetClass)) {
                found = true;
                return false;
            }
            return true;
        }

        public boolean check(EquationEntry e) {
            found = false;
            e.expression.visit(this);
            return found;
        }
    }
    ContainsOperator containsPulse = new ContainsOperator();
    containsPulse.targetClass = Pulse.class;
    ContainsOperator containsSinewave = new ContainsOperator();
    containsSinewave.targetClass = Sinewave.class;
    ContainsVariable containsT = new ContainsVariable(new Variable("$t", 0));
    for (Variable v : s.variables) {
        // in a static (no structural dynamics) simulation, no $variable needs to be computed at runtime
        if (v.name.startsWith("$"))
            continue;
        // Constants are already subbed in. "initOnly" values are defined during init cycle, and can now be subbed during code generation.
        if (v.hasAttribute("constant") || v.hasAttribute("initOnly"))
            continue;
        for (EquationEntry eq : v.equations) {
            // don't need to write out equations defining dynamics already defined by a device
            if (Device.isXyceDevice(s) && Device.ignoreEquation(eq))
                continue;
            Symbol handler = null;
            if (eq.variable.order > 1) {
                Backend.err.get().println("Support for higher order differential equations not implemented yet (" + eq + ")");
                throw new Backend.AbortRun();
            } else if (eq.variable.order == 1) {
                handler = new SymbolStateVar1(eq);
            } else // The following are all order 0
            if (containsPulse.check(eq)) {
                handler = new SymbolPulse(eq);
            } else if (containsSinewave.check(eq)) {
                handler = new SymbolSinewave(eq);
            } else // TODO: this doesn't seem like an adequate test. Why would having a $t be the only reason to generate a zero-order symbol?
            if (containsT.check(eq.expression)) {
                handler = new SymbolStateVar0(eq);
            } else if (isExplicitInit(eq)) {
                handler = new SymbolConstantIC(eq);
            } else {
                // The RHS expression depends on state variables, so we create a netlist .func for it.
                handler = new SymbolFunc(eq);
            }
            equationSymbols.put(eq, handler);
            // May set the handler for v several times, but only the last one is kept. Multiple handlers should agree on symbol for reference. Better yet is to handle multiple equations together.
            variableSymbols.put(v.name, handler);
        }
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Variable(gov.sandia.n2a.eqset.Variable) Visitor(gov.sandia.n2a.language.Visitor) SymbolStateVar0(gov.sandia.n2a.backend.xyce.netlist.SymbolStateVar0) SymbolStateVar1(gov.sandia.n2a.backend.xyce.netlist.SymbolStateVar1) Device(gov.sandia.n2a.backend.xyce.netlist.Device) Symbol(gov.sandia.n2a.backend.xyce.netlist.Symbol) SymbolPulse(gov.sandia.n2a.backend.xyce.netlist.SymbolPulse) SymbolFunc(gov.sandia.n2a.backend.xyce.netlist.SymbolFunc) SymbolSinewave(gov.sandia.n2a.backend.xyce.netlist.SymbolSinewave) EquationEntry(gov.sandia.n2a.eqset.EquationEntry) SymbolConstantIC(gov.sandia.n2a.backend.xyce.netlist.SymbolConstantIC)

Aggregations

Operator (gov.sandia.n2a.language.Operator)27 AccessVariable (gov.sandia.n2a.language.AccessVariable)17 Constant (gov.sandia.n2a.language.Constant)14 Visitor (gov.sandia.n2a.language.Visitor)11 Type (gov.sandia.n2a.language.Type)10 Scalar (gov.sandia.n2a.language.type.Scalar)10 Variable (gov.sandia.n2a.eqset.Variable)9 ArrayList (java.util.ArrayList)7 EquationSet (gov.sandia.n2a.eqset.EquationSet)6 Output (gov.sandia.n2a.language.function.Output)6 Text (gov.sandia.n2a.language.type.Text)6 TreeSet (java.util.TreeSet)4 ConnectionBinding (gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)3 VariableReference (gov.sandia.n2a.eqset.VariableReference)3 Input (gov.sandia.n2a.language.function.Input)3 Symbol (gov.sandia.n2a.backend.xyce.netlist.Symbol)2 EquationEntry (gov.sandia.n2a.eqset.EquationEntry)2 BuildMatrix (gov.sandia.n2a.language.BuildMatrix)2 Function (gov.sandia.n2a.language.Function)2 ParseException (gov.sandia.n2a.language.ParseException)2