Search in sources :

Example 1 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class JobC method generateStatic.

public void generateStatic(final EquationSet s, final StringBuilder result) {
    for (EquationSet p : s.parts) generateStatic(p, result);
    // Generate static definitions
    final BackendDataC bed = (BackendDataC) s.backendData;
    class CheckStatic extends Visitor {

        public boolean global;

        public boolean visit(Operator op) {
            if (op instanceof Constant) {
                Type m = ((Constant) op).value;
                if (m instanceof Matrix) {
                    Matrix A = (Matrix) m;
                    int rows = A.rows();
                    int cols = A.columns();
                    String matrixName = "Matrix" + matrixNames.size();
                    matrixNames.put(op, matrixName);
                    if (rows == 3 && cols == 1)
                        result.append("Vector3 " + matrixName + " = Matrix<float>");
                    else
                        result.append("Matrix<float> " + matrixName);
                    result.append(" (\"" + A + "\");\n");
                }
                // Don't try to descend tree from here
                return false;
            }
            if (op instanceof Function) {
                Function f = (Function) op;
                if (// We need to auto-generate the column name.
                f instanceof Output && f.operands.length < 3) {
                    String stringName = "columnName" + stringNames.size();
                    stringNames.put(op, stringName);
                    if (global) {
                        bed.setGlobalNeedPath(s);
                        bed.globalColumns.add(stringName);
                    } else {
                        bed.setLocalNeedPath(s);
                        bed.localColumns.add(stringName);
                    }
                }
                // Detect functions that need static handles
                if (f.operands.length > 0) {
                    Operator operand0 = f.operands[0];
                    if (operand0 instanceof Constant) {
                        Constant c = (Constant) operand0;
                        Type o = c.value;
                        if (o instanceof Text) {
                            String fileName = ((Text) o).value;
                            if (op instanceof ReadMatrix) {
                                if (!matrixNames.containsKey(fileName)) {
                                    String matrixName = "Matrix" + matrixNames.size();
                                    matrixNames.put(fileName, matrixName);
                                    result.append("MatrixInput * " + matrixName + " = matrixHelper (\"" + fileName + "\");\n");
                                }
                            } else if (f instanceof Input) {
                                if (!inputNames.containsKey(fileName)) {
                                    String inputName = "Input" + inputNames.size();
                                    inputNames.put(fileName, inputName);
                                    result.append("InputHolder * " + inputName + " = inputHelper (\"" + fileName + "\");\n");
                                }
                            } else if (f instanceof Output) {
                                if (!outputNames.containsKey(fileName)) {
                                    String outputName = "Output" + outputNames.size();
                                    outputNames.put(fileName, outputName);
                                    result.append("OutputHolder * " + outputName + " = outputHelper (\"" + fileName + "\");\n");
                                }
                            }
                        }
                    } else // Dynamic file name (no static handle)
                    {
                        if (f instanceof ReadMatrix) {
                            matrixNames.put(op, "Matrix" + matrixNames.size());
                            stringNames.put(operand0, "fileName" + stringNames.size());
                        } else if (f instanceof Input) {
                            inputNames.put(op, "Input" + inputNames.size());
                            stringNames.put(operand0, "fileName" + stringNames.size());
                        } else if (f instanceof Output) {
                            outputNames.put(op, "Output" + outputNames.size());
                            stringNames.put(operand0, "fileName" + stringNames.size());
                        }
                    }
                }
                // Functions could be nested, so continue descent.
                return true;
            }
            return true;
        }
    }
    CheckStatic checkStatic = new CheckStatic();
    for (Variable v : s.ordered) {
        checkStatic.global = v.hasAttribute("global");
        v.visit(checkStatic);
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) EquationSet(gov.sandia.n2a.eqset.EquationSet) Variable(gov.sandia.n2a.eqset.Variable) AccessVariable(gov.sandia.n2a.language.AccessVariable) Visitor(gov.sandia.n2a.language.Visitor) Constant(gov.sandia.n2a.language.Constant) Text(gov.sandia.n2a.language.type.Text) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) Function(gov.sandia.n2a.language.Function) Type(gov.sandia.n2a.language.Type) Input(gov.sandia.n2a.language.function.Input) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) BuildMatrix(gov.sandia.n2a.language.BuildMatrix) Matrix(gov.sandia.n2a.language.type.Matrix) Output(gov.sandia.n2a.language.function.Output)

Example 2 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class InternalBackendData method analyzeEvents.

