Pitcl interface to Ptolemy

Author: Edward A. Lee (eal@eecs.berkeley.edu)

The Tcl commands defined here implement an interface to the Ptolemy kernel that is significantly richer than the older ptcl interface. Normally, these commands should not be used directly. Use instead the class interface defined in the ::ptolemy namespace.

The commands are designed to expose most of functionality of the kernel at the Tcl level, although at this point the facilities are still incomplete. In certain cases, the commands are designed to try to hide blemishes in the design of the kernel, providing a more sensible interface. All commands are defined in the ::pitcl namespace, except the matlab and mathematica commands, which are defined in both the global namespace and the ::pitcl namespace.

Because interaction with Itcl is not as rich as it might be, this implementation preserves from its predecessor the notion of a current galaxy and current universe. This seems to be the simplest approach, and is hidden from the user by the classes in the ::ptolemy namespace. For commands that operate on a block, the block can usually be a star, galaxy, universe, wormhole, or target. Names of blocks can take any of the following forms:

  1. name
  2. name1.name2
  3. name1.name2...nameN
  4. .name
  5. .name1.name2
  6. .name1.name2...nameN
  7. this
  8. target

The first can specify a member of the current galaxy, a master star, a master galaxy, or a target (names conflicts are resolved in that order). The second can specify a star within a galaxy within the current galaxy, or a star or galaxy within a master galaxy. The third is just the obvious generalization of this. The fourth specifies a universe. The fifth specifies a block (star or galaxy) within a universe. The sixth is the obvious generalization. The seventh specifies the current galaxy, and the last specifies the current target.

Remaining to be done:

addBlock

Usage: addBlock name class

Create a new instance of star, galaxy, or wormhole. The specified block name may be absolute or relative to the current galaxy, unless it is a universe, in which case it must be absolute. I.e., it must begin with a leading period. The galaxy within which the block is to be created must exist or an error is triggered. An error is also triggered if the block already exists.

addState

Usage: addState statename type initvalue

Create a new state for a galaxy or universe. The specified state name may be absolute or relative to the current galaxy.

NOTE: Currently this is restricted to adding states to galaxies and universe. It should be generalized to add states to arbitrary blocks.

addUniverse

Usage: addUniverse name domain

Create a new, empty universe. The name can begin with a period (as in ".foo") or can omit the period (as in "foo"). In either case, the full name of the resulting universe has a leading period (".foo"). If a universe with the given name already exists, it is cleared. The second argument is the domain of the new universe.

aliasDown

Usage: aliasDown ?-deep? portname

Return the full name of the port that is aliased to the specified galaxy port. If there is none, return an empty string. If the -deep option is given, then return the bottom-level port, which is always a star port. Otherwise, just return the next level down.

aliasUp

Usage: aliasUp ?-deep? portname

If the -deep option is not given, return the full name of the galaxy port that is aliased to the specified port at the next level up in the hierarchy, or an empty string if there is none. If the -deep option is given, then return the top-level galaxy port, which may in fact be the same as the specified port if that port is already at the top level.

NOTE: If the specified port is a plain port within a multiport, the returned port may be a plain port within a multiport one level up in the hierarchy. This port name can be used to disconnect, but not to recreate the topology.

begin

Usage: begin blockname

Invoke the begin method of the specified block. The block must be a star, universe, or wormhole. This must be called after init.

NOTE: Ptolemy Universes don't actually have begin methods. This is an oversight. We query for the target and invoke its begin method here.

FIXME: Calling begin without init causes a core dump.

blocks

Usage: blocks ?-fullname? ?-deep? ?blockname?

Return a list of blocks contained by the specified block. If the -fullname option is given, the names in the returned list have the form _.universe.galaxy...galaxy.block_, giving the exact unique name of each block, with a leading period. If the -deep option is given, then recursively descend into galaxies, adding their blocks to the list, rather than listing the galaxy. Thus, all blocks returned will be stars. Note that probably makes no sense to use the -deep option without the -fullname option, since the names may not end up being unique.

If no blockname is given, then the current galaxy is used. If the argument is the name of a star (and hence contains no blocks), then return an empty string.

clear

Usage: clear ?univname?

Delete all blocks in the specified universe, or if none is specified, the current universe. The target is also reset to the default target.

connect

Usage: connect ?-bus buswidth? ?-note annotation? srcport dstport

