private void _inferFiringCounts(SymbolicScheduleElement element, String expression) throws IllegalActionException, NameDuplicationException { String recursiveExpression; if (expression == null) { recursiveExpression = element.expression(); } else { recursiveExpression = expression + "*" + element.expression(); } if (element instanceof SymbolicFiring) { SymbolicFiring firing = (SymbolicFiring) element; Entity actor = (Entity) firing.getActor(); Variable parameter = (Variable) actor.getAttribute("firingsPerIteration"); if (parameter == null) { parameter = new Parameter(actor, "firingsPerIteration"); parameter.setVisibility(Settable.NOT_EDITABLE); parameter.setPersistent(false); } parameter.setExpression(recursiveExpression); } else if (element instanceof SymbolicSchedule) { SymbolicSchedule schedule = (SymbolicSchedule) element; for (Iterator i = schedule.iterator(); i.hasNext(); ) { _inferFiringCounts((SymbolicScheduleElement) i.next(), recursiveExpression); } } else { throw new RuntimeException("Unexpected Schedule Element"); } }
/** * Look up and return the type term for the specified name in the scope. Return null if the name * is not defined in this scope, or is a constant type. * * @return The InequalityTerm associated with the given name in the scope. * @exception IllegalActionException If a value in the scope exists with the given name, but * cannot be evaluated. */ public ptolemy.graph.InequalityTerm getTypeTerm(String name) throws IllegalActionException { PSDFDirector director = (PSDFDirector) getContainer(); CompositeActor reference = (CompositeActor) director.getContainer(); Variable result = getScopedVariable(null, reference, name); if (result != null) { return result.getTypeTerm(); } else { return null; } }
/** * Look up and return the attribute with the specified name in the scope. Return null if such an * attribute does not exist. * * @return The attribute with the specified name in the scope. * @exception IllegalActionException If a value in the scope exists with the given name, but * cannot be evaluated. */ public ptolemy.data.Token get(String name) throws IllegalActionException { PSDFDirector director = (PSDFDirector) getContainer(); CompositeActor reference = (CompositeActor) director.getContainer(); Variable result = getScopedVariable(null, reference, name); if (result != null) { return result.getToken(); } else { return null; } }
/** * Override the base class to set type constraints between the output ports and parameters of this * actor whose name matches the output port. If there is no such parameter, then create an * instance of Variable with a matching name and set up the type constraints to that instance. The * type of the output port is constrained to be at least that of the parameter or variable. * * @exception IllegalActionException If there is no director, or if the director's preinitialize() * method throws it, or if this actor is not opaque. */ public void preinitialize() throws IllegalActionException { super.preinitialize(); Iterator ports = outputPortList().iterator(); while (ports.hasNext()) { TypedIOPort port = (TypedIOPort) ports.next(); // Ensure that the production rate is one. // FIXME: This may not be right if there is no // actual source of data for this port (e.g. no // SetVariable actor). Variable rate = (Variable) port.getAttribute("tokenProductionRate"); if (rate == null) { try { rate = new Variable(port, "tokenProductionRate"); } catch (NameDuplicationException e) { throw new InternalErrorException(e); } } rate.setToken(new IntToken(1)); String portName = port.getName(); Attribute attribute = getAttribute(portName); if (attribute == null) { try { workspace().getWriteAccess(); attribute = new Variable(this, portName); } catch (NameDuplicationException ex) { throw new InternalErrorException(ex); } finally { workspace().doneWriting(); } } // attribute is now assured to be non-null. if (attribute instanceof Variable) { port.setTypeAtLeast((Variable) attribute); } else { // Assume the port type must be a string. port.setTypeEquals(BaseType.STRING); } } }
/** * If there is no variable with the specified name, then create one. This is done in * preinitialize() so that we can set up a type constraint that ensures that the type of the * variable is at least that of the input port. * * @exception IllegalActionException If the superclass throws it, or if there is no container. */ public void preinitialize() throws IllegalActionException { super.preinitialize(); Attribute attribute = getModifiedVariable(); if (attribute instanceof Variable) { ((Variable) attribute).setTypeAtLeast(input); } }
// ///////////////////////////////////////////////////////////////// // // private methods //// private void _setValue(Token value) throws IllegalActionException { Attribute variable = getModifiedVariable(); if (variable instanceof Variable) { ((Variable) variable).setToken(value); // NOTE: If we don't call validate(), then the // change will not propagate to dependents. ((Variable) variable).validate(); } else if (variable instanceof Settable) { ((Settable) variable).setExpression(value.toString()); // NOTE: If we don't call validate(), then the // change will not propagate to dependents. ((Settable) variable).validate(); } else { throw new IllegalActionException( SetVariable.this, "Cannot set the value of the variable " + "named: " + variableName.getExpression()); } }
/** * Create a new icon with the given name in the given container. The container is required to * implement Settable, or an exception will be thrown. * * @param container The container for this attribute. * @param name The name of this attribute. * @exception IllegalActionException If thrown by the parent class or while setting an attribute * @exception NameDuplicationException If the name coincides with an attribute already in the * container. */ public TableIcon(NamedObj container, String name) throws NameDuplicationException, IllegalActionException { super(container, name); variableName = new StringParameter(this, "variableName"); boxColor = new ColorAttribute(this, "boxColor"); boxColor.setExpression("{1.0, 1.0, 1.0, 1.0}"); Variable UNBOUNDED = new Variable(this, "UNBOUNDED"); UNBOUNDED.setVisibility(Settable.NONE); UNBOUNDED.setExpression("0"); maxRows = new Parameter(this, "maxRows"); maxRows.setTypeEquals(BaseType.INT); maxRows.setExpression("UNBOUNDED"); Variable ALL = new Variable(this, "ALL"); ALL.setVisibility(Settable.NONE); Token emptyStringArray = new ArrayToken(BaseType.STRING); ALL.setToken(emptyStringArray); fields = new Parameter(this, "fields"); fields.setTypeEquals(new ArrayType(BaseType.STRING)); fields.setExpression("ALL"); colorKey = new StringParameter(this, "colorKey"); }
/** * 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(); }
// ///////////////////////////////////////////////////////////////// // // private methods //// // Recursively compute the set of free variables for all actors // deeply contained in the given model. private Set _freeVariables(Entity model) throws IllegalActionException { // First get the free variables of contained actors. Set set = new HashSet(); if (model instanceof CompositeEntity) { for (Iterator entities = ((CompositeEntity) model).entityList().iterator(); entities.hasNext(); ) { Entity entity = (Entity) entities.next(); set.addAll(_freeVariables(entity)); } } // Next, compute the set of variable names defined in this container. Set variableNames = new HashSet(); for (Iterator variables = model.attributeList(Variable.class).iterator(); variables.hasNext(); ) { Variable variable = (Variable) variables.next(); variableNames.add(variable.getName()); } variableNames = Collections.unmodifiableSet(variableNames); // Free variables of contained actors that are defined in this // container are not free variables of this container. set.removeAll(variableNames); // Iterate over all the variables of this container, and add in // any free variables they reference. PtParser parser = new PtParser(); ParseTreeFreeVariableCollector collector = new ParseTreeFreeVariableCollector(); for (Iterator variables = model.attributeList(Variable.class).iterator(); variables.hasNext(); ) { Variable variable = (Variable) variables.next(); String expression = variable.getExpression(); ASTPtRootNode root; if (variable.isStringMode()) { root = parser.generateStringParseTree(expression); } else { root = parser.generateParseTree(expression); } Set freeIdentifiers = new HashSet(collector.collectFreeVariables(root)); // Identifiers that reference other variables in the same container // are bound, not free. Set tempSet = new HashSet(variableNames); tempSet.remove(variable.getName()); freeIdentifiers.removeAll(tempSet); set.addAll(freeIdentifiers); } _entityToFreeVariableNameSet.put(model, set); return set; }
/** * Construct an event with the given name contained by the specified composite entity. The * container argument must not be null, or a NullPointerException will be thrown. This event will * use the workspace of the container for synchronization and version counts. If the name argument * is null, then the name is set to the empty string. Increment the version of the workspace. This * constructor write-synchronizes on the workspace. * * @param container The container. * @param name The name of the state. * @exception IllegalActionException If the state cannot be contained by the proposed container. * @exception NameDuplicationException If the name coincides with that of an entity already in the * container. */ public ListDirectory(CompositeEntity container, String name) throws IllegalActionException, NameDuplicationException { super(container, name); directory = new FileParameter(this, "directory"); directory.setExpression("."); Parameter allowFiles = new Parameter(directory, "allowFiles"); allowFiles.setTypeEquals(BaseType.BOOLEAN); allowFiles.setToken(BooleanToken.FALSE); Parameter allowDirectories = new Parameter(directory, "allowDirectories"); allowDirectories.setTypeEquals(BaseType.BOOLEAN); allowDirectories.setToken(BooleanToken.TRUE); filter = new StringParameter(this, "filter"); filter.setExpression("*.xml"); includeFiles = new Parameter(this, "includeFiles"); includeFiles.setTypeEquals(BaseType.BOOLEAN); includeFiles.setExpression("true"); includeDirectories = new Parameter(this, "includeDirectories"); includeDirectories.setTypeEquals(BaseType.BOOLEAN); includeDirectories.setExpression("false"); recursive = new Parameter(this, "recursive"); recursive.setTypeEquals(BaseType.BOOLEAN); recursive.setExpression("false"); files = new Parameter(this, "files"); files.setExpression("{ }"); files.setVisibility(Settable.NOT_EDITABLE); files.setPersistent(false); Variable variable = new Variable(files, "_textHeightHint"); variable.setExpression("5"); variable.setPersistent(false); }
/** * Set the parameter "inputArrayElement" of the model to an element of the input array. * * @param t The element value. * @exception IllegalActionException If the model does not have a settable attribute named * "inputArrayElement". */ private void _updateParameter(Token t) throws IllegalActionException { Attribute attribute = _model.getAttribute("inputArrayElement"); // Use the token directly rather than a string if possible. if (attribute instanceof Variable) { if (_debugging) { _debug("** Transferring input to parameter inputArrayElement."); } ((Variable) attribute).setToken(t); } else if (attribute instanceof Settable) { if (_debugging) { _debug("** Transferring input as string to inputArrayElement."); } ((Settable) attribute).setExpression(t.toString()); } else { throw new IllegalActionException( this, "The specified model does not have an inputArrayElement parameter."); } }
/** * 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; } }
/** * 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(); }