TITLE: Container Operations v7 * Version v7 has a small change made at the September 2000 meeting at which the proposal was encouraged with a straw vote of 5/0/1. The change is to remove the search mode argument from the FLATTEN function. The search mode was supposed to address the issue of when to emit the items at a node of the search tree, but the node is always a container and no containers appear in the output. * Version v6 corrects some typos and the omission of the INORDER search mode. * Version v5 resulted from the June 2000 meeting where the amended proposal was supported by a straw vote of 7/0/0. The six main functions will not check for duplicate arguments, leaving that to the underlying functions. The descriptive text is modified to describe the error cases in the style of the rest of the document. The container argument is IN rather than INOUT. The FLATTEN function gained an argument to describe the order of recursive search. For both the FLATTEN and FILTER functions, duplicate entries are silently removed with no error. Both of these functions will return the same type of container as that given as the input argument. * Version v4 is the result of discussions at the March 2000 meeting. The clarification of what "atomic" could mean for each case resulted in the removal of the atomic versions and the redefinition of the meaning of the remaining function for each case. The ability to control (in some cases, only partially) the operation order is now allowed by using vector containers. The descriptions assume that container iterators will be included in MPI/RT 1.1. The issues section is updated and the error return descriptions are complete. * Version v3 responds to comments at the December 1999 meeting where the proposal was encouraged with a straw vote of 7/0/0. The main change was that there should be "atomic" versions of each function as well. This is now noted in the issues section, and six new functions have been added. Error return values have been noted. * Version v2 includes comments from the June 1999 meeting. The container argument provided to the functions must be flattened and contain only elements which can be acted upon. The order that operations are performed on the given objects is now undefined and may be done in parallel. Two new functions are introduced to manipulate containers to help prepare them for use: FLATTEN and FILTER. The email summary and extended background notes were removed. * Version v1 was my summary of issues and an informal proposal that was based on an earlier proposal by Nathan Doss not accepted in MPI/RT 1.0 due to time constraints of the standards process. SUMMARY: New functions on containers are proposed which propagate their operations to all objects within the container. Two additional container manipulation functions support this use. BACKGROUND: After the July 1998 MPI/RT meeting there was a wide-ranging email discussion on how to further integrate containers with MPI/RT. Although a few spin-off issues were dealt with in MPI/RT 1.0, most were deferred until a time when we could think through their ramifications more thoroughly. Several operations were identified for which it seemed clearly beneficial to be able to perform the operation on a number of objects in a container at once. ISSUES: * Nested containers: If containers are allowed to be nested, then the question arises of what algorithm (e.g., depth first) is used to traverse the container. This proposal disallows nested containers for the proposed operations, but provides a new function to assist in flattening a nested container into a single container. * Order of activation: Should the order that operations are applied to the objects be defined or should it be left to the implementation? This proposal allows the user to partially control the order in some cases by providing a vector container when desired. In the case of START, for instance, part of the operation may be ordered (getting the buffer from the bufiter and marking the channel ready) while the selection of which channel will transfer first is determined by QoS after all channels have been enqueued. * One operation per object: An object may be encountered more than once in a vector container or in nested containers. This proposal states that it is up to the underlying single-object function to determine the course of action. * Non-type objects: All of the container operations being proposed are on an object of a specific type. When an object not of this type is found in the container, we could (a) report an error, (b) ignore the object, or the always popular (c) declare an "erroneous" program. This proposal says the underlying single-object function will determine the course of action. * Blocking operations: When performing an operation on a number of objects, there is the question of whether we state that they occur synchronously (that is, sequentially, waiting for one to complete before operating on the next) or asynchronously. Only one of these operations (DEACTIVATE) is blocking in the sense that the calling code may have to wait for communication completion. This proposal states explicitly what happens for that case. * Cost of using: If the above issues are always resolved at the time the function is called, the overhead could be a significant factor. Therefore, the proposed functions are not required to handle nested containers. Two additional support functions are provided to allow users to flatten and filter containers. PROPOSAL: The following six functions and their descriptions will be added to the MPI/RT 1.1 standard. In each case, the description of the function will be placed following the non-container version of the function, e.g., MPIRT_CONTAINER_START will follow MPIRT_START. New error returns are defined which must be added to Annex A. Operation and entity tables at the end of the appropriate chapters must be revised. New error returns: MPIRT_ERR_INV_TYPE -- no such object type (to MPIRT_CONTAINER_FILTER) Insert the following at 163/21: MPIRT_CONTAINER_START (container) IN container a container that includes all channels to be started (MPIRT_CONTAINER) int MPIRT_Container_start (MPIRT_Container container) int MPIRT::Container::Start (void) const This function allows the user to start multiple channels with a single function call. The given channels remove a buffer from their buffer iterators and transition into their *Transferrable* substate in the order in which they would be selected from the container using a container iterator over that container. No channel will transition into the *Transferring* substate until all have been placed into the *Transferrable* substate. Subsequent operation is determined by the QoS of all channels. The container may be empty, but it may not be NULL. Other error returns may be generated as if each first-level object in the container were processed by MPIRT_CHANNEL_START. Insert the following at 164/6: MPIRT_CONTAINER_ACTIVATE (container) IN container a container that includes all channels to be activated (MPIRT_CONTAINER) int MPIRT_Container_activate (MPIRT_Container container) int MPIRT::Container::Activate () const This function allows the user to activate multiple channels with a single function call. The given channels transition into their *Waiting for Transfer* substate in the order in which they would be selected from the container using a container iterator over that container. No channel transitions into the *Transferrable* substate until all have been placed into the *Waiting for Transfer* substate. The container may be empty, but it may not be NULL. Other error returns may be generated as if each first-level object in the container were processed by MPIRT_CHANNEL_ACTIVATE. Insert the following at 164/21: MPIRT_CONTAINER_DEACTIVATE (container) IN container a container that includes all channels to be deactivated (MPIRT_CONTAINER) int MPIRT_Container_deactivate (MPIRT_Container container) int MPIRT::Container::Deactivate () const This function allows the user to deactivate multiple channels with a single function call. MPIRT_CHANNEL_DEACTIVATE may block waiting for a channel transmission to finish. For any channels which must be awaited, the order in which the waiting is done is the order in which they would be selected from the container using a container iterator over that container. The container may be empty, but it may not be NULL. Other error returns may be generated as if each first-level object in the container were processed by MPIRT_CHANNEL_DEACTIVATE. Insert the following at 233/47: MPIRT_CONTAINER_MARK (container) IN container a container that includes all probes to be marked (MPIRT_CONTAINER) int MPIRT_Container_mark (MPIRT_Container container) int MPIRT::Container::Mark () const This function allows the user to mark multiple probes with a single function call. The order in which the operations are performed on the given objects is that in which they would be selected from the container using a container iterator over that container. The container may be empty, but it may not be NULL. Other error returns may be generated as if each first-level object in the container were processed by MPIRT_PROBE_MARK. Insert the following at 234/29: MPIRT_CONTAINER_ACCUMULATE (container) IN container a container that includes all probes to be accumulated (MPIRT_CONTAINER) int MPIRT_Container_accumulate (MPIRT_Container container) int MPIRT::Container::Accumulate () const This function allows the user to accumulate multiple probes with a single function call. The order in which the operations are performed on the given objects is that in which they would be selected from the container using a container iterator over that container. The container may be empty, but it may not be NULL. Other error returns may be generated as if each first-level object in the container were processed by MPIRT_PROBE_ACCUMULATE. Insert the following at 72/36: MPIRT_CONTAINER_RAISE (container) IN container a container that includes all triggers to be raised (MPIRT_CONTAINER) int MPIRT_Container_raise (MPIRT_Container container) int MPIRT::Container::Raise () const This function allows the user to raise multiple triggers with a single function call. The order in which the operations are performed on the given objects is undefined and may be done in parallel. The container may be empty, but it may not be NULL. Other error returns may be generated as if each first-level object in the container were processed by MPIRT_TRIGGER_RAISE. The following two functions manipulate containers and will be included in Section 2.5.2 (Generic Container Operations). Tables at the end of the chapter must be revised. Note that both have the usual footnote that the argument class must be the same or a superclass of the function. Insert the following at 36/33: MPIRT_name-of-CONTAINER-class_FLATTEN (in_container, out_container) IN in_container a possibly nested container that will be flattened (MPIRT_name-of-CONTAINER-class) OUT out_container a non-nested container (ref. to MPIRT_name-of-CONTAINER-class) int MPIRT_name-of-CONTAINER-class_flatten (MPIRT_Container in_container, MPIRT_name-of-CONTAINER-class *out_container) int MPIRT::name-of-CONTAINER-class::Flatten ( MPIRT::name-of-CONTAINER-class &out_container) const This function takes as input a possibly nested container and returns a new container of the same type containing each non-container object found in a nested search of the input container. If the input container is a vector, the order of elements in the output vector is determined by the order in which the elements would be selected using a container iterator in a depth-first traversal of the input container and any nested containers. When duplicate entries are encountered, the first one is kept in the output container and the others are silently ignored. The container may be empty, but it may not be NULL. Note that the system has created a new container object that must later be freed by the user. MPIRT_name-of-CONTAINER-class_FILTER (in_container, obj_type, out_container) IN in_container a container that will be filtered (MPIRT_name-of-CONTAINER-class) IN obj_type the type of object to be retained (MPIRT_OBJECT_TYPE) OUT out_container the filtered container (ref. to MPIRT_name-of-CONTAINER-class) int MPIRT_name-of-CONTAINER-class_filter (MPIRT_Container in_container, MPIRT_Object_type obj_type, MPIRT_Cset *out_container) int MPIRT::name-of-CONTAINER-class::Filter (MPIRT::Object_type obj_type, MPIRT::name-of-CONTAINER-class &out_container) const This function takes as input a container and returns a new container of the same type containing objects in "in_container" that have the type "obj_type". When duplicate entries are encountered, the first one is kept in the output container and the others are silently ignored. Only first level objects will be included; objects in nested containers are not considered. The container may be empty, but it may not be NULL. If an unknown object type is given, the function will return MPIRT_ERR_INV_TYPE. Note that the system has created a new container object that must later be freed by the user. Additional container functions may be found in sections 4.2.3, 9.1.3, 9.1.4, and 15.3.