Example #1
0
  /**
   * Return true if the receiver containing this boundary detector is connected to the inside of an
   * input boundary port; return false otherwise. A boundary port is an opaque port that is
   * contained by a composite actor. This method is not synchronized so the caller should be.
   *
   * @return True if the containing receiver is connected to the inside of a boundary port; return
   *     false otherwise.
   * @exception IllegalActionException
   * @exception InvalidStateException
   */
  public boolean isConnectedToBoundaryInside()
      throws InvalidStateException, IllegalActionException {
    if (_connectedInsideOfBoundaryCacheIsOn) {
      return _isConnectedInsideOfBoundaryValue;
    } else {
      IOPort contPort = _receiver.getContainer();

      if (contPort == null) {
        _connectedInsideOfBoundaryCacheIsOn = false;
        _isConnectedInsideOfBoundaryValue = false;
        return _isConnectedInsideOfBoundaryValue;
      }

      ComponentEntity contEntity = (ComponentEntity) contPort.getContainer();
      IOPort connectedPort = null;
      ComponentEntity connectedEntity = null;

      Iterator ports = contPort.connectedPortList().iterator();

      while (ports.hasNext()) {
        connectedPort = (IOPort) ports.next();
        connectedEntity = (ComponentEntity) connectedPort.getContainer();

        if ((connectedEntity == contEntity.getContainer())
            && connectedPort.isInput()
            && connectedPort.isOpaque()) {
          // The port container of this receiver is
          // connected to the inside of a boundary port.
          // Now determine if this receiver's channel is
          // connected to the boundary port.
          Receiver[][] receivers = connectedPort.deepGetReceivers();

          for (int i = 0; i < receivers.length; i++) {
            for (int j = 0; j < receivers[i].length; j++) {
              if (_receiver == receivers[i][j]) {
                _connectedInsideOfBoundaryCacheIsOn = true;
                _isConnectedInsideOfBoundaryValue = true;
                return true;
              }
            }
          }
        }
      }

      _connectedInsideOfBoundaryCacheIsOn = true;
      _isConnectedInsideOfBoundaryValue = false;
      return _isConnectedInsideOfBoundaryValue;
    }
  }
Example #2
0
 /**
  * Construct a trigger event with the specified destination IO port, timestamp, microstep, and
  * depth.
  *
  * @param ioPort The destination IO port.
  * @param timeStamp The time when the event occurs.
  * @param microstep The phase of execution within a fixed time.
  * @param depth The topological depth of the destination IO Port.
  */
 public DEEvent(IOPort ioPort, Time timeStamp, int microstep, int depth) {
   _actor = (Actor) ioPort.getContainer();
   _ioPort = ioPort;
   _timestamp = timeStamp;
   _microstep = microstep;
   _depth = depth;
 }
Example #3
0
 /** @return the model entities (should be actors) that can still send input msgs to this port */
 public synchronized Set<Entity> getActiveSources() {
   Set<Entity> results = new HashSet<Entity>();
   for (IOPort port : operationalSourcePorts) {
     results.add((Entity) port.getContainer());
   }
   return results;
 }
Example #4
0
  /**
   * Create a map containing the services and Receivers ID's corresponding to a given bidimensional
   * array of Receiver. i.e. ((service1, (ID1, ..., IDi), ..., (servicen, (IDj, ..., IDr)).
   *
   * @param receivers The bidimensional array of Receivers.
   * @return A HashMap containing services and lists of Receiver IDs.
   */
  private HashMap createServicesReceiversMap(Receiver[][] receivers) {
    HashMap servicesReceiversMap = new HashMap();

    for (int i = 0; i < receivers.length; i++) {
      for (int j = 0; j < receivers[i].length; j++) {
        if (receivers[i][j] != null) {
          IOPort port = receivers[i][j].getContainer();
          Actor actor = (Actor) port.getContainer();

          if (!servicesReceiversMap.containsKey(
              ((ClientThread) actorsThreadsMap.get(actor)).getService())) {
            servicesReceiversMap.put(
                ((ClientThread) actorsThreadsMap.get(actor)).getService(), new LinkedList());
          }

          LinkedList list =
              (LinkedList)
                  servicesReceiversMap.get(
                      ((ClientThread) actorsThreadsMap.get(actor)).getService());
          Integer ID = ((DistributedSDFReceiver) receivers[i][j]).getID();
          list.add(ID);
        }
      }
    }

    return servicesReceiversMap;
  }