Form a connection between two ports. The ports are given by dotted names that can be absolute (beginning with a period) or relative to the current galaxy. If abuswidthoption is given, then it specifies the number of parallel connections to make. If theannotationoption is given, the annotation is recorded on the connection. Such annotations are used, for example, in dataflow domains to specify the number and values of initial tokens that are put on an arc. For such domains, theannotationargument is a list giving the values of initial tokens that will be put on the arc.

connected

Usage: connected ?-deep? portname

Return a list of ports to which the given port is connected, or an empty list if it is not connected. The full name of each port is returned. If the given port is the alias of a galaxy port and the -deep option is not given, then the galaxy port name is reported as {aliasUp _portname_}. It is possible for a multiport to have both an upward alias and a connection, in which case, both are returned. If the -deep option is given, then star ports are always returned, never galaxy ports. That is, the star port to which the given port is ultimately connected to is returned. If the name of a multiport is given, this method returns a list of all the ports connected to the multiport.

NOTE: If the far side port is a multiport, then the specific port within that multiport to which we are connected is returned. This is probably not exactly the information originally used to create the connection, since the connect command accepts a multiport name, and creates ports within that multiport as needed. However, the information returned here is exactly what is needed to recreate the exact the topology, since if a multiport is given in a connect command, there is no control over which specific port is used for the connection.

cont

Usage: cont univname ?stoptime?

Continue an execution of a universe until the specified stop time. What this time means depends on the domain. In SDF, for example, it gives the number of iterations of a complete schedule. In DE, it gives the simulated time after which no more events will be processed. If no argument is given, then the stop time is taken to be unity. As a side effect, the current galaxy is set to the universe being run.

currentGalaxy

Usage: currentGalaxy ?name?

Return the full name of current galaxy or universe if no argument is given. If a name is given and a galaxy or universe exists with that name, make that the current galaxy. If there is no such galaxy, return an error.

defGalaxy

Usage: defGalaxy galname domain ?{galaxy-building-commands}?

Define a master galaxy. The first argument is the name of the galaxy, i.e. the name that is registered on the knownBlocks list for use by addBlock. The second argument is the domain of the galaxy. The galaxy can only be used in this domain, and the inside of the galaxy is also in this domain; to define a wormhole (a galaxy that is used in a domain different from its internals), use the defWormhole command. The third argument is a set of galaxy building commands. If it is not given, an empty galaxy is defined. Otherwise, the commands are executed in the ::pitcl namespace to construct the galaxy. Any pitcl commands can be included. Note that if errors occur during the execution of these galaxy defining commands, then a partially constructed galaxy will be on the knownBlocks list.

defWormhole

Usage: defWormhole wormname outerdomain innerdomain target ?{galaxy-building-commands}?");

Define a master wormhole. The first argument is the name of the wormhole, i.e. the name that is registered on the knownBlocks list for use by addBlock. The second argument is the external domain of the wormhole. This is the domain within which the wormhole can be used. The third argument is the internal domain of the wormhole. This can be the same as the outer domain, and a wormhole will still be created. The fourth argument is the name of the target. If this is an empty string, then the default target for the inner domain will be used. The final (optional) argument is a set of galaxy building commands. If it is not given, an empty wormhole is defined. Otherwise, the commands are executed in the ::pitcl namespace to construct the wormhole. Note that if errors occur during the execution of these wormhole defining commands, then a partially constructed wormhole will be on the knownBlocks list.

NOTE: In the predecessor interface, ptcl, defgalaxy was used for wormholes and galaxies. But that approach relied far too much on on the current state, and precluded incremental construction of wormholes.

galaxyPort

Usage: galaxyPort portname aliasport

This procedure establishes an "alias" relationship between a galaxy port and a port in a block within the galaxy. The first argument is the name of the galaxy port. If no port with that name exists, it is created. The second argument is the name of a block port within the galaxy.

NOTE: This procedure replaces the alias command in PTcl. Also note that this procedure could be greatly simplified by bypassing the InterpGalaxy::alias method. We use that method only because it registers the operation on the "actionList" for later cloning of the galaxy. If the cloning mechanism is simplified, then this implementation can probably be simplified.

getAnnotation

Usage: getAnnotation portname

Return the annotation created with the -note option for a given port. If no annotation was specified, return an empty string.

NOTE: If a multiport is passed in, this method returns an empty string, indicating no annotation. Is this what we want?

getClassName

Usage: getClassName ?blockname?

Return the class name of the specified block, or if none is specified, of the current galaxy. Note that the class name of a galaxy is the name of the master galaxy from which it was originally cloned, or if the galaxy is a master (on the KnownBlocks list), then its own name. The class name of a Ptolemy star has the domain name as a prefix, as in "SDFRamp".

