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