Example #5
0
  /**
   * Set the container. This overrides the base class to record the director.
   *
   * @param port The container.
   * @exception IllegalActionException If the container is not of an appropriate subclass of IOPort,
   *     or if the container's director is not an instance of PNDirector.
   */
  public void setContainer(IOPort port) throws IllegalActionException {
    super.setContainer(port);
    if (port == null) {
      _director = null;
    } else {
      Actor actor = (Actor) port.getContainer();
      Director director;

      // For a composite actor,
      // the receiver type of an input port is decided by
      // the executive director.
      // While the receiver type of an output is decided by the director.
      // NOTE: getExecutiveDirector() and getDirector() yield the same
      // result for actors that do not contain directors.
      if (port.isInput()) {
        director = actor.getExecutiveDirector();
      } else {
        director = actor.getDirector();
      }

      if (!(director instanceof PNDirector)) {
        throw new IllegalActionException(
            port,
            "Cannot use an instance of PNQueueReceiver "
                + "since the director is not a PNDirector.");
      }

      _director = (PNDirector) director;
    }
  }
Example #6
0
  /**
   * Check for the given channel of the given port to see if variables are needed for recording read
   * offset and write offset. If the buffer size of a channel divides the readTokens and writeTokens
   * given in the argument, then there is no need for the variables. Otherwise the integer offsets
   * are replaced with variables and the code to initialize these variables are generated.
   *
   * @param port The port to be checked.
   * @param channelNumber The channel number.
   * @param readTokens The number of tokens read.
   * @param writeTokens The number of tokens written.
   * @return Code that declares the read and write offset variables.
   * @exception IllegalActionException If getting the rate or reading parameters throws it.
   */
  protected String _createOffsetVariablesIfNeeded(
      IOPort port, int channelNumber, int readTokens, int writeTokens)
      throws IllegalActionException {
    StringBuffer code = new StringBuffer();

    CodeGeneratorHelper helper = (CodeGeneratorHelper) _getHelper(port.getContainer());

    int bufferSize = helper.getBufferSize(port, channelNumber);
    if (bufferSize != 0 && (readTokens % bufferSize != 0 || writeTokens % bufferSize != 0)) {

      // Increase the buffer size of that channel to the power of two.
      int newBufferSize = _ceilToPowerOfTwo(bufferSize);
      helper.setBufferSize(port, channelNumber, newBufferSize);

      int width;
      if (port.isInput()) {
        width = port.getWidth();
      } else {
        width = port.getWidthInside();
      }

      // We check again if the new bufferSize divides readTokens or
      // writeTokens. If yes, we could avoid using variable to represent
      // offset.
      if (readTokens % newBufferSize != 0) {

        // Declare the read offset variable.
        StringBuffer channelReadOffset = new StringBuffer();
        channelReadOffset.append(CodeGeneratorHelper.generateName(port));
        if (width > 1) {
          channelReadOffset.append("_" + channelNumber);
        }
        channelReadOffset.append("_readoffset");
        String channelReadOffsetVariable = channelReadOffset.toString();
        // code.append("static int " + channelReadOffsetVariable + " = "
        // + helper.getReadOffset(port, channelNumber) + ";\n");
        code.append("static int " + channelReadOffsetVariable + ";\n");
        // Now replace the concrete offset with the variable.
        helper.setReadOffset(port, channelNumber, channelReadOffsetVariable);
      }

      if (writeTokens % newBufferSize != 0) {

        // Declare the write offset variable.
        StringBuffer channelWriteOffset = new StringBuffer();
        channelWriteOffset.append(CodeGeneratorHelper.generateName(port));
        if (width > 1) {
          channelWriteOffset.append("_" + channelNumber);
        }
        channelWriteOffset.append("_writeoffset");
        String channelWriteOffsetVariable = channelWriteOffset.toString();
        code.append("static int " + channelWriteOffsetVariable + ";\n");
        // Now replace the concrete offset with the variable.
        helper.setWriteOffset(port, channelNumber, channelWriteOffsetVariable);
      }
    }
    return code.toString();
  }
