The current Legion implementation supports a core PVM interface  , which includes functions for data marshaling, message passing, and task creation and control. Legion supports legacy PVM codes, and provides an enhanced PVM environment using Legion features such as security and placement services. For example, PVM applications can be run with encrypted message passing on Legion's PVM implementation.
A link-in replacement PVM library uses the primitive services provided by Legion, to support the PVM interface. For example, PVM tasks map directly to Legion objects: thus pvm_spawn() uses Legion.CreatObject(), and PVM task ids are mapped to Legion LOIDs. PVM Buffers are implemented by using Legion Buffers (the fundamental data container in the Legion runtime library): pvm_pmkint() thus uses LegionBuffer::put_int(). Similarly, PVM message-passing maps to Legion method invocation: the PVM-Legion library exports a new method, LegionPVMSend(). Sending a message to a task maps to calling the LegionPVMSend() method on the object corresponding to that task. A LegionBuffer containing the message becomes the parameter to the method.
Whereas PVM tasks are identified by integer task identifiers (Tids), Legion objects are identified by LOIDs, which come in varying sizes but are generally much larger than an int. The Legion-PVM library must therefore provide a mapping between Tids and LOIDs. Legion's contexts are used to manage this mapping, and the Legion library caches the mappings that have already been looked up. Since Tid-to-LOID mappings are invariant, caching can be performed without any consistency management costs.
Whereas PVM spawn requires a "task name" parameter to identify the type of task to spawn, Legion uses class LOIDs to specify an object's type. The Legion-PVM library utilizes a single class object for each type of task: therefore, Legion-PVM tasks are instances of Legion classes. Mapping between task names (i.e., as specified to pvm_spawn()) and class LOIDs is managed in Legion context space.
Legion classes have associated "implementation objects," which provide their instances with binary implementations. Because of this, PVM-Legion does not spawn tasks stored in a "well-known" directory location, as standard PVM does. A mechanism is provided for "registering" task implementations with the appropriate classes. Once executables are registered, the user does not need to explicitly manage the copying of binaries between hosts on disjoint file systems, since Legion automatically manages this, unlike standard PVM.
The PVM-Legion library can be installed using the source files in $LEGION/src/ServiceObjects/PVM3.
Task object code files can be compiled as before. Link against libLegionPVM.3, and basic Legion libraries (the final linkage must be performed using a C++ compiler, or using C++ appropriate flags for ld, since the Legion library has C++ link-time requirements).
A sample Legion PVM makefile is shown in Figure 8.
|Figure 8Sample Legion PVM make file|
This step can be skipped for tasks that will be started only from the command line (tasks that will not be "spawned").
legion_pvm_register <class name>
<binary path> <platform type>
This creates PVM-specific contexts, a class object for the task class, registers the name in Legion context space, and creates an implementation object for the class.
You can now run the PVM application. If necessary, you can examine Legion context space to get information about the PVM-Legion state with legion_ls.
legion_ls /pvm/tasksThe first lists the Tids of running PVM tasks (use the -L flag to include LOIDs), the second lists registered task classes. You can also use Legion class utilities to examine the class state (e.g., legion_list_instances).
There are several examples of PVM programs in an example file in your Legion system. They are in the following directory:
This section uses a sample program called "hello_other" to demonstrate the process of registering and running a PVM program. To compile this code, enter:
$ make $LEGION/bin/$LEGION_ARCH/hello_other
To register your program with the Legion/PVM system, use the legion_pvm_register command. The first time this is run Legion will create /pvm and /pvm/tasks directories. Your output will look something like this:
$ legion_pvm_register hello_other \ $LEGION/bin/$LEGION_ARCH/hello_other $LEGION_ARCH "/pvm" does not exist - creating it "/pvm/tasks" does not exist - creating it Task class "/pvm/tasks/hello_other" does not exist - creating it $
The hello_other class is now registered in context space and can be seen with the legion_ls command.
$ legion_ls -l /pvm/tasks hello_other (class) $
You can now run a simple example, with the new class. This example creates a new task and returns its and its host's PVM task ids in a simple message. Note that the command to run the example does not have a legion_ prefix.
$ hello i'm t34c8e665 from t64d7b9e5: hello, world from t64d7b9e5 (parent t34c8e665) on xxx.xxx.xxx.xxx $
Other programs can be registered and run using the same procedure.
Please see the Legion web site's tutorials section for an on-line tutorial called "Running a PVM code in Legion with the fewest changes" (<legion.virginia.edu/documentation/tutorials/PVM_cookbook.html>). The tutorial shows how to adapt a sample PVM program to run in Legion. Please note, however, that while this "fewest changes" approach allows you to run the program and to transparently read and write files remotely, it does not support heterogeneous conversions of data. If you run this program on several machines which have different integer formats, such as Intel PCs (little-endian) and IBM RS/6000s (big-endian), using unformatted I/O will produce surprising results. If you want to use such a heterogeneous system, you will have to either use formatted I/O (all files are text) or use the "typed binary" I/O calls instead of Fortran READ and WRITE statements. These "typed binary" I/O calls are discussed in "Buffered I/O library, low impact interface," in the Legion Developer Manual.
Directory of Legion 1.5 Manuals