/** * Return the schedule. This method attempts to construct a schedule based on a topological sort * of the graph (which uses causality interfaces). If there are cycles, no such sort is possible, * and this method simply returns a schedule that lists the actors in their natural order in the * container, which is the order in which they were created (unless that order has been modified * through "bring to front" or "send to back"). This method should not be called directly, but * rather the getSchedule() method (which is defined in the superclass) will call it when the * schedule is invalid. This method is not synchronized on the workspace. * * @return A schedule. */ @Override protected Schedule _getSchedule() { StaticSchedulingDirector director = (StaticSchedulingDirector) getContainer(); if (director == null) { throw new NotSchedulableException(this, "No director. "); } CompositeActor compositeActor = (CompositeActor) director.getContainer(); if (compositeActor == null) { throw new NotSchedulableException(this, "No container."); } CausalityInterfaceForComposites causality = (CausalityInterfaceForComposites) compositeActor.getCausalityInterface(); List<Actor> sortedActors; try { sortedActors = causality.topologicalSort(); } catch (IllegalActionException ex) { sortedActors = compositeActor.deepEntityList(); } Schedule schedule = new Schedule(); if (_debugging) { _debug("## Schedule generated:"); } for (Actor actor : sortedActors) { Firing firing = new Firing(actor); schedule.add(firing); if (_debugging) { _debug(" - " + actor.getFullName()); } } if (_debugging) { _debug("## End of schedule."); } setValid(true); return schedule; }
/** * Returns <code>null</code> as a Tree EditPart holds no children under it. * * @return <code>null</code> */ protected List getModelChildren() { NamedObj namedObjectModel = getNamedObjectModel(); List children = new ArrayList(); if (namedObjectModel instanceof AtomicActor) { AtomicActor actor = (AtomicActor) namedObjectModel; children.addAll(actor.attributeList(Parameter.class)); children.addAll(actor.inputPortList()); children.addAll(actor.outputPortList()); } else if (namedObjectModel instanceof CompositeActor) { CompositeActor composite = (CompositeActor) namedObjectModel; children.addAll(composite.attributeList(AtomicActor.class)); children.addAll(composite.attributeList(Parameter.class)); children.addAll(composite.inputPortList()); Enumeration enumeration = composite.getEntities(); while (enumeration.hasMoreElements()) { children.add(enumeration.nextElement()); } } else if (namedObjectModel instanceof IOPort) { IOPort text = (IOPort) namedObjectModel; children.addAll(text.attributeList(ptolemy.kernel.util.StringAttribute.class)); } else if (namedObjectModel instanceof Vertex) { Vertex text = (Vertex) namedObjectModel; children.addAll(text.attributeList(Vertex.class)); } else if (namedObjectModel instanceof TextAttribute) { TextAttribute text = (TextAttribute) namedObjectModel; children.addAll(text.attributeList(ptolemy.kernel.util.StringAttribute.class)); } else if (namedObjectModel instanceof Director) { Director director = (Director) namedObjectModel; children.addAll(director.attributeList(Parameter.class)); } return children; }
@Override public void setFocus() { super.setFocus(); MoMLParser.purgeAllModelRecords(); if (actor == null && momlPath != null) { final MoMLParser parser = new MoMLParser(new Workspace()); try { final IResource moml = ResourcesPlugin.getWorkspace().getRoot().findMember(momlPath); CompositeActor toplevel = (CompositeActor) parser.parse(null, new File(moml.getLocation().toString()).toURL()); toplevel.workspace().setName(moml.getProject().getName()); ComponentEntity entity = PasserelleProjectUtils.findEntityByName(toplevel, actorName); if (entity != null && entity.getName().equals(actorName)) { this.actor = (SubstitutionParticipant) entity; } } catch (Exception e) { logger.error("Cannot parse " + momlPath, e); } } if (actor != null) { viewer.setContentProvider(createActorContentProvider()); viewer.setInput(new Object()); } }
/** Create the shared plot and set it up based on the director parameters. */ public void _createView() { super._createView(); try { // Find out how many iterations the director expects to run for. CompositeActor toplevel = (CompositeActor) _toplevel; SDFDirector director = (SDFDirector) toplevel.getDirector(); int iterations = ((IntToken) (director.iterations.getToken())).intValue(); _sketchedSource = (SketchedSource) toplevel.getEntity("SketchedSource"); // Note: The order of the following is important. // First, specify how long the sketched plot should be. _sketchedSource.length.setToken(new IntToken(iterations)); // Then, create the plot and place it in this applet, // and specify to both the source and destination actors // to use the same plot widget. EditablePlot plot = new EditablePlot(); plot.setSize(700, 300); plot.setTitle("Editable envelope"); plot.setXRange(0, iterations); plot.setButtons(true); getContentPane().add(plot); _sketchedSource.place(new AWTContainer(plot)); plot.setBackground(null); plot.addEditListener(this); } catch (Exception ex) { report("Error constructing model.", ex); } }
/** * Initialize the applet. This method is called by the browser or applet viewer to inform this * applet that it has been loaded into the system. It is always called before the first time that * the start() method is called. In this base class, this method creates a new workspace, and * instantiates in it the model whose class name is given by the <i>modelClass</i> applet * parameter. If that model does not contain a manager, then this method creates one for it. */ public void init() { super.init(); _setupOK = true; _workspace = new Workspace(getClass().getName()); try { _toplevel = _createModel(_workspace); _toplevel.setModelErrorHandler(new BasicModelErrorHandler()); // This might not actually be a top level, because we might // be looking inside. So we check before creating a manager. if ((_toplevel.getContainer() == null) && _toplevel instanceof CompositeActor) { if (((CompositeActor) _toplevel).getManager() == null) { _manager = new Manager(_workspace, "manager"); _manager.addExecutionListener(this); ((CompositeActor) _toplevel).setManager(_manager); } else { _manager = ((CompositeActor) _toplevel).getManager(); } } } catch (Exception ex) { _setupOK = false; report("Creation of model failed:\n", ex); } _createView(); }
/** * Return a string representation of the buffer sizes of the relations in the model. This * diagnostic method shows the buffer size expression for each relation along with the relation * itself. * * @return A string representation of the buffer sizes. */ public String displayBufferSizes() { StringBuffer result = new StringBuffer(); PSDFDirector director = (PSDFDirector) getContainer(); CompositeActor model = (CompositeActor) director.getContainer(); Iterator relations = model.relationList().iterator(); while (relations.hasNext()) { Relation relation = (Relation) relations.next(); Variable variable = (Variable) relation.getAttribute("bufferSize"); result.append(relation.getName() + ": "); if (variable == null) { result.append("null"); } else { result.append(variable.getExpression()); } result.append("\n"); } return result.toString(); }
/** * Generate the initialize code for the associated SDF director. * * @return The generated initialize code. * @exception IllegalActionException If the helper associated with an actor throws it while * generating initialize code for the actor. */ public String generateInitializeCode() throws IllegalActionException { StringBuffer code = new StringBuffer(); code.append(super.generateInitializeCode()); ptolemy.actor.CompositeActor container = (ptolemy.actor.CompositeActor) getComponent().getContainer(); CodeGeneratorHelper containerHelper = (CodeGeneratorHelper) _getHelper(container); // Generate code for creating external initial production. Iterator outputPorts = container.outputPortList().iterator(); while (outputPorts.hasNext()) { IOPort outputPort = (IOPort) outputPorts.next(); int rate = DFUtilities.getTokenInitProduction(outputPort); if (rate > 0) { for (int i = 0; i < outputPort.getWidthInside(); i++) { if (i < outputPort.getWidth()) { String name = outputPort.getName(); if (outputPort.isMultiport()) { name = name + '#' + i; } for (int k = 0; k < rate; k++) { code.append(CodeStream.indent(containerHelper.getReference(name + "," + k))); code.append(" = "); code.append(containerHelper.getReference("@" + name + "," + k)); code.append(";" + _eol); } } } // The offset of the ports connected to the output port is // updated by outside director. _updatePortOffset(outputPort, code, rate); } } return code.toString(); }
/** * Create a LinkedList containing all the instances of Actor contained by the CompositeActor in * which this director is embedded. * * @return A LinkedList containing all the instances of Actor contained by the CompositeActor in * which this director is embedded. */ private LinkedList getActors() { if (VERBOSE) { System.out.println("Getting actors"); } CompositeActor container = (CompositeActor) getContainer(); // A linked list containing all the actors. LinkedList allActorList = new LinkedList(); // Populate it. for (Iterator entities = container.deepEntityList().iterator(); entities.hasNext(); ) { ComponentEntity entity = (ComponentEntity) entities.next(); // Fill allActorList with the list of things that we can schedule if (entity instanceof Actor) { allActorList.addLast(entity); } } return allActorList; }
/** * Override the base class to open the model specified if the attribute is modelFileOrURL, or for * other parameters, to cache their values. * * @param attribute The attribute that changed. * @exception IllegalActionException If the change is not acceptable to this container (not thrown * in this base class). */ public void attributeChanged(Attribute attribute) throws IllegalActionException { if (attribute == modelFileOrURL) { // Open the file and read the MoML to create a model. URL url = modelFileOrURL.asURL(); if (url != null) { // By specifying no workspace argument to the parser, we // are asking it to create a new workspace for the referenced // model. This is necessary because the execution of that // model will proceed through its own sequences, and it // will need to get write permission on the workspace. // Particularly if it is executing in a new thread, then // during the fire() method of this actor it would be // inappropriate to grant write access on the workspace // of this actor. MoMLParser parser = new MoMLParser(); try { _model = parser.parse(null, url); } catch (Exception ex) { throw new IllegalActionException(this, ex, "Failed to read model."); } // Create a manager, if appropriate. if (_model instanceof CompositeActor) { _manager = new Manager(_model.workspace(), "Manager"); ((CompositeActor) _model).setManager(_manager); if (_debugging) { _debug("** Created new manager."); } } } else { // URL is null... delete the current model. _model = null; _manager = null; _throwable = null; } } else if (attribute == maxOutputLength) { IntToken length = (IntToken) maxOutputLength.getToken(); if (length.intValue() > 0) { _outputLength = length.intValue(); } else { throw new IllegalActionException(this, "output array length is less than or equal 0?!"); } } else { super.attributeChanged(attribute); } }
/** * Check to see if the buffer size for the current schedule is greater than the previous size. If * so, set the buffer size to the current buffer size needed. * * @exception IllegalActionException If thrown while getting helper or buffer size. */ protected void _updatePortBufferSize() throws IllegalActionException { ptolemy.domains.sdf.kernel.SDFDirector director = (ptolemy.domains.sdf.kernel.SDFDirector) getComponent(); CompositeActor container = (CompositeActor) director.getContainer(); ptolemy.codegen.c.actor.TypedCompositeActor containerHelper = (ptolemy.codegen.c.actor.TypedCompositeActor) _getHelper(container); Iterator actors = container.deepEntityList().iterator(); while (actors.hasNext()) { Actor actor = (Actor) actors.next(); CodeGeneratorHelper actorHelper = (CodeGeneratorHelper) _getHelper((NamedObj) actor); Iterator inputPorts = actor.inputPortList().iterator(); while (inputPorts.hasNext()) { IOPort inputPort = (IOPort) inputPorts.next(); for (int k = 0; k < inputPort.getWidth(); k++) { int newCapacity = getBufferSize(inputPort, k); int oldCapacity = actorHelper.getBufferSize(inputPort, k); if (newCapacity > oldCapacity) { actorHelper.setBufferSize(inputPort, k, newCapacity); } } } } Iterator outputPorts = container.outputPortList().iterator(); while (outputPorts.hasNext()) { IOPort outputPort = (IOPort) outputPorts.next(); for (int k = 0; k < outputPort.getWidthInside(); k++) { int newCapacity = getBufferSize(outputPort, k); int oldCapacity = containerHelper.getBufferSize(outputPort, k); if (newCapacity > oldCapacity) { containerHelper.setBufferSize(outputPort, k, newCapacity); } } } }
/** * Topology analysis to get a list of agents. The agents should be TypedCompositeActor with * parameter charonMode as null (by default) or true. * * @param actor Container to be analyzed to return agent list. * @return List of agents defined in model. */ private LinkedList _agents(CompositeActor actor) throws IllegalActionException { LinkedList agentList = new LinkedList(); ListIterator agentsIterator = actor.entityList(TypedCompositeActor.class).listIterator(); while (agentsIterator.hasNext()) { TypedCompositeActor agent = (TypedCompositeActor) agentsIterator.next(); Parameter charonAgent = (Parameter) agent.getAttribute("charonAgent"); if ((charonAgent == null) || ((BooleanToken) charonAgent.getToken()).booleanValue()) { agentList.add(agent); } } return agentList; }
/** * Read in a MoML class, sanitize the top level name, initialize the model. Usually initialize() * is called after calling readInModel(). * * <p>If the director is an SDF director, then the number of iterations is handled specially. If * the director is an SDF director and a parameter called "copernicus_iterations" is present, then * the value of that parameter is used as the number of iterations. If the director is an SDF * director, and there is no "copernicus_iterations" parameter but the * "ptolemy.ptII.copernicusIterations" Java property is set, then the value of that property is * used as the number of iterations. * * @param toplevel The model we are generating code for. */ public void initialize(CompositeActor toplevel) throws IllegalActionException, NameDuplicationException { _toplevel = toplevel; // Applet codegen works with all directors, not just SDF. Director topLevelDirector = toplevel.getDirector(); // FIXME: nearly duplicate code in java/TestApplication.java if (topLevelDirector != null && topLevelDirector instanceof SDFDirector) { SDFDirector director = (SDFDirector) topLevelDirector; Parameter iterations = (Parameter) director.getAttribute("iterations"); Parameter copernicus_iterations = (Parameter) director.getAttribute("copernicus_iterations"); // Set to be a large number of iterations, unless // copernicus_iterations is set. if (copernicus_iterations != null) { iterations.setToken(copernicus_iterations.getToken()); } else { String copernicusIterations = StringUtilities.getProperty("ptolemy.ptII.copernicusIterations"); if (copernicusIterations.length() > 0) { System.out.println( "KernelMain: " + "Setting number of iterations to " + copernicusIterations); iterations.setToken(new IntToken(copernicusIterations)); } } } // Initialize the model to ensure type resolution and scheduling // are done. try { Manager manager = new Manager(_toplevel.workspace(), "manager"); _toplevel.setManager(manager); manager.preinitializeAndResolveTypes(); } catch (Exception exception) { throw new KernelRuntimeException(exception, "Could not initialize composite actor"); } }
/** * Transform the graphic block diagram to text expression. Assume container only contains atomic * actors. * * @param container contains actors. * @return txtExpression of graphic block diagram. */ private String _graphToText(CompositeActor container) throws IllegalActionException { // It is not trivial to transform graph to text. // Here, we assume there is only one Integrator and one expression actor. String txtString = ""; LinkedList actors = new LinkedList(container.entityList()); ListIterator actorIterator = actors.listIterator(); // we begin with Integrator. AtomicActor beginActor = new AtomicActor(); while (actorIterator.hasNext()) { Actor actor = (Actor) actorIterator.next(); if (Integrator.class.isInstance(actor)) { beginActor = (AtomicActor) actor; break; } } if (beginActor == null) { throw new IllegalActionException("Integrator is needed!"); } else { // we trace the output of the Integrator // we assume the output of the integrator is connectted // to the container output directly and they have same names // for simplicity at this time. // FIXME: we really need to reconsider the methods of ports. List outputs = beginActor.outputPortList(); ListIterator outputIterator = outputs.listIterator(); String outputName = ""; if (outputs.size() != 1) { throw new IllegalActionException("Integrator only have one output! " + outputs.size()); } else { TypedIOPort output = (TypedIOPort) outputIterator.next(); ListIterator sinkIterator = output.connectedPortList().listIterator(); while (sinkIterator.hasNext()) { TypedIOPort sink = (TypedIOPort) sinkIterator.next(); if (sink.isOutput()) { // FIXME: we need to consider depth in hierarchy // to avoid two outputs connected to same output // of composite actor outputName = sink.getName(); } } txtString += ("diff { d(" + outputName + ") == "); } // we trace the input of the integrator List inputs = beginActor.inputPortList(); ListIterator inputIterator = inputs.listIterator(); if (inputs.size() != 1) { throw new IllegalActionException("Integrator only have one input!"); } else { TypedIOPort input = (TypedIOPort) inputIterator.next(); List sources = input.connectedPortList(); if (sources.size() != 1) { throw new IllegalActionException("There is only one connection to the input!"); } else { TypedIOPort source = (TypedIOPort) sources.get(0); // if there is just an integrator if (source.isInput()) { txtString += (source.getName() + " ; }" + _endLine); } // if there is some expression actor else { AtomicActor expressionActor = (AtomicActor) source.getContainer(); if (Expression.class.isInstance(expressionActor)) { Parameter expPara = (Parameter) expressionActor.getAttribute("expression"); txtString += (expPara.getExpression() + " ; } " + _endLine); } else { throw new IllegalActionException("This should be Expression Atomic Actor!"); } } } } } return txtString; }
/** * Generate code for the agent. * * @param CompositeActor The agent generated code from. * @return The agent code. */ private String _agentCode(CompositeActor actor) throws IllegalActionException { // System.out.println("dealing with " + actor.getFullName()); String codeString = "agent"; String parameterString = ""; String inputString = ""; String outputString = ""; String initString = ""; String modeString = ""; String modeParameterString = ""; String typedModeParameterString = ""; String flowString = ""; String invariantString = ""; LinkedList parameterList = (LinkedList) actor.attributeList(Parameter.class); /* Parameter invariantPara = (Parameter) actor.getAttribute("_invariant"); if (invariantPara != null) { invariantString = "inv { " + ((StringToken)invariantPara.getToken()).stringValue() + " } "; //get rid of _invariant parameter parameterList.remove(invariantPara);; //FIXME: it seems that after getAttribute, //the attribute does not exist? } */ ListIterator assertions = _assertions(actor).listIterator(); while (assertions.hasNext()) { Assertion assertion = (Assertion) assertions.next(); if (invariantString.length() == 0) { invariantString = "inv { " + assertion.assertion.getExpression(); } else { invariantString += (" ; " + assertion.assertion.getExpression()); } invariantString += " } "; } int parameterNumber = parameterList.size(); ListIterator parameters = parameterList.listIterator(); _inPorts = actor.inputPortList().iterator(); while (_inPorts.hasNext()) { if (inputString == "") { inputString += ("read analog real " + ((NamedObj) _inPorts.next()).getName()); } else { inputString += (", " + ((NamedObj) _inPorts.next()).getName()); } } if (inputString != "") { inputString += ";"; } _outPorts = actor.outputPortList().iterator(); int outportNumber = actor.outputPortList().size(); // since the parameters are either for mode or for outport, // we assume the number of the parameters for outport is the same // with the number of outport(s) boolean parameterForOutport = false; while (parameters.hasNext()) { String parameterName = ((NamedObj) parameters.next()).getName(); if (parameterName.startsWith("_")) { continue; } if (parameters.nextIndex() > (parameterNumber - outportNumber)) { parameterForOutport = true; } if (parameterString == "") { parameterString += ("real " + parameterName); } else { parameterString += (", real " + parameterName); } if (parameterForOutport) { if (_outPorts.hasNext()) { String outportName = ((NamedObj) _outPorts.next()).getName(); if (outputString == "") { outputString += ("write analog real " + outportName); } else { outputString += (", " + outportName); } initString += (outportName + " = " + parameterName + " ;"); } } else { if (modeParameterString == "") { modeParameterString += parameterName; typedModeParameterString += ("real " + parameterName); } else { modeParameterString += (", " + parameterName); typedModeParameterString += (", real " + parameterName); } } } if (outputString != "") { outputString += ";"; } initString = "init { " + initString + " }"; modeString = "mode top = " + actor.getName() + "TopMode" + " ( " + modeParameterString + " ) ;"; codeString += (" " + actor.getName() + " ( " + parameterString + " )" + _endLine + "{" + _endLine + " " + outputString + _endLine + " " + inputString + _endLine + " " + initString + _endLine + " " + modeString + _endLine + "}" + _endLine); if (FSMDirector.class.isInstance(actor.getDirector())) { // mode code generation goes here. _modeCode += ("mode " + actor.getName() + "TopMode" + " ( " + typedModeParameterString + " )" + _endLine + "{" + _endLine + " " + outputString + _endLine + " " + inputString + _endLine); // notice the _fsmModeCode(actor) will modify the _modeCode with transitions code // and return the mode code for each sub mode.(refinement) String subModeString = _fsmModeCode( ((FSMDirector) actor.getDirector()).getController(), inputString, outputString); _modeCode += (" " + invariantString + _endLine + "}" + _endLine + subModeString); } else { flowString = _graphToText(actor); _modeCode += ("mode " + actor.getName() + "TopMode" + " ( " + typedModeParameterString + " )" + _endLine + "{" + _endLine + " " + outputString + _endLine + " " + inputString + _endLine + " " + flowString + _endLine + " " + invariantString + _endLine + "}" + _endLine); } return codeString; }
// we assume the composite agent has no mode // only atomic agent has mode private String _compositeAgentCode(CompositeActor actor) throws IllegalActionException { if (FSMDirector.class.isInstance(actor.getDirector())) { // System.out.println("in FSM"); return _agentCode(actor); } LinkedList subAgents = _agents(actor); if (subAgents.size() == 0) { return _agentCode(actor); } String compositeCodeString = ""; String subAgentCode = ""; String privateVariables = ""; ListIterator subAgentsIterator = subAgents.listIterator(); // the output ports of composite agent // In fact, there is always at most one output List outputPorts = actor.outputPortList(); ListIterator outputPortsIterator = actor.outputPortList().listIterator(); if (outputPorts.size() > 1) { throw new IllegalActionException(" The agent has more than one output!"); } // get the source subAgent name String outputAgentName = ""; String outputPortName = ""; String sourceForOutputName = ""; while (outputPortsIterator.hasNext()) { TypedIOPort output = (TypedIOPort) outputPortsIterator.next(); outputPortName = output.getName(); ListIterator sourcePorts = output.insidePortList().listIterator(); TypedIOPort sourcePort = new TypedIOPort(); while (sourcePorts.hasNext()) { TypedIOPort port = (TypedIOPort) sourcePorts.next(); if (port.isOutput()) { if (sourcePort == null) { throw new IllegalActionException(" The output has more than one source!"); } else { sourcePort = port; sourceForOutputName = sourcePort.getName(); Nameable sourceContainer = sourcePort.getContainer(); outputAgentName = sourceContainer.getName(); } } } } while (subAgentsIterator.hasNext()) { String subAgentConnectionInputs = ""; String subAgentConnectionOutputs = ""; CompositeActor subAgent = (CompositeActor) subAgentsIterator.next(); if (outputAgentName.equals(subAgent.getName())) { // the inside output actually is input to outside environment subAgentConnectionOutputs += sourceForOutputName; subAgentConnectionInputs += outputPortName; } subAgentCode += (" agent " + subAgent.getName().toLowerCase() + " = " + subAgent.getName() + " ( "); if (actor.depthInHierarchy() == 0) { subAgentCode += _agentParameterTokens((NamedObj) subAgent); } else { subAgentCode += _agentParameters((NamedObj) subAgent, false); } subAgentCode += (" );" + _endLine); ListIterator subAgentInputs = subAgent.inputPortList().listIterator(); while (subAgentInputs.hasNext()) { TypedIOPort input = (TypedIOPort) subAgentInputs.next(); LinkedList sourceList = _shallowSourcePortList(input); ListIterator sources = sourceList.listIterator(); boolean privateVariable = true; while (sources.hasNext()) { TypedIOPort source = (TypedIOPort) sources.next(); if (source.depthInHierarchy() != input.depthInHierarchy()) { privateVariable = false; } if (!(source.getName().equals(input.getName()))) { if (subAgentConnectionOutputs == "") { subAgentConnectionOutputs += source.getName(); subAgentConnectionInputs += input.getName(); } else { subAgentConnectionOutputs += (", " + source.getName()); subAgentConnectionInputs += (", " + input.getName()); } } } if (privateVariable) { if (privateVariables == "") { privateVariables += ("private analog real " + input.getName()); } else { privateVariables += (", " + input.getName()); } } } if (subAgentConnectionInputs.length() != 0) { subAgentCode += (" [ " + subAgentConnectionInputs + " := " + subAgentConnectionOutputs + " ] ;" + _endLine); } compositeCodeString += _compositeAgentCode(subAgent); } compositeCodeString += "agent"; String parameterString = ""; String inputString = ""; String outputString = ""; String initString = ""; String modeString = ""; String modeParameterString = ""; LinkedList parameterList = (LinkedList) actor.attributeList(Parameter.class); int parameterNumber = parameterList.size(); ListIterator parameters = parameterList.listIterator(); _inPorts = actor.inputPortList().iterator(); while (_inPorts.hasNext()) { if (inputString == "") { inputString += ("read analog real " + ((NamedObj) _inPorts.next()).getName()); } else { inputString += (", " + ((NamedObj) _inPorts.next()).getName()); } } if (inputString != "") { inputString += ";"; } _outPorts = actor.outputPortList().iterator(); if (_outPorts.hasNext()) { String outportName = ((NamedObj) _outPorts.next()).getName(); if (outputString == "") { outputString += ("write analog real " + outportName); } else { outputString += (", " + outportName); } } if (outputString != "") { outputString += ";"; } if (privateVariables.length() != 0) { privateVariables += ";"; } compositeCodeString += (" " + actor.getName() + " ( "); if (actor.depthInHierarchy() != 0) { compositeCodeString += _agentParameters((NamedObj) actor, true); } compositeCodeString += (" )" + _endLine + "{" + _endLine + " " + outputString + _endLine + " " + inputString + _endLine + " " + privateVariables + _endLine + subAgentCode + _endLine + "}" + _endLine); return compositeCodeString; }
// Topology analysis to get the list of assertions. private LinkedList _assertions(CompositeActor actor) throws IllegalActionException { LinkedList assertionList = new LinkedList(); assertionList = (LinkedList) actor.entityList(Assertion.class); return assertionList; }
/** * Return the parameterized scheduling sequence. An exception will be thrown if the graph is not * schedulable. * * @return A schedule of the deeply contained opaque entities in the firing order. * @exception NotSchedulableException If a parameterized schedule cannot be derived for the model. * @exception IllegalActionException If the rate parameters of the model are not correct, or the * computed rates for external ports are not correct. */ @SuppressWarnings("unused") protected Schedule _getSchedule() throws NotSchedulableException, IllegalActionException { PSDFDirector director = (PSDFDirector) getContainer(); CompositeActor model = (CompositeActor) director.getContainer(); // Get the vectorization factor. String vectorizationFactorExpression = "1"; String vectorizationName = director.vectorizationFactor.getName(model); vectorizationFactorExpression = vectorizationName.replaceAll("\\.", "::"); if (vectorizationFactorExpression.indexOf(" ") != -1) { throw new InternalErrorException( "The vectorizationFactor " + "PSDFDirector parameter must " + "not have spaces in its value. The original value " + "was \"" + vectorizationName + "\". Try changing the name of " + "director."); } PSDFGraphReader graphReader = new PSDFGraphReader(); PSDFGraph graph = (PSDFGraph) graphReader.convert(model); _debug("PSDF graph = \n" + graph.toString()); if (_debugFlag) { graph.printEdgeRateExpressions(); } PSDFAPGANStrategy strategy = new PSDFAPGANStrategy(graph); ptolemy.graph.sched.Schedule graphSchedule = strategy.schedule(); _debug("P-APGAN schedule = \n" + graphSchedule.toString()); SymbolicScheduleElement resultSchedule = _expandAPGAN(graph, strategy.getClusterManager().getRootNode(), strategy); resultSchedule.setIterationCount(vectorizationFactorExpression); _debug("Final schedule = \n" + resultSchedule.toString()); if (_debugging) { _debug("The buffer size map:\n"); Iterator relations = _bufferSizeMap.keySet().iterator(); while (relations.hasNext()) { Relation relation = (Relation) relations.next(); _debug(relation.getName() + ": " + _bufferSizeMap.get(relation) + "\n"); } } _saveBufferSizes(_bufferSizeMap); // Crazy hack to infer firing counts for each actor. try { _inferFiringCounts(resultSchedule, null); } catch (NameDuplicationException ex) { throw new NotSchedulableException(new LinkedList(), ex, "Error recording firing counts"); } // Crazy hack to Infer port production: FIXME: This should be // done as part of the APGAN expansion where the rates of // external ports are unknown The reason is that it will make // rate information propagate from an actor input port to // another actors input port that are connected on the inside // to the same external input port. See // BaseSDFScheduler.setContainerRates. Iterator ports = model.portList().iterator(); while (ports.hasNext()) { IOPort port = (IOPort) ports.next(); if (_debugging && VERBOSE) { _debug("External Port " + port.getName()); } if (port.isInput() && port.isOutput()) { throw new NotSchedulableException( port, "External port is both an input and an output, " + "which is not allowed in SDF."); } else if (port.isInput()) { List sinks = port.insideSinkPortList(); if (sinks.size() > 0) { IOPort connectedPort = (IOPort) sinks.get(0); Entity entity = (Entity) connectedPort.getContainer(); String name = connectedPort.getName(model); String identifier = name.replaceAll("\\.", "::"); String sinkExpression; Variable sinkRateVariable = DFUtilities.getRateVariable(connectedPort, "tokenConsumptionRate"); if (sinkRateVariable == null) { sinkExpression = "1"; } else { sinkExpression = identifier + "::" + sinkRateVariable.getName(); } String expression = sinkExpression + " * " + entity.getName() + "::firingsPerIteration"; DFUtilities.setExpressionIfNotDefined(port, "tokenConsumptionRate", expression); if (_debugging && VERBOSE) { _debug("Setting tokenConsumptionRate to " + expression); } } } else if (port.isOutput()) { List sources = port.insideSourcePortList(); if (sources.size() > 0) { IOPort connectedPort = (IOPort) sources.get(0); Entity entity = (Entity) connectedPort.getContainer(); String name = connectedPort.getName(model); String identifier = name.replaceAll("\\.", "::"); Variable sourceRateVariable = DFUtilities.getRateVariable(connectedPort, "tokenProductionRate"); String sourceExpression; if (sourceRateVariable == null) { sourceExpression = "1"; } else { sourceExpression = identifier + "::" + sourceRateVariable.getName(); } String expression = sourceExpression + " * " + entity.getName() + "::firingsPerIteration"; DFUtilities.setExpressionIfNotDefined(port, "tokenProductionRate", expression); if (_debugging && VERBOSE) { _debug("Setting tokenProductionRate to " + expression); } } // Infer init production. // Note that this is a very simple type of inference... // However, in general, we don't want to try to // flatten this model... // Iterator connectedPorts = // port.insideSourcePortList().iterator(); // IOPort foundOutputPort = null; // int inferredRate = 0; // while (connectedPorts.hasNext()) { // IOPort connectedPort = (IOPort) connectedPorts.next(); // int newRate; // if (connectedPort.isOutput()) { // newRate = // DFUtilities.getTokenInitProduction(connectedPort); // } else { // newRate = 0; // } // // If we've already set the rate, then check that the // // rate for any other internal port is correct. // if (foundOutputPort != null && // newRate != inferredRate) { // throw new NotSchedulableException( // "External output port " + port // + " is connected on the inside to ports " // + "with different initial production: " // + foundOutputPort + " and " // + connectedPort); // } // foundOutputPort = connectedPort; // inferredRate = newRate; // } // DFUtilities._setIfNotDefined( // port, "tokenInitProduction", inferredRate); // if (_debugging && VERBOSE) { // _debug("Setting tokenInitProduction to " // + inferredRate); // } } else { throw new NotSchedulableException( port, "External port is neither an input and an output, " + "which is not allowed in SDF."); } } // Set the schedule to be valid. setValid(true); if (resultSchedule instanceof Schedule) { return (Schedule) resultSchedule; } else { // Must be ScheduleElement. Schedule schedule = new Schedule(); schedule.add((ScheduleElement) resultSchedule); return schedule; } }
/** * Generate code for transferring enough tokens to fulfill the output production rate. * * @param outputPort The port to transfer tokens. * @param code The string buffer that the generated code is appended to. * @exception IllegalActionException If thrown while transferring tokens. */ public void generateTransferOutputsCode(IOPort outputPort, StringBuffer code) throws IllegalActionException { code.append( CodeStream.indent( _codeGenerator.comment("SDFDirector: " + "Transfer tokens to the outside."))); int rate = DFUtilities.getTokenProductionRate(outputPort); CompositeActor container = (CompositeActor) getComponent().getContainer(); ptolemy.codegen.c.actor.TypedCompositeActor compositeActorHelper = (ptolemy.codegen.c.actor.TypedCompositeActor) _getHelper(container); if (container instanceof TypedCompositeActorWithCoSimulation) { if (_portNumber == 0) { int numberOfOutputPorts = container.outputPortList().size(); code.append(_INDENT2 + "jobjectArray tokensToAllOutputPorts;" + _eol); code.append( _INDENT2 + "jclass objClass = (*env)->FindClass(env, " + "\"Ljava/lang/Object;\");" + _eol); code.append( _INDENT2 + "tokensToAllOutputPorts = " + "(*env)->NewObjectArray(env, " + numberOfOutputPorts + ", objClass, NULL);" + _eol); } String portName = outputPort.getName(); String tokensToThisPort = "tokensTo" + portName; ; Type type = ((TypedIOPort) outputPort).getType(); int numberOfChannels = outputPort.getWidthInside(); code.append(_INDENT2 + "jobjectArray " + tokensToThisPort + ";" + _eol); if (type == BaseType.INT) { if (!_intFlag) { code.append(_INDENT2 + "jclass objClassI = (*env)->FindClass(env, " + "\"[I\");" + _eol); _intFlag = true; } code.append( _INDENT2 + tokensToThisPort + " = (*env)->NewObjectArray(env, " + numberOfChannels + ", objClassI, NULL);" + _eol); } else if (type == BaseType.DOUBLE) { if (!_doubleFlag) { code.append(_INDENT2 + "jclass objClassD = (*env)->FindClass(env, " + "\"[D\");" + _eol); _doubleFlag = true; } code.append( _INDENT2 + tokensToThisPort + " = (*env)->NewObjectArray(env, " + numberOfChannels + ", objClassD, NULL);" + _eol); } else { // FIXME: need to deal with other types } for (int i = 0; i < outputPort.getWidthInside(); i++) { String tokensToOneChannel = "tokensToOneChannelOf" + portName; if (i == 0) { if (type == BaseType.INT) { code.append(_INDENT2 + "jint " + tokensToOneChannel + "[" + rate + "];" + _eol); } else if (type == BaseType.DOUBLE) { code.append(_INDENT2 + "jdouble " + tokensToOneChannel + "[" + rate + "];" + _eol); } else { // FIXME: need to deal with other types } } String portNameWithChannelNumber = portName; if (outputPort.isMultiport()) { portNameWithChannelNumber = portName + '#' + i; } for (int k = 0; k < rate; k++) { code.append( _INDENT2 + tokensToOneChannel + "[" + k + "] = " + compositeActorHelper.getReference("@" + portNameWithChannelNumber + "," + k) + ";" + _eol); } String tokensToOneChannelArray = "arr" + portName + i; if (type == BaseType.INT) { code.append( _INDENT2 + "jintArray " + tokensToOneChannelArray + " = " + "(*env)->NewIntArray(env, " + rate + ");" + _eol); code.append( _INDENT2 + "(*env)->SetIntArrayRegion" + "(env, " + tokensToOneChannelArray + ", 0, " + rate + ", " + tokensToOneChannel + ");" + _eol); } else if (type == BaseType.DOUBLE) { code.append( _INDENT2 + "jdoubleArray " + tokensToOneChannelArray + " = " + "(*env)->NewDoubleArray(env, " + rate + ");" + _eol); code.append( _INDENT2 + "(*env)->SetDoubleArrayRegion" + "(env, " + tokensToOneChannelArray + ", 0, " + rate + ", " + tokensToOneChannel + ");" + _eol); } else { // FIXME: need to deal with other types } code.append( _INDENT2 + "(*env)->SetObjectArrayElement" + "(env, " + tokensToThisPort + ", " + i + ", " + tokensToOneChannelArray + ");" + _eol); code.append( _INDENT2 + "(*env)->DeleteLocalRef(env, " + tokensToOneChannelArray + ");" + _eol); } code.append( _INDENT2 + "(*env)->SetObjectArrayElement" + "(env, tokensToAllOutputPorts, " + _portNumber + ", " + tokensToThisPort + ");" + _eol); code.append(_INDENT2 + "(*env)->DeleteLocalRef(env, " + tokensToThisPort + ");" + _eol); _portNumber++; } else { for (int i = 0; i < outputPort.getWidthInside(); i++) { if (i < outputPort.getWidth()) { String name = outputPort.getName(); if (outputPort.isMultiport()) { name = name + '#' + i; } for (int k = 0; k < rate; k++) { code.append(CodeStream.indent(compositeActorHelper.getReference(name + "," + k))); code.append(" =" + _eol); code.append( CodeStream.indent( _INDENT2 + compositeActorHelper.getReference("@" + name + "," + k))); code.append(";" + _eol); } } } } // The offset of the ports connected to the output port is // updated by outside director. _updatePortOffset(outputPort, code, rate); }
/** * Check to see if variables are needed to represent read and write offsets for the given port. * * @return Code that declares the read and write offset variables. * @exception IllegalActionException If getting the rate or reading parameters throws it. */ protected String _createOffsetVariablesIfNeeded() throws IllegalActionException { StringBuffer code = new StringBuffer(); CompositeActor container = (CompositeActor) getComponent().getContainer(); boolean inline = ((BooleanToken) _codeGenerator.inline.getToken()).booleanValue(); StringBuffer tempCode = new StringBuffer(); Iterator outputPorts = container.outputPortList().iterator(); while (outputPorts.hasNext()) { IOPort outputPort = (IOPort) outputPorts.next(); for (int i = 0; i < outputPort.getWidthInside(); i++) { int readTokens = 0; int writeTokens = 0; // If each actor firing is inlined in the code, then read // and write positions in the buffer must return to the // previous values after one iteration of the container actor // in order to avoid using read and write offset variables. if (inline) { readTokens = DFUtilities.getRate(outputPort); writeTokens = readTokens; // If each actor firing is wrapped in a function, then read // and write positions in the buffer must return to the // previous values after one firing of this actor or one // firing of the actor that produces tokens consumed by the // inside receiver of this actor in order to avoid using // read and write offset variables. } else { readTokens = DFUtilities.getRate(outputPort); Iterator sourcePorts = outputPort.insideSourcePortList().iterator(); label1: while (sourcePorts.hasNext()) { IOPort sourcePort = (IOPort) sourcePorts.next(); CodeGeneratorHelper helper = (CodeGeneratorHelper) _getHelper(sourcePort.getContainer()); int width; if (sourcePort.isInput()) { width = sourcePort.getWidthInside(); } else { width = sourcePort.getWidth(); } for (int j = 0; j < width; j++) { Iterator channels = helper.getSinkChannels(sourcePort, j).iterator(); while (channels.hasNext()) { Channel channel = (Channel) channels.next(); if (channel.port == outputPort && channel.channelNumber == i) { writeTokens = DFUtilities.getRate(sourcePort); break label1; } } } } } tempCode.append(_createOffsetVariablesIfNeeded(outputPort, i, readTokens, writeTokens)); } } if (tempCode.length() > 0) { code.append("\n" + _codeGenerator.comment(container.getName() + "'s offset variables")); code.append(tempCode); } Iterator actors = container.deepEntityList().iterator(); while (actors.hasNext()) { StringBuffer tempCode2 = new StringBuffer(); Actor actor = (Actor) actors.next(); Iterator inputPorts = actor.inputPortList().iterator(); while (inputPorts.hasNext()) { IOPort inputPort = (IOPort) inputPorts.next(); for (int i = 0; i < inputPort.getWidth(); i++) { int readTokens = 0; int writeTokens = 0; // If each actor firing is inlined in the code, // then read and write positions in the buffer // must return to the previous values after one // iteration of the container actor in order to // avoid using read and write offset variables. if (inline) { Variable firings = (Variable) ((NamedObj) actor).getAttribute("firingsPerIteration"); int firingsPerIteration = ((IntToken) firings.getToken()).intValue(); readTokens = DFUtilities.getRate(inputPort) * firingsPerIteration; writeTokens = readTokens; // If each actor firing is wrapped in a // function, then read and write positions in // the buffer must return to the previous // values after one firing of this actor or // one firing of the actor that produces // tokens consumed by this actor in order to // avoid using read and write offset // variables. } else { readTokens = DFUtilities.getRate(inputPort); Iterator sourcePorts = inputPort.sourcePortList().iterator(); label2: while (sourcePorts.hasNext()) { IOPort sourcePort = (IOPort) sourcePorts.next(); CodeGeneratorHelper helper = (CodeGeneratorHelper) _getHelper(sourcePort.getContainer()); int width; if (sourcePort.isInput()) { width = sourcePort.getWidthInside(); } else { width = sourcePort.getWidth(); } for (int j = 0; j < width; j++) { Iterator channels = helper.getSinkChannels(sourcePort, j).iterator(); while (channels.hasNext()) { Channel channel = (Channel) channels.next(); if (channel.port == inputPort && channel.channelNumber == i) { writeTokens = DFUtilities.getRate(sourcePort); break label2; } } } } } tempCode2.append(_createOffsetVariablesIfNeeded(inputPort, i, readTokens, writeTokens)); } } if (tempCode2.length() > 0) { code.append("\n" + _codeGenerator.comment(actor.getName() + "'s offset variables")); code.append(tempCode2); } } return code.toString(); }
/** * Execute the filter model on each input array element until it gets as many elements as * specified by the <i>maxOutputLength</i> parameter. If there are no enough elements satisfying * the filter model, then only output all the satisfied elements. Before running the filter model, * this method update the filter model's <i>inputArrayElement</i> parameter for each array * element. After running the filter model, this method looks for the <i>evaluatedValue</i> * parameter and keep the input element if the evaluated value is ture, otherwise, skip the * element. * * @exception IllegalActionException If there is no director, or if the director's action methods * throw it. */ public void fire() throws IllegalActionException { super.fire(); if (_model instanceof CompositeActor) { CompositeActor executable = (CompositeActor) _model; _manager = executable.getManager(); if (_manager == null) { throw new InternalErrorException("No manager!"); } if (_debugging) { _manager.addDebugListener(this); Director director = executable.getDirector(); if (director != null) { director.addDebugListener(this); } } else { _manager.removeDebugListener(this); Director director = executable.getDirector(); if (director != null) { director.removeDebugListener(this); } } int i = 0; int j = 0; LinkedList list = new LinkedList(); ArrayToken array = (ArrayToken) inputArray.get(0); while ((i < _outputLength) && (j < array.length())) { Token t = array.getElement(j); _updateParameter(t); if (_debugging) { _debug("** Executing filter model."); } try { _manager.execute(); } catch (KernelException ex) { throw new IllegalActionException(this, ex, "Execution failed."); } if (_getResult()) { i++; list.add(t); } j++; } Token[] result = new Token[list.size()]; for (i = 0; i < list.size(); i++) { result[i] = (Token) list.get(i); } outputArray.send(0, new ArrayToken(array.getElementType(), result)); } }
/** * Parse the xml file and run it. If a parameter named "copernicus_iterations" is present, then * the value of that parameter is used to set the iterations parameter. If there is no * "copernicus_iterations" parameter, then then the number of iterations is set to 100000. */ public TestApplication(String xmlFilename) throws Exception { MoMLParser parser = new MoMLParser(); // The test suite calls MoMLSimpleApplication multiple times, // and the list of filters is static, so we reset it each time // so as to avoid adding filters every time we run an auto test. // We set the list of MoMLFilters to handle Backward Compatibility. MoMLParser.setMoMLFilters(BackwardCompatibility.allFilters()); // Filter out any graphical classes. // We should filter out graphical classes or the // treeShakeWithoutCodegen rule will fail when we run it on // actor/lib/test/auto/ComplexDivide. MoMLParser.addMoMLFilter(new RemoveGraphicalClasses()); // parser.setErrorHandler(new StreamErrorHandler()); // We use parse(URL, URL) here instead of parseFile(String) // because parseFile() works best on relative pathnames and // has problems finding resources like files specified in // parameters if the xml file was specified as an absolute path. CompositeActor toplevel = null; // First, we gc and then print the memory stats // BTW to get more info about gc, // use java -verbose:gc -Xloggc:filename . . . System.gc(); Thread.sleep(1000); Runtime runtime = Runtime.getRuntime(); try { URL url = new URL(null, xmlFilename); toplevel = (CompositeActor) parser.parse(url, url.openStream()); } catch (Exception ex) { File f = new File(xmlFilename); URL url = f.toURL(); System.err.println("Warning: Parsing '" + xmlFilename + "' failed: "); ex.printStackTrace(); System.err.println(" Trying '" + url + "'"); toplevel = (CompositeActor) parser.parse(null, url); } // FIXME: nearly duplicate code in kernel/KernelMain.java SDFDirector director = (SDFDirector) toplevel.getDirector(); if (director != null) { Parameter iterations = (Parameter) director.getAttribute("iterations"); Parameter copernicus_iterations = (Parameter) director.getAttribute("copernicus_iterations"); // Set to be a large number of iterations, unless // copernicus_iterations is set. if (copernicus_iterations != null) { iterations.setToken(copernicus_iterations.getToken()); } else { iterations.setToken(new IntToken(100000)); } System.out.println("TestApplication: Setting Iterations to " + iterations.getToken()); } Manager manager = new Manager(toplevel.workspace(), "TestApplication"); toplevel.setManager(manager); toplevel.addChangeListener(this); String modelName = toplevel.getName(); long startTime = System.currentTimeMillis(); long totalMemory1 = runtime.totalMemory() / 1024; long freeMemory1 = runtime.freeMemory() / 1024; System.out.println("Spent " + (startTime - _parseStartTime) + " ms. creating the model."); System.out.println( modelName + ": Stats before execution: " + Manager.timeAndMemory(startTime, totalMemory1, freeMemory1)); // Second, we run and print memory stats. manager.execute(); long totalMemory2 = runtime.totalMemory() / 1024; long freeMemory2 = runtime.freeMemory() / 1024; String standardStats = Manager.timeAndMemory(startTime, totalMemory2, freeMemory2); System.out.println(modelName + ": Execution stats: " + standardStats); // Third, we gc and print memory stats. System.gc(); Thread.sleep(1000); long totalMemory3 = runtime.totalMemory() / 1024; long freeMemory3 = runtime.freeMemory() / 1024; System.out.println( modelName + ": After Garbage Collection: " + Manager.timeAndMemory(startTime, totalMemory3, freeMemory3)); // Print out the standard stats at the end // so as not to break too many scripts System.out.println(standardStats); }