Example #7
0
 /**
  * Return the local ports whose names match the ports in the specified collection.
  *
  * @param ports A collection of ports.
  * @exception IllegalActionException If no matching port is found.
  */
 private Collection<IOPort> _localMirrors(Collection<IOPort> ports) throws IllegalActionException {
   Set<IOPort> result = new HashSet<IOPort>();
   for (IOPort port : ports) {
     IOPort localPort = (IOPort) ((Entity) _actor).getPort(port.getName());
     if (localPort == null) {
       throw new IllegalActionException(
           port.getContainer(), port, "Expected matching port in " + _actor.getFullName());
     }
     result.add(localPort);
   }
   return result;
 }
Example #8
0
  /**
   * Return the list of sending (up-stream) ports that are connected to the specified port. This
   * treats every port as an opaque port.
   *
   * @param port The specified port.
   * @return The list of sending ports.
   */
  protected static List<IOPort> _getSourcePortList(IOPort port) {
    List<IOPort> result = new ArrayList<IOPort>();

    for (IOPort connectedPort : (List<IOPort>) port.connectedPortList()) {
      boolean isInput = connectedPort.isInput();
      boolean isCompositeInput =
          connectedPort.getContainer() instanceof CompositeEntity
              && isInput
              && port.depthInHierarchy() > connectedPort.depthInHierarchy();

      if (!isInput || isCompositeInput) {
        result.add(connectedPort);
      }
    }
    return result;
  }
Example #9
0
  /**
   * Return the director that created this receiver. If this receiver is an inside receiver of an
   * output port of an opaque composite actor, then the director will be the local director of the
   * container of its port. Otherwise, it's the executive director of the container of its port.Note
   * that the director returned is guaranteed to be non-null. This method is read synchronized on
   * the workspace.
   *
   * @return An instance of DEDirector.
   * @exception IllegalActionException If there is no container port, or if the port has no
   *     container actor, or if the actor has no director, or if the director is not an instance of
   *     DEDirector.
   */
  private DEDirector _getDirector() throws IllegalActionException {
    IOPort port = getContainer();

    if (port != null) {
      if (_directorVersion == port.workspace().getVersion()) {
        return _director;
      }

      // Cache is invalid.  Reconstruct it.
      try {
        port.workspace().getReadAccess();

        Actor actor = (Actor) port.getContainer();

        if (actor != null) {
          Director dir;

          if (!port.isInput()
              && (actor instanceof CompositeActor)
              && ((CompositeActor) actor).isOpaque()) {
            dir = actor.getDirector();
          } else {
            dir = actor.getExecutiveDirector();
          }

          if (dir != null) {
            if (dir instanceof DEDirector) {
              _director = (DEDirector) dir;
              _directorVersion = port.workspace().getVersion();
              return _director;
            } else {
              throw new IllegalActionException(getContainer(), "Does not have a DEDirector.");
            }
          }
        }
      } finally {
        port.workspace().doneReading();
      }
    }

    throw new IllegalActionException(
        getContainer(), "Does not have a IOPort as the container of the receiver.");
  }