public static void analyzeEvents(final EquationSet s, final List<EventTarget> eventTargets, final List<Variable> eventReferences) {
    class EventVisitor extends Visitor {

        public boolean found;

        public boolean visit(Operator op) {
            if (op instanceof Event) {
                found = true;
                Event de = (Event) op;
                if (// this event has not yet been analyzed
                de.eventType == null) {
                    final EventTarget et = new EventTarget(de);
                    int targetIndex = eventTargets.indexOf(et);
                    if (// event target already exists
                    targetIndex >= 0) {
                        de.eventType = eventTargets.get(targetIndex);
                    } else // we must create a new event target, or more properly, fill in the event target we just used as a query object
                    {
                        // Create an entry and save the index
                        targetIndex = eventTargets.size();
                        eventTargets.add(et);
                        de.eventType = et;
                        et.container = s;
                        // Determine edge type
                        if (de.operands.length < 3) {
                            et.edge = EventTarget.RISE;
                        } else if (de.operands[2] instanceof Constant) {
                            Constant c = (Constant) de.operands[2];
                            if (c.value instanceof Text) {
                                Text t = (Text) c.value;
                                if (t.value.equalsIgnoreCase("nonzero"))
                                    et.edge = EventTarget.NONZERO;
                                else if (t.value.equalsIgnoreCase("change"))
                                    et.edge = EventTarget.CHANGE;
                                else if (t.value.equalsIgnoreCase("fall"))
                                    et.edge = EventTarget.FALL;
                                else
                                    et.edge = EventTarget.RISE;
                            } else {
                                Backend.err.get().println("ERROR: event() edge type must be a string.");
                                throw new Backend.AbortRun();
                            }
                        } else {
                            Backend.err.get().println("ERROR: event() edge type must be constant.");
                            throw new Backend.AbortRun();
                        }
                        // Allocate auxiliary variable
                        if (de.operands[0] instanceof AccessVariable) {
                            AccessVariable av = (AccessVariable) de.operands[0];
                            VariableReference reference = av.reference;
                            Variable v = reference.variable;
                            // then the user has broken the rule that we can't see temporaries in other parts.
                            if (v.hasAttribute("temporary") && v.container != s) {
                                Backend.err.get().println("WARNING: Cannot be temporary due to event monitor: " + v.container.name + "." + v.nameString() + " from " + s.name);
                                v.removeAttribute("temporary");
                            }
                            // so fall through to the !trackOne case below.
                            if (!v.hasAttribute("temporary")) {
                                // ensure it's buffered, so we can detect change
                                v.addAttribute("externalRead");
                                et.trackOne = true;
                                // just a holder for the reference
                                et.track = new Variable();
                                et.track.reference = reference;
                            }
                        }
                        if (// Expression, so create auxiliary variable. Aux not needed for NONZERO, because no change detection.
                        !et.trackOne && et.edge != EventTarget.NONZERO) {
                            et.track = new Variable("eventAux" + targetIndex, 0);
                            et.track.type = new Scalar(0);
                            et.track.reference = new VariableReference();
                            et.track.reference.variable = et.track;
                        }
                        // Locate any temporaries for evaluation. TODO: for more efficiency, we could have separate lists of temporaries for the condition and delay operands
                        // Tie into the dependency graph using a phantom variable (which can go away afterward without damaging the graph).
                        final Variable phantom = new Variable("event");
                        phantom.uses = new IdentityHashMap<Variable, Integer>();
                        for (int i = 0; i < et.event.operands.length; i++) et.event.operands[i].visit(new Visitor() {

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    Variable v = av.reference.variable;
                                    if (!phantom.uses.containsKey(v))
                                        phantom.uses.put(v, 1);
                                    return false;
                                }
                                return true;
                            }
                        });
                        // Scan all variables in equation set to see if we need them
                        for (Variable t : s.variables) {
                            if (t.hasAttribute("temporary") && phantom.dependsOn(t) != null)
                                et.dependencies.add(t);
                        }
                        // Note the default is already set to -1 (no care)
                        class DelayVisitor extends Visitor {

                            TreeSet<EquationSet> containers = new TreeSet<EquationSet>();

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    // could include the target part itself, if in fact we use local variables
                                    containers.add(av.reference.variable.container);
                                    return false;
                                }
                                return true;
                            }
                        }
                        DelayVisitor dv = new DelayVisitor();
                        if (de.operands.length >= 2) {
                            if (de.operands[1] instanceof Constant) {
                                Constant c = (Constant) de.operands[1];
                                et.delay = (float) ((Scalar) c.value).value;
                                if (et.delay < 0)
                                    et.delay = -1;
                            } else {
                                // indicates that we need to evaluate delay at run time
                                et.delay = -2;
                                de.operands[1].visit(dv);
                            }
                        }
                        // Set up monitors in source parts
                        class ConditionVisitor extends Visitor {

                            TreeSet<EquationSet> containers = new TreeSet<EquationSet>();

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    Variable v = av.reference.variable;
                                    EquationSet sourceContainer = v.container;
                                    containers.add(sourceContainer);
                                    // Set up monitors for values that can vary during update.
                                    if (!v.hasAttribute("constant") && !v.hasAttribute("initOnly") && !et.monitors(sourceContainer)) {
                                        EventSource es = new EventSource(sourceContainer, et);
                                        // null means self-reference, a special case handled in Part
                                        if (sourceContainer != s)
                                            es.reference = av.reference;
                                        et.sources.add(es);
                                    }
                                    return false;
                                }
                                return true;
                            }
                        }
                        ConditionVisitor cv = new ConditionVisitor();
                        de.operands[0].visit(cv);
                        // Special case for event with no references that vary
                        if (et.sources.isEmpty()) {
                            // We can avoid creating a self monitor if we know for certain that the event will never fire
                            boolean neverFires = false;
                            if (de.operands[0] instanceof Constant) {
                                if (et.edge == EventTarget.NONZERO) {
                                    Type op0 = ((Constant) de.operands[0]).value;
                                    if (op0 instanceof Scalar) {
                                        neverFires = ((Scalar) op0).value == 0;
                                    } else {
                                        Backend.err.get().println("ERROR: Condition for event() must resolve to a number.");
                                        throw new Backend.AbortRun();
                                    }
                                } else {
                                    neverFires = true;
                                }
                            }
                            if (!neverFires) {
                                EventSource es = new EventSource(s, et);
                                // This is a self-reference, so es.reference should be null.
                                et.sources.add(es);
                            }
                        }
                        // Determine if monitor needs to test every target, or if one representative target is sufficient
                        for (EventSource source : et.sources) {
                            // associated with any given source instance, so every target must be evaluated separately.
                            if (cv.containers.size() > 1)
                                source.testEach = true;
                            if (dv.containers.size() > 1 || (dv.containers.size() == 1 && dv.containers.first() != source.container))
                                source.delayEach = true;
                        }
                    }
                }
            }
            return true;
        }
    }
    EventVisitor eventVisitor = new EventVisitor();
    for (Variable v : s.variables) {
        eventVisitor.found = false;
        v.visit(eventVisitor);
        if ((eventVisitor.found || v.dependsOnEvent()) && v.reference.variable != v)
            eventReferences.add(v);
    }
}
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) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar) TreeSet(java.util.TreeSet) EquationSet(gov.sandia.n2a.eqset.EquationSet) AccessVariable(gov.sandia.n2a.language.AccessVariable) VariableReference(gov.sandia.n2a.eqset.VariableReference) Text(gov.sandia.n2a.language.type.Text) Backend(gov.sandia.n2a.plugins.extpoints.Backend) Type(gov.sandia.n2a.language.Type) Event(gov.sandia.n2a.language.function.Event)

