/** * 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; }
/** * 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(); }
// 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; }
/** * 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); }