Hi Kasia,
Looking at ptolemy/domains/pn/kernel/PNDirector.java, I believe that the algorithm works on a per-receiver basis, so it should block only when there is no data on all the channels of a multiport. Edward might have some input here, but that is my understanding.

See also the PN chapter in
"Heterogeneous Concurrent Modeling and Design in Java (Volume 3: Ptolemy II Domains)" at
http://www.eecs.berkeley.edu/Pubs/TechRpts/2008/EECS-2008-37.html

There are some tests that involve multiports with width greater than 1 in
ptolemy/domains/pn/test/auto/WidthInferenceTest*.xml

I've attached a model that has a Const and a Ramp going to a Commutator.
The Const has its firingCountLimit set to 1.
The Ramp has its firingCountLimit set to 50 because if firingCountLimit is set to NONE,
then the PN Director will throw

ptolemy.kernel.util.IllegalActionException: Queue size 131072 exceeds the maximum capacity in port .PNMultiport.Commutator.input. Perhaps you have an unbounded queue?
  in .PNMultiport.PN Director
at ptolemy.domains.pn.kernel.PNDirector._incrementLowestWriteCapacityPort(PNDirector.java:482) at ptolemy.domains.pn.kernel.PNDirector._resolveInternalDeadlock(PNDirector.java:549) at ptolemy.actor.process.CompositeProcessDirector._resolveDeadlock(CompositeProcessDirector.java:719)
    at ptolemy.actor.process.ProcessDirector.fire(ProcessDirector.java:259)
    at ptolemy.actor.CompositeActor.fire(CompositeActor.java:458)
    at ptolemy.actor.Manager.iterate(Manager.java:742)
    at ptolemy.actor.Manager.execute(Manager.java:351)
    at ptolemy.actor.Manager.run(Manager.java:1111)
    at ptolemy.actor.Manager$PtolemyRunThread.run(Manager.java:1641)

I modified the development version of PNDirector to indicate which port is causing the problem and it looks like what happens when firingCountLimit is NONE is that the Ramp produces data and the Commutator fails to read from the Ramp because there is no token on the
channel connected to the Const port.

Commutator's fire() method indicates what happens when data is not available:
/** Read <i>blockSize</i> tokens from each input channel and send them
     *  to the output port. If an input channel does not have enough
     *  tokens, suspend firing
     *  and return. In this case, the actor makes a record of the
     *  input channel that it last attempted to read so that it can
     *  start reading at that channel in the next iteration.  The
     *  order in which the tokens are produced is the order of the
     *  channels in the input port.
     *
     *  @exception IllegalActionException If there is no director.
     */
    public void fire() throws IllegalActionException {
        super.fire();
        _tentativeInputPosition = _currentInputPosition;

        int width = input.getWidth();
        int blockSizeValue = ((IntToken) blockSize.getToken()).intValue();

        for (int i = 0; i < width; i++) {
            if (!input.hasToken(_tentativeInputPosition, blockSizeValue)) {
                break;
            }
            Token[] inputs = input.get(_tentativeInputPosition++,
                    blockSizeValue);
            output.send(0, inputs, blockSizeValue);

            if (_tentativeInputPosition >= width) {
        _tentativeInputPosition = 0;
            }
        }
    }


A better answer to your question might be: The Ptolemy II PNDirector works on a per-channel basis, so a multiport blocks on a per-channel basis, but it depends on how the actor is written. Most actors expect data on each channel and read sequentially. Some actors, such as NondeterministicMerge read from channels that have data and skip channels
that do not have data.

See PNMultiportNondeterministicMerge.xml for a model that has the Const with
a firingCountLimit of 1  and the Ramp with a firingCountLimit of 50.




Note that PN cannot handle a relation with multiple sources connected to the relation.
PNDirector says:

/** Override the base class to reset the capacities of all the receivers.
     *  @exception IllegalActionException If the superclass throws it.
     */
    public void preinitialize() throws IllegalActionException {
        super.preinitialize();

// Check that no relation has multiple sources of data connected to it. // FIXME: This only detects the error at this level of the hierarchy.
        // Probably need to recursively descend into composite actors.
        CompositeEntity container = (CompositeEntity) getContainer();
        Iterator relations = container.relationList().iterator();

        while (relations.hasNext()) {
            IORelation relation = (IORelation) relations.next();

            if (relation.linkedSourcePortList().size() > 1) {
                throw new IllegalActionException(relation,
            "Relation has multiple sources of data,"
                                + " which is not allowed in PN."
                                + " If you want nondeterministic merge,"
                                + " use the NondeterministicMerge actor.");
            }
        }
...


_Christopher

On 9/15/11 7:50 AM, Katarzyna Bylec wrote:
Hello,

I'm working on some problem from PN domain and while designing the solution I'd like to make it clear what's the blocking algorithm concerning multiports.

I more detail - I have a multiport input. Does the containing actor write blocks when there's no data on the channel it tries to read from or can it move to another channel in this port and blocks only when there's no data in all channels?

Regards,
Kasia

--
Christopher Brooks, PMP                       University of California
CHESS Executive Director                      US Mail: 337 Cory Hall
Programmer/Analyst CHESS/Ptolemy/Trust        Berkeley, CA 94720-1774
ph: 510.643.9841                                (Office: 545Q Cory)
home: (F-Tu) 707.665.0131 cell: 707.332.0670

<?xml version="1.0" standalone="no"?>
<!DOCTYPE entity PUBLIC "-//UC Berkeley//DTD MoML 1//EN"
    "http://ptolemy.eecs.berkeley.edu/xml/dtd/MoML_1.dtd";>
<entity name="PNMultiport" class="ptolemy.actor.TypedCompositeActor">
    <property name="_createdBy" class="ptolemy.kernel.attributes.VersionAttribute" value="8.1.devel">
    </property>
    <property name="PN Director" class="ptolemy.domains.pn.kernel.PNDirector">
        <property name="_location" class="ptolemy.kernel.util.Location" value="[80.0, 65.0]">
        </property>
    </property>
    <property name="_windowProperties" class="ptolemy.actor.gui.WindowPropertiesAttribute" value="{bounds={0, 30, 1438, 519}, maximized=false}">
    </property>
    <property name="_vergilSize" class="ptolemy.actor.gui.SizeAttribute" value="[1225, 409]">
    </property>
    <property name="_vergilZoomFactor" class="ptolemy.data.expr.ExpertParameter" value="1.0">
    </property>
    <property name="_vergilCenter" class="ptolemy.data.expr.ExpertParameter" value="{612.5, 204.5}">
    </property>
    <property name="Annotation" class="ptolemy.vergil.kernel.attributes.TextAttribute">
        <property name="text" class="ptolemy.kernel.util.StringAttribute" value="The Ramp Actor has its firingCountLimit set to 50 &#10;so as to avoid an exception in PNDirector.">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[20.0, 255.0]">
        </property>
    </property>
    <entity name="Const" class="ptolemy.actor.lib.Const">
        <property name="firingCountLimit" class="ptolemy.data.expr.Parameter" value="1">
        </property>
        <property name="value" class="ptolemy.data.expr.Parameter" value="{&quot;a1&quot;, &quot;a2&quot;, &quot;a3&quot;, &quot;a4&quot;}">
        </property>
        <doc>Create a constant sequence.</doc>
        <property name="_icon" class="ptolemy.vergil.icon.BoxedValueIcon">
            <property name="attributeName" class="ptolemy.kernel.util.StringAttribute" value="value">
            </property>
            <property name="displayWidth" class="ptolemy.data.expr.Parameter" value="60">
            </property>
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[125.0, 120.0]">
        </property>
    </entity>
    <entity name="ArrayToSequence" class="ptolemy.domains.sdf.lib.ArrayToSequence">
        <property name="enforceArrayLength" class="ptolemy.data.expr.Parameter" value="false">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[260.0625, 120.0]">
        </property>
    </entity>
    <entity name="SequenceToArray" class="ptolemy.domains.sdf.lib.SequenceToArray">
        <property name="arrayLength" class="ptolemy.actor.parameters.PortParameter" value="4">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="{625.0, 115.0}">
        </property>
    </entity>
    <entity name="Commutator" class="ptolemy.actor.lib.Commutator">
        <property name="_location" class="ptolemy.kernel.util.Location" value="[440.0, 190.0]">
        </property>
    </entity>
    <entity name="Distributor" class="ptolemy.actor.lib.Distributor">
        <property name="blockSize" class="ptolemy.data.expr.Parameter" value="4">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[525.0, 190.0]">
        </property>
    </entity>
    <entity name="ArrayToSequence2" class="ptolemy.domains.sdf.lib.ArrayToSequence">
        <property name="enforceArrayLength" class="ptolemy.data.expr.Parameter" value="false">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[260.0, 180.0]">
        </property>
    </entity>
    <entity name="SequenceToArray2" class="ptolemy.domains.sdf.lib.SequenceToArray">
        <property name="arrayLength" class="ptolemy.actor.parameters.PortParameter" value="4">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[635.0, 175.0]">
        </property>
    </entity>
    <entity name="Ramp" class="ptolemy.actor.lib.Ramp">
        <property name="firingCountLimit" class="ptolemy.data.expr.Parameter" value="NONE">
        </property>
        <property name="init" class="ptolemy.data.expr.Parameter" value="{1,2,3,4}">
        </property>
        <property name="step" class="ptolemy.actor.parameters.PortParameter" value="{1,10,100,1000}">
        </property>
        <doc>Create a sequence of tokens with increasing value</doc>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[85.0, 185.0]">
        </property>
    </entity>
    <entity name="Display" class="ptolemy.actor.lib.gui.Display">
        <property name="_windowProperties" class="ptolemy.actor.gui.WindowPropertiesAttribute" value="{bounds={598, 421, 484, 208}, maximized=false}">
        </property>
        <property name="_paneSize" class="ptolemy.actor.gui.SizeAttribute">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[800.0, 100.0]">
        </property>
    </entity>
    <entity name="Display2" class="ptolemy.actor.lib.gui.Display">
        <property name="_windowProperties" class="ptolemy.actor.gui.WindowPropertiesAttribute" value="{bounds={1116, 214, 484, 208}, maximized=false}">
        </property>
        <property name="_paneSize" class="ptolemy.actor.gui.SizeAttribute">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[803.75, 171.796875]">
        </property>
    </entity>
    <relation name="relation" class="ptolemy.actor.TypedIORelation">
        <property name="width" class="ptolemy.data.expr.Parameter" value="-1">
        </property>
    </relation>
    <relation name="relation2" class="ptolemy.actor.TypedIORelation">
        <property name="width" class="ptolemy.data.expr.Parameter" value="-1">
        </property>
    </relation>
    <relation name="relation7" class="ptolemy.actor.TypedIORelation">
        <property name="width" class="ptolemy.data.expr.Parameter" value="-1">
        </property>
    </relation>
    <relation name="relation8" class="ptolemy.actor.TypedIORelation">
        <property name="width" class="ptolemy.data.expr.Parameter" value="-1">
        </property>
    </relation>
    <relation name="relation11" class="ptolemy.actor.TypedIORelation">
        <property name="width" class="ptolemy.data.expr.Parameter" value="-1">
        </property>
    </relation>
    <relation name="relation12" class="ptolemy.actor.TypedIORelation">
        <property name="width" class="ptolemy.data.expr.Parameter" value="-1">
        </property>
    </relation>
    <relation name="relation4" class="ptolemy.actor.TypedIORelation">
    </relation>
    <relation name="relation3" class="ptolemy.actor.TypedIORelation">
    </relation>
    <relation name="relation5" class="ptolemy.actor.TypedIORelation">
    </relation>
    <link port="Const.output" relation="relation"/>
    <link port="ArrayToSequence.input" relation="relation"/>
    <link port="ArrayToSequence.output" relation="relation7"/>
    <link port="SequenceToArray.input" relation="relation11"/>
    <link port="SequenceToArray.output" relation="relation3"/>
    <link port="Commutator.input" relation="relation7"/>
    <link port="Commutator.input" relation="relation8"/>
    <link port="Commutator.output" relation="relation2"/>
    <link port="Distributor.input" relation="relation2"/>
    <link port="Distributor.output" relation="relation11"/>
    <link port="Distributor.output" relation="relation12"/>
    <link port="ArrayToSequence2.input" relation="relation4"/>
    <link port="ArrayToSequence2.output" relation="relation8"/>
    <link port="SequenceToArray2.input" relation="relation12"/>
    <link port="SequenceToArray2.output" relation="relation5"/>
    <link port="Ramp.output" relation="relation4"/>
    <link port="Display.input" relation="relation3"/>
    <link port="Display2.input" relation="relation5"/>
</entity>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE entity PUBLIC "-//UC Berkeley//DTD MoML 1//EN"
    "http://ptolemy.eecs.berkeley.edu/xml/dtd/MoML_1.dtd";>
<entity name="PNMultiportNondeterministicMerge" class="ptolemy.actor.TypedCompositeActor">
    <property name="_createdBy" class="ptolemy.kernel.attributes.VersionAttribute" value="8.1.devel">
    </property>
    <property name="PN Director" class="ptolemy.domains.pn.kernel.PNDirector">
        <property name="_location" class="ptolemy.kernel.util.Location" value="[80.0, 65.0]">
        </property>
    </property>
    <property name="_windowProperties" class="ptolemy.actor.gui.WindowPropertiesAttribute" value="{bounds={0, 30, 1438, 519}, maximized=false}">
    </property>
    <property name="_vergilSize" class="ptolemy.actor.gui.SizeAttribute" value="[1225, 409]">
    </property>
    <property name="_vergilZoomFactor" class="ptolemy.data.expr.ExpertParameter" value="1.0">
    </property>
    <property name="_vergilCenter" class="ptolemy.data.expr.ExpertParameter" value="{612.5, 204.5}">
    </property>
    <property name="Annotation" class="ptolemy.vergil.kernel.attributes.TextAttribute">
        <property name="text" class="ptolemy.kernel.util.StringAttribute" value="The Ramp Actor has its firingCountLimit set to 50 &#10;so as to avoid an exception in PNDirector.">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[20.0, 255.0]">
        </property>
    </property>
    <entity name="Const" class="ptolemy.actor.lib.Const">
        <property name="firingCountLimit" class="ptolemy.data.expr.Parameter" value="1">
        </property>
        <property name="value" class="ptolemy.data.expr.Parameter" value="{&quot;a1&quot;, &quot;a2&quot;, &quot;a3&quot;, &quot;a4&quot;}">
        </property>
        <doc>Create a constant sequence.</doc>
        <property name="_icon" class="ptolemy.vergil.icon.BoxedValueIcon">
            <property name="attributeName" class="ptolemy.kernel.util.StringAttribute" value="value">
            </property>
            <property name="displayWidth" class="ptolemy.data.expr.Parameter" value="60">
            </property>
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[125.0, 120.0]">
        </property>
    </entity>
    <entity name="ArrayToSequence" class="ptolemy.domains.sdf.lib.ArrayToSequence">
        <property name="enforceArrayLength" class="ptolemy.data.expr.Parameter" value="false">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[260.0625, 120.0]">
        </property>
    </entity>
    <entity name="ArrayToSequence2" class="ptolemy.domains.sdf.lib.ArrayToSequence">
        <property name="enforceArrayLength" class="ptolemy.data.expr.Parameter" value="false">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[260.0, 180.0]">
        </property>
    </entity>
    <entity name="Display" class="ptolemy.actor.lib.gui.Display">
        <property name="_windowProperties" class="ptolemy.actor.gui.WindowPropertiesAttribute" value="{bounds={598, 421, 484, 208}, maximized=false}">
        </property>
        <property name="_paneSize" class="ptolemy.actor.gui.SizeAttribute" value="[484, 164]">
        </property>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[725.0, 145.0]">
        </property>
    </entity>
    <entity name="Ramp" class="ptolemy.actor.lib.Ramp">
        <property name="firingCountLimit" class="ptolemy.data.expr.Parameter" value="20">
        </property>
        <property name="init" class="ptolemy.data.expr.Parameter" value="{1,2,3,4}">
        </property>
        <property name="step" class="ptolemy.actor.parameters.PortParameter" value="{1,10,100,1000}">
        </property>
        <doc>Create a sequence of tokens with increasing value</doc>
        <property name="_location" class="ptolemy.kernel.util.Location" value="[85.0, 185.0]">
        </property>
    </entity>
    <entity name="NondeterministicMerge" class="ptolemy.domains.pn.kernel.NondeterministicMerge">
        <property name="_location" class="ptolemy.kernel.util.Location" value="[490.0, 150.0]">
        </property>
    </entity>
    <relation name="relation" class="ptolemy.actor.TypedIORelation">
        <property name="width" class="ptolemy.data.expr.Parameter" value="-1">
        </property>
    </relation>
    <relation name="relation4" class="ptolemy.actor.TypedIORelation">
    </relation>
    <relation name="relation6" class="ptolemy.actor.TypedIORelation">
    </relation>
    <relation name="relation7" class="ptolemy.actor.TypedIORelation">
    </relation>
    <relation name="relation2" class="ptolemy.actor.TypedIORelation">
    </relation>
    <link port="Const.output" relation="relation"/>
    <link port="ArrayToSequence.input" relation="relation"/>
    <link port="ArrayToSequence.output" relation="relation6"/>
    <link port="ArrayToSequence2.input" relation="relation4"/>
    <link port="ArrayToSequence2.output" relation="relation7"/>
    <link port="Display.input" relation="relation2"/>
    <link port="Ramp.output" relation="relation4"/>
    <link port="NondeterministicMerge.input" relation="relation6"/>
    <link port="NondeterministicMerge.input" relation="relation7"/>
    <link port="NondeterministicMerge.output" relation="relation2"/>
</entity>
_______________________________________________
Kepler-users mailing list
Kepler-users@kepler-project.org
http://lists.nceas.ucsb.edu/kepler/mailman/listinfo/kepler-users

Reply via email to