getData

Usage: getData ?-geo? portname

Return the data buffered in the port, or if the -geo option is given, the data buffered on the geodesic. The data is returned as a list of items, where each item is a string constructed using the print method of the particle. If there is no data, an empty string is returned.

NOTE: Because of flaws in the design of the Ptolemy kernel, without the -geo option, only the current particle (that accessed with operator %0) is returned. Other particles in the port are ignored.

FIXME: This procedure has only been tested in the SDF domain. In particular, the -geo option is unlikely to yield anything useful in other domains.

getDescriptor

Usage: getDescriptor ?blockname?

Return the descriptor of the specified block, or if none is specified, of the current galaxy.

getDomain

Usage: getDomain ?-inside? ?blockname?

Return the domain of the specified block, or if none is specified, of the current galaxy. The domain returned by default is the one within which the block is designed to work. Thus, for a wormhole, it will not be the inside domain, but rather the outside domain. To get the inside domain of a wormhole, use the -inside option. This option is ignored if the block is not a wormhole.

getFullName

Usage: getFullName ?blockname?

Return the full name of the specified block, or if none is specified, of the current galaxy. The full name begins with a period, followed by the universe name, followed by parent galaxy names separated by periods, followed by the final block name.

getParent

Usage: getParent ?blockname?

Return the full name of the parent of the specified block, or if none is specified, of the current galaxy. If the specified block is an instance of a star or galaxy, then the full name begins with a period, followed by the universe name, followed by parent galaxy names separated by periods, followed by the final block name. If the specified block is a universe, then return ".". If the specified block is a master star or galaxy, then return the empty string. If the specified block does not exist, then return an error.

getSchedule

Usage: getSchedule ?blockname?

Return the schedule of the specified universe, or if none is specified, of the current universe. Note that it is necessary to invoke init before there is a schedule. If init has not been invoked, then return an error. The format of the returned schedule is as follows:

<schedule> ::= { ( <entry> )+ }

<entry> ::= { scheduler <string:scheduler_identifier> } | { galaxy <string:galaxy_or_universe_name> } | { target <string:target_name> } | { numberOfProcessors <int:numprocs> } | { numberOfStars <int:numstars> } | { numberOfStarOrClusterFirings <int:sizeofDAG> } | { makespan <int:makespan> } | { totalIdleTime <int:idletime> } | { utilization <float:utilization> } | { preamble <schedule> } | { cluster <schedule> } | { cluster <string:name> <schedule> } | { assign <string:token> <string:value> } | { fire <star> } | { fire <star> <f_info> } | { idle <int:idletime>} | { processor <string:name> <schedule> } | { repeat <int:repetitions> <schedule> } | { <string:annotation> <schedule> } | { <string:annotation> <schedule> <string:endannotation>}

<star> ::= send | receive | <string:star_name>

<f_info> ::= { ( <f_entry> )+ }

<f_entry> ::= { exec_time <int:exec_time> } | { start_row <int:start_row_index> } | { start_col <int:start_col_index> } | { end_row <int:end_row_index> } | { end_col <int:end_col_index> } | { <string:label> <string:value> }

The notation "( <name> ) +" means one or more items of type name. The notation "<type:description>" means an item of the given type and description. The braces ("{" and "}") are all part of the format, and are included to make the string trivial to parse in Tcl.

Note that all entries are optional, and the list will inevitably grow as we add more schedulers. Some are used only by specific schedulers. For instance, the "assign" item is used by BDF to record a value that affects the schedule. Thus a tool that uses any of this information to display a schedule cannot count on any item being present. It has to fail gracefully if it does not know how to display the schedule. The last two items of type "entry" can use any string as an identifier. This makes the format flexible, so that it can support new schedulers. I believe all schedule visualization tools should fall back on a textual schedule display if they cannot represent the given information, or necessary information is missing. So for example, one way to write the gantt tool would be to search the schedule for annotations that it does not recognize. If it finds any, display the schedule textually. Otherwise, draw a gantt chart.

The <f_entry> items allow the scheduler to give additional information about the schedule. Anything is allowed here, but the specific items listed are used by parallel CG schedulers and the MDSDF scheduler.

For example,