Example 3 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class Input method getRow.

public Holder getRow(Instance context, Type op1, boolean time) {
    Simulator simulator = Simulator.getSimulator(context);
    // If we can't cache a line from the requested stream, then semantics of this function are lost, so give up.
    if (simulator == null)
        return null;
    Holder H = null;
    try {
        // get an input holder
        String path = ((Text) operands[0].eval(context)).value;
        H = simulator.inputs.get(path);
        if (H == null) {
            H = new Holder();
            if (// not ideal; reading stdin should be reserved for headless operation
            path.isEmpty())
                // not ideal; reading stdin should be reserved for headless operation
                H.stream = new BufferedReader(new InputStreamReader(System.in));
            else
                H.stream = new BufferedReader(new FileReader(new File(path).getAbsoluteFile()));
            // sqrt (epsilon for time representation (currently double)), about 1e-8
            H.epsilon = Math.sqrt(Math.ulp(1.0));
            if (simulator.currentEvent instanceof EventStep)
                H.epsilon = Math.min(H.epsilon, ((EventStep) simulator.currentEvent).dt / 1000);
            simulator.inputs.put(path, H);
        }
        if (op1 instanceof Scalar)
            H.getRow(((Scalar) op1).value, time);
        else
            H.getRow(0, time);
    } catch (IOException e) {
        return null;
    }
    return H;
}
Also used : InputStreamReader(java.io.InputStreamReader) EventStep(gov.sandia.n2a.backend.internal.EventStep) BufferedReader(java.io.BufferedReader) Text(gov.sandia.n2a.language.type.Text) FileReader(java.io.FileReader) IOException(java.io.IOException) Simulator(gov.sandia.n2a.backend.internal.Simulator) File(java.io.File) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 4 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class ReadMatrix method eval.