Example #10
0
  /**
   * Return true if the receiver containing this boundary detector is contained on the outside of a
   * boundary port. A boundary port is an opaque port that is contained by a composite actor. If the
   * containing receiver is contained on the outside of a boundary port then return true; otherwise
   * return false. This method is not synchronized so the caller should be.
   *
   * @return True if the containing receiver is contained on the outside of a boundary port; return
   *     false otherwise.
   */
  public boolean isOutsideBoundary() {
    if (_outsideBoundaryCacheIsOn) {
      return _isInsideBoundaryValue;
    } else {
      IOPort innerPort = _receiver.getContainer();

      if (innerPort == null) {
        _outsideBoundaryCacheIsOn = false;
        _isOutsideBoundaryValue = false;
        return _isOutsideBoundaryValue;
      }

      ComponentEntity innerEntity = (ComponentEntity) innerPort.getContainer();

      if ((innerEntity != null) && !innerEntity.isAtomic() && innerPort.isOpaque()) {
        // The containing receiver is contained by the port
        // of a composite actor.
        if (innerPort.isOutput() && !innerPort.isInput()) {
          _isOutsideBoundaryValue = false;
        } else if (!innerPort.isOutput() && innerPort.isInput()) {
          _isOutsideBoundaryValue = true;
        } else if (!innerPort.isOutput() && !innerPort.isInput()) {
          _isOutsideBoundaryValue = false;
        } else {
          // CONCERN: The following only works if the port
          // is not both an input and output.
          throw new IllegalArgumentException(
              "A port that "
                  + "is both an input and output can not be "
                  + "properly dealt with by "
                  + "PNQueueReceiver.isInsideBoundary");
        }

        _outsideBoundaryCacheIsOn = true;
        return _isOutsideBoundaryValue;
      }

      _outsideBoundaryCacheIsOn = true;
      _isOutsideBoundaryValue = false;
      return _isOutsideBoundaryValue;
    }
  }
Example #11
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;
    }
  }