{
  { scheduler "T.C. Hu's Parallel Scheduler"}
  { galaxy foo}
  { numberOfProcessors 2}
  { processor 1 {
     { totalIdleTime 20 }
     { target NOW }
     { fire starA { exec_time 5 } }
     { fire starB { exec_time 5 } }
  }}
  { processor 2 {
     { fire starC { exec_time 25 } }
     { fire starD { exec_time 5 } }
  }}
  { totalIdleTime 20}
  { makespan 30}
  { utilization 66.66}
}
Here is a simpler example:
{
  {fire starA}
  {fire starB}
  {fire starC}
}

getTarget

Usage: getTarget ?-inside? ?blockname?

Given a block, return the name of its target. This procedure is most useful for blocks that are universes and wormholes when the -inside option is given. In this case, it returns the name of the target that controls the invocation of the blocks inside the universe or wormhole. Without the -inside option, it returns the name of the target that controls the invocation of the specified block (its outside target). However, this name will always be a null string before the universe has been initialized.

init

Usage: init ?blockname?

Initialize the specified block, or if none is specified, the current galaxy. This causes the states and portholes to be initialized and, for stars, universes, and wormholes, the setup method to be run. In addition, if the block is a universe or a wormhole, then the target is initialized. In statically scheduled domains, initializing the target causes the schedule to be computed. If a halt is requested or an error occurs during the initialization, then return an error (so that no script continues assuming the block has been initialized). Note that the begin method is not invoked. That should be explicitly invoked after this initialization.

initState

Usage: initState statename

Initialize a state. This causes the initial value to be evaluated and the current value set to the initial value.

isGalaxy

Usage: isGalaxy blockname

Return 1 if the specified block is a galaxy. Return 0 otherwise. A wormhole is not galaxy for these purposes, since normally you cannot see inside.

isMultiPort

Usage: isMultiPort portname

Return 1 if the specified port is a multiport. Return 0 otherwise. A multiport in Ptolemy is a port that contains any number of other ports.

isWormhole

Usage: isWormhole blockname

Return 1 if the specified block is a Wormhole. Return 0 otherwise. A Wormhole in Ptolemy is a star that contains a galaxy.

knownBlocks

Usage: knownBlocks ?domain?

Return a list of the available blocks in the specified domain, or (if no domain is given) the current domain.

knownDomains

Usage: knownDomains

Return a list of the available domains.

knownTargets

Usage: knownTargets ?domain?

Return a list of targets for the specified domain. (if no domain is given) the current domain.

knownUniverses

Usage: knownUniverses

Return a list of the names of the known universes. Each name begins with a dot, and hence is absolute.

mathematica

Usage: mathematica command ?arg ...?

Manage a Mathematica session. Mathematica is a commercial program for symbolic mathematics. This command will only work if your version of the executable has been built with an interface to Mathematica. Possible commands and their arguments are given below:

  terminate session:             end
  evaluate Mathematica command:  evalscript
  get expression in Tcl form:    getname?_script_?
  evaluate Mathematica command:  sendscript
  start a session:               start ?_identifier_?
  Tcl/Mathematica status:        status
The "mathematica send" command will not return output generated by Mathematica (unless an error occurs), "mathematica eval" will return it as a single string, and "mathematica get" sends the script for evaluation and returns the value of the variable name. For example, "mathematica send {Plot[Sin[2 Pi x], {x, 0, 1}]}" will create a simple plot, and "mathematica eval {?Plot}" will return help information about the Plot command. The "mathematica status" command returns 0 if the Tcl/Mathematica connection is open and Mathematica is running, and non-zero otherwise. A -1 indicates that the connection is not open, whereas 1 means that Mathematica is not running. Note that Mathematica syntax uses square brackets to denote function calls, parenthesis to group algebraic expressions, and curly braces to denote vectors and matrices. If Tcl tries to evaluate a string containing any of these special characters, then Tcl will flag an error.

matlab

Usage: matlab command ?arg ...?

Manage a Matlab session. This command will only work if your version of the executable has been built with Matlab. Possible commands and their arguments are given below:

  terminate session:           end
  evaluate Matlab script:      evalscript
  get matrix as Tcl lists:     getname?_script_?
  get matrix as ordered pairs: getpairsname?_script_?
  evaluate Matlab script:      sendscript
  set matrix as Tcl lists:     setname_rows_cols_real_ ?_imag_?
  start a session:             start ?_identifier_? ?_start_command_?
  Tcl/Matlab status:           status
  unset a matrix:              unset
The "matlab send" command will not return output from by Matlab (unless an error occurs), "matlab eval" will return output as a single string, and "matlab get" sends the script for evaluation and returns the value of the variable name. For example, "::pitcl::matlab send {plot( [1 2 2.5 1] )}" will create a simple plot, and "::pitcl::matlab eval {help plot}" will return help information about the plot command.