public Type eval(Instance context) {
    Simulator simulator = Simulator.getSimulator(context);
    // absence of simulator indicates analysis phase, so opening files is unnecessary
    if (simulator == null)
        return new Scalar(0);
    String path = ((Text) operands[0].eval(context)).value;
    Matrix A = simulator.matrices.get(path);
    if (A == null) {
        A = Matrix.factory(new File(path).getAbsoluteFile());
        simulator.matrices.put(path, A);
    }
    String mode = "";
    int lastParm = operands.length - 1;
    if (lastParm > 0) {
        Type parmValue = operands[lastParm].eval(context);
        if (parmValue instanceof Text)
            mode = ((Text) parmValue).value;
    }
    if (mode.equals("columns"))
        return new Scalar(A.columns());
    if (mode.equals("rows"))
        return new Scalar(A.rows());
    int rows = A.rows();
    int columns = A.columns();
    int lastRow = rows - 1;
    int lastColumn = columns - 1;
    double row = ((Scalar) operands[1].eval(context)).value;
    double column = ((Scalar) operands[2].eval(context)).value;
    if (mode.equals("raw")) {
        int r = (int) Math.floor(row);
        int c = (int) Math.floor(column);
        if (r < 0)
            r = 0;
        else if (r >= rows)
            r = lastRow;
        if (c < 0)
            c = 0;
        else if (c >= columns)
            c = lastColumn;
        return new Scalar(A.get(r, c));
    } else {
        row *= lastRow;
        column *= lastColumn;
        int r = (int) Math.floor(row);
        int c = (int) Math.floor(column);
        if (r < 0) {
            if (c < 0)
                return new Scalar(A.get(0, 0));
            else if (c >= lastColumn)
                return new Scalar(A.get(0, lastColumn));
            else {
                double b = column - c;
                return new Scalar((1 - b) * A.get(0, c) + b * A.get(0, c + 1));
            }
        } else if (r >= lastRow) {
            if (c < 0)
                return new Scalar(A.get(lastRow, 0));
            else if (c >= lastColumn)
                return new Scalar(A.get(lastRow, lastColumn));
            else {
                double b = column - c;
                return new Scalar((1 - b) * A.get(lastRow, c) + b * A.get(lastRow, c + 1));
            }
        } else {
            double a = row - r;
            double a1 = 1 - a;
            if (c < 0)
                return new Scalar(a1 * A.get(r, 0) + a * A.get(r + 1, 0));
            else if (c >= lastColumn)
                return new Scalar(a1 * A.get(r, lastColumn) + a * A.get(r + 1, lastColumn));
            else {
                double b = column - c;
                return new Scalar((1 - b) * (a1 * A.get(r, c) + a * A.get(r + 1, c)) + b * (a1 * A.get(r, c + 1) + a * A.get(r + 1, c + 1)));
            }
        }
    }
}
Also used : Type(gov.sandia.n2a.language.Type) Matrix(gov.sandia.n2a.language.type.Matrix) Text(gov.sandia.n2a.language.type.Text) Simulator(gov.sandia.n2a.backend.internal.Simulator) File(java.io.File) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 5 with Text

use of gov.sandia.n2a.language.type.Text 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)

Aggregations

Text (gov.sandia.n2a.language.type.Text)21 Matrix (gov.sandia.n2a.language.type.Matrix)12 Scalar (gov.sandia.n2a.language.type.Scalar)12 Constant (gov.sandia.n2a.language.Constant)10 Operator (gov.sandia.n2a.language.Operator)10 Type (gov.sandia.n2a.language.Type)10 AccessVariable (gov.sandia.n2a.language.AccessVariable)7 Visitor (gov.sandia.n2a.language.Visitor)7 BuildMatrix (gov.sandia.n2a.language.BuildMatrix)6 Input (gov.sandia.n2a.language.function.Input)6 Output (gov.sandia.n2a.language.function.Output)6 ReadMatrix (gov.sandia.n2a.language.function.ReadMatrix)6 Simulator (gov.sandia.n2a.backend.internal.Simulator)5 EquationSet (gov.sandia.n2a.eqset.EquationSet)5 Variable (gov.sandia.n2a.eqset.Variable)5 Add (gov.sandia.n2a.language.operator.Add)5 Event (gov.sandia.n2a.language.function.Event)4 MatrixDense (gov.sandia.n2a.linear.MatrixDense)4 Backend (gov.sandia.n2a.plugins.extpoints.Backend)3 ConnectionMatrix (gov.sandia.n2a.eqset.EquationSet.ConnectionMatrix)2