Example #12
0
  /**
   * Return the dependency between the specified input port and the specified output port. This is
   * done by checking the guards and actions of all the transitions. When called for the first time
   * since a change in the model structure, this method performs the complete analysis of the FSM
   * and caches the result. Subsequent calls just look up the result.
   *
   * @param input The input port.
   * @param output The output port, or null to update the dependencies (and record equivalence
   *     classes) without requiring there to be an output port.
   * @return The dependency between the specified input port and the specified output port, or null
   *     if a null output is port specified.
   * @exception IllegalActionException If a guard expression cannot be parsed.
   */
  public Dependency getDependency(IOPort input, IOPort output) throws IllegalActionException {
    // If the dependency is not up-to-date, then update it.
    long workspaceVersion = ((NamedObj) _actor).workspace().getVersion();
    if (_dependencyVersion != workspaceVersion) {
      // Need to update dependencies. The cached version
      // is obsolete.
      try {
        ((NamedObj) _actor).workspace().getReadAccess();
        _reverseDependencies = new HashMap<IOPort, Map<IOPort, Dependency>>();
        _forwardDependencies = new HashMap<IOPort, Map<IOPort, Dependency>>();

        // Iterate over all the associated interfaces.
        for (CausalityInterface causality : _composedInterfaces) {
          List<IOPort> mirrorInputs = causality.getActor().inputPortList();
          for (IOPort mirrorInput : mirrorInputs) {
            Port localInput = ((Entity) _actor).getPort(mirrorInput.getName());
            if (!(localInput instanceof IOPort)) {
              throw new IllegalActionException(
                  _actor,
                  mirrorInput.getContainer(),
                  "No matching port with name " + mirrorInput.getName());
            }
            // The localInput may not be an input port...
            // It may have been an output port that the FSMActor controller
            // also has as an input port. But we don't want to set a forward
            // depedency in this case.
            if (!((IOPort) localInput).isInput()) {
              continue;
            }
            Map<IOPort, Dependency> forwardMap = _forwardDependencies.get(localInput);
            if (forwardMap == null) {
              forwardMap = new HashMap<IOPort, Dependency>();
              _forwardDependencies.put((IOPort) localInput, forwardMap);
            }
            for (IOPort dependentOutput : causality.dependentPorts(mirrorInput)) {
              Port localOutput = ((Entity) _actor).getPort(dependentOutput.getName());
              if (!(localOutput instanceof IOPort)) {
                throw new IllegalActionException(
                    _actor,
                    mirrorInput.getContainer(),
                    "No matching port with name " + mirrorInput.getName());
              }
              Dependency dependency = causality.getDependency(mirrorInput, dependentOutput);
              forwardMap.put((IOPort) localOutput, dependency);
              // Now handle the reverse dependencies.
              Map<IOPort, Dependency> backwardMap = _reverseDependencies.get(localOutput);
              if (backwardMap == null) {
                backwardMap = new HashMap<IOPort, Dependency>();
                _reverseDependencies.put((IOPort) localOutput, backwardMap);
              }
              backwardMap.put((IOPort) localInput, dependency);
            }
          }
        }
        // Next do equivalence classes.
        // We iterate over the input ports, and for each one,
        // find the ports for which it has equivalents in any
        // associated causality.
        _equivalenceClasses = new HashMap<IOPort, Collection<IOPort>>();
        Collection<IOPort> localInputs = _actor.inputPortList();
        for (IOPort localInput : localInputs) {
          Collection<IOPort> equivalences = _equivalenceClasses.get(localInput);
          if (equivalences != null) {
            // This input port is done.
            continue;
          }
          equivalences = new HashSet<IOPort>();
          // Iterate over all the associated interfaces.
          for (CausalityInterface causality : _composedInterfaces) {
            IOPort mirrorInput =
                (IOPort) ((Entity) causality.getActor()).getPort(localInput.getName());
            if (mirrorInput == null) {
              throw new IllegalActionException(
                  _actor,
                  localInput,
                  "Expected matching port in " + causality.getActor().getFullName());
            }
            equivalences.addAll(_localMirrors(causality.equivalentPorts(mirrorInput)));
          }
          // Set the equivalence class for all ports in the set.
          for (IOPort equivalentPort : equivalences) {
            _equivalenceClasses.put(equivalentPort, equivalences);
          }
        }
      } finally {
        ((NamedObj) _actor).workspace().doneReading();
      }
      _dependencyVersion = workspaceVersion;
    }
    if (output == null) {
      return null;
    }
    Map<IOPort, Dependency> inputMap = _forwardDependencies.get(input);
    if (inputMap != null) {
      Dependency result = inputMap.get(output);
      if (result != null) {
        return result;
      }
    }
    // If there is no recorded dependency, then reply
    // with the additive identity (which indicates no
    // dependency).
    return _defaultDependency.oPlusIdentity();
  }
Example #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();
  }
Example #14
0
 /**
  * Construct a UnitTerm from an IOPort. The constructed UnitExpr will have one UnitTerm and it
  * will be a variable with the name being that of the port.
  *
  * @param ioPort The IOPort.
  */
 public UnitExpr(IOPort ioPort) {
   UnitTerm uTerm = new UnitTerm();
   uTerm.setVariable(ioPort.getContainer().getName() + "." + ioPort.getName());
   _uTerms.add(uTerm);
 }
Example #15
0
 /**
  * Construct a trigger event with the specified destination IO port, timestamp, microstep, and
  * depth.
  *
  * @param ioPort The destination IO port.
  * @param timeStamp The time when the event occurs.
  * @param microstep The phase of execution within a fixed time.
  * @param depth The topological depth of the destination IO Port.
  * @exception IllegalActionException If the actor has a priority parameter, but its value cannot
  *     be obtained, which should be an integer.
  */
 public DEEvent(IOPort ioPort, Time timeStamp, int microstep, int depth)
     throws IllegalActionException {
   this(
       ioPort == null ? null : (Actor) ioPort.getContainer(), ioPort, timeStamp, microstep, depth);
 }