The "matlab status" command returns 0 if the Tcl/Matlab connection is open and Matlab is running, and non-zero otherwise. A return value of -1 indicates that the connection is not open, whereas 1 means that Matlab is not running. The "matlab start" command will launch an interface to Matlab. If the MATLAB_SERVER_HOSTNAME environment variable is set, then Matlab will be started on that machine. The argument specifies how to start Matlab. Note that Matlab syntax uses square brackets to denote vectors and matrices, which will cause errors if Tcl tries to evaluate a string containing them.

NOTE: The matlab command can cause Tycho to hang if it is being run in the background. This is because the external interface provided for matlab assumes that a terminal is connected to the program. To unhang tycho, put it in the foreground. We have also sometimes seen matlab hang the entire X window session. To correct this, kill the matlab process. Bugs should be reported to the Math Works, Inc.

monitor

Usage: monitor on|off

Turn on or off the monitoring of ptcl commands. When monitoring is on, then every time a ptcl command is called, the full text of the command is passed to the "monitorPtcl" procedure. By default, that procedure prints out the command using the Tcl puts procedure, but that procedure may be overridden.

monitorPtcl

When monitoring is turned on, this procedure is called each time a Ptcl procedure is invoked. The full text of the command is passed as arguments. This method may be overridden, but the default method prints the command using the Tcl puts procedure.

FIXME: This does not work for defGalaxy commands.

onFiring

Usage: onFiring ?-before? ?-after? ?starname? command

Bind a Tcl command to the firing of a star. If the -after option is given, then the binding triggers after the star firing (the invocation of its run method, which invokes the go method). If the -before option is given, or if no options are given, then the binding triggers before the firing. If no starname is specified, then the command is bound to all star firings. In either case, the full name of the particular star that triggers the binding will be appended to the command before the command invoked. For example, the command

	onFiring puts
will result in the printing of the name of every star after it is fired. The value returned by registerAction is a handle (a unique string) that can be used to cancel the action using onFiringCancel.

onFiringCancel

Usage: onFiringCancel handle|all

Cancel a binding created with onFiring. The single argument is the handle returned by onFiring or the keyword "all", in which case the all existing bindings are canceled.

ports

Return a list of port names for the specified block.

Usage: ports ?-inputs? ?-outputs? ?-multiports? blockname

If options are specified, they can be any combination of:

The first two options indicate that inputs or outputs should be listed. Specifying both of these options lists only ports that are both an input and an output, something supported in some domains. Specifying neither results in all ports being listed. The -multiports option specifies that only multiports should be listed, rather than the individual ports within the multiport. In this case, after each multiport is a list of its contained ports. For example, a multiport named "input" with two contained ordinary ports will appear in the result as "input {input#1 input#2}".

portsContained

Usage: portsContained ?-deep? portname

Return a list of ports contained by the given multiport. If the -deep option is given, then return the lowest level ports in the alias chain, which are always star ports. Otherwise, the returned ports may be galaxy ports. It is an error if the named port is not a multiport.

remove

Usage: remove name

Delete the specified block.

reset

Usage: reset ?galname?

Reconstruct the specified galaxy, or if none is specified, the current galaxy. This deletes all contained blocks, and then constructs new blocks of the same time and redoes all the connections. It uses the actionList of InterpGalaxy.

FIXME: test

run

Usage: run univname ?stoptime?

Run a universe until the specified stop time. What this time means depends on the domain. In SDF, for example, it gives the number of iterations of a complete schedule. In DE, it gives the simulated time after which no more events will be processed. If no argument is given, then the stop time is taken to be unity. As a side effect, the current galaxy is set to the universe being run. This procedure is equivalent to the sequence init, begin, cont.

setState

Usage: setState statename statevalue

Set the initial value of the specified state. For this to affect the current value you must invoke initState.

setTarget

Usage: setTarget ?blockname? targetname

Change the target for the specified block. Currently, the block must be a universe, although eventually it may be allowed to be a wormhole. If no block is specified, assume the current galaxy (which again must be a universe). The targets for the all the constituent blocks are immediately updated (no need to initialize).

states

Usage: states ?blockname?

Return the list of states in the given block. If no argument is given, return a list of the states of the current galaxy.

stateValue

Usage: stateValue ?-initial? statename

Return the value of the specified state. If the option is -initial, then return the initial value. Otherwise, return the current value.

wrapup

Usage: wrapup univname

Invoke the wrapup method of the specified universe.