예제 #1
0
  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");
    }
  }
예제 #2
0
    /**
     * 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;
      }
    }
예제 #3
0
    /**
     * 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;
      }
    }
예제 #4
0
  /**
   * 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);
      }
    }
  }
예제 #5
0
  /**
   * 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);
    }
  }
예제 #6
0
  // /////////////////////////////////////////////////////////////////
  // // 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());
    }
  }
예제 #7
0
  /**
   * 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");
  }
예제 #8
0
  /**
   * 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();
  }
예제 #9
0
  // /////////////////////////////////////////////////////////////////
  // // 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;
  }
예제 #10
0
  /**
   * 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);
  }
예제 #11
0
  /**
   * 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.");
    }
  }
예제 #12
0
  /**
   * 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;
    }
  }
예제 #13
0
  /**
   * 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();
  }