예제 #1
0
  /**
   * Perform the dispatching of the schedule in parallel to the distributed platform. For each level
   * of the Schedule, a commandMap is created and issued to the synchronizer. //TODO: This can be
   * made real static, precalculate and issue might yield slight better results? Is it worth the
   * effort?
   *
   * @see ptolemy.distributed.client.ThreadSynchronizer
   * @exception IllegalActionException If port methods throw it.
   */
  private void parallelFire() throws IllegalActionException {
    //        System.out.println("ParallelFire");
    Scheduler scheduler = getScheduler();

    if (scheduler == null) {
      throw new IllegalActionException("Attempted to fire " + "system with no scheduler");
    }

    // This will throw IllegalActionException if this director
    // does not have a container.
    Schedule schedule = scheduler.getSchedule();
    Iterator levels = schedule.iterator();

    while (levels.hasNext() && !_stopRequested) {
      Schedule level = (Schedule) levels.next();
      Iterator firings = level.firingIterator();

      HashMap commandsMap = new HashMap();

      while (firings.hasNext()) {
        Firing firing = (Firing) firings.next();
        Actor actor = firing.getActor();
        ClientThread clientThread = (ClientThread) actorsThreadsMap.get(actor);
        clientThread.setIterationCount(firing.getIterationCount());
        commandsMap.put(clientThread, Integer.valueOf(ClientThread.ITERATE));
      }

      synchronizer.setCommands(commandsMap);

      // Here is where the synchronization takes place.
      synchronizer.commandsProcessed();
    }
  }
예제 #2
0
  /**
   * Perform the dispatching of the schedule in a pipelined parallel manner on to the distributed
   * platform. For each level of the Schedule, a commandMap is created and issued to the
   * synchronizer.
   *
   * @exception IllegalActionException If there is no scheduler.
   * @see ptolemy.distributed.client.ThreadSynchronizer
   * @exception IllegalActionException If port methods throw it.
   */
  private void pipelinedParallelFire() throws IllegalActionException {
    int iterationsValue = ((IntToken) (iterations.getToken())).intValue();

    Scheduler scheduler = getScheduler();

    if (scheduler == null) {
      throw new IllegalActionException("Attempted to fire " + "system with no scheduler");
    }

    // This will throw IllegalActionException if this director
    // does not have a container.
    Schedule schedule = scheduler.getSchedule();

    //        System.out.println("Schedule size:" + schedule.size());
    int aux = iterationsValue - _iterationCount;

    if (aux < schedule.size()) {
      Iterator firings = schedule.get(schedule.size() - aux - 1).firingIterator();

      while (firings.hasNext()) {
        Firing firing = (Firing) firings.next();
        Actor actor = firing.getActor();

        //                System.out.println("removing: " + actor.getFullName());
        ClientThread clientThread = (ClientThread) actorsThreadsMap.get(actor);
        clientThread.setIterationCount(firing.getIterationCount());
        commandsMap.remove(clientThread);
      }
    }

    synchronizer.setCommands(commandsMap);

    // Here is where the synchronization takes place.
    synchronizer.commandsProcessed();
  }
예제 #3
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;
    }
  }
예제 #4
0
  /**
   * Fills the queues with data tokens so that a fully parallel execution can be performed. It
   * performs firings of the different levels of the schedule, adding one more level in every round.
   * For example for a parallel schedule consisting of three levels, first if fires the actors in
   * level 1, followed by actors in levels 1 and 2.
   *
   * @exception IllegalActionException If there is no scheduler.
   */
  private void bufferingPhase() throws IllegalActionException {
    System.out.println("Buffering...");

    int iterationsValue = ((IntToken) (iterations.getToken())).intValue();

    Scheduler scheduler = getScheduler();

    if (scheduler == null) {
      throw new IllegalActionException("Attempted to fire " + "system with no scheduler");
    }

    // This will throw IllegalActionException if this director
    // does not have a container.
    Schedule schedule = scheduler.getSchedule();
    Iterator levels = schedule.iterator();

    int levelNumber = 0;

    commandsMap = new HashMap();

    while (levels.hasNext() && !_stopRequested) {
      ScheduleElement level = (Schedule) levels.next();

      Iterator firings = level.firingIterator();

      while (firings.hasNext()) {
        Firing firing = (Firing) firings.next();
        Actor actor = firing.getActor();
        ClientThread clientThread = (ClientThread) actorsThreadsMap.get(actor);
        clientThread.setIterationCount(firing.getIterationCount());
        commandsMap.put(clientThread, Integer.valueOf(ClientThread.ITERATE));
      }

      int aux = levelNumber - iterationsValue;

      if (aux >= 0) {
        firings = schedule.get(aux).firingIterator();

        while (firings.hasNext()) {
          Firing firing = (Firing) firings.next();
          Actor actor = firing.getActor();

          System.out.println("removing: " + actor.getFullName());
          ClientThread clientThread = (ClientThread) actorsThreadsMap.get(actor);
          clientThread.setIterationCount(firing.getIterationCount());
          commandsMap.remove(clientThread);
        }
      }

      levelNumber = levelNumber + 1;

      if (levels.hasNext()) {
        synchronizer.setCommands(commandsMap);

        // Here is where the synchronization takes place.
        synchronizer.commandsProcessed();
      }
    }

    System.out.println("Finished Buffering...");
  }