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