next up previous
Next: Performance Evaluation Up: NetStream: a Flexible and Previous: A Basic Example of


Example of Groups Management

In this section we provide an example of utilization of the newly added methods to deal with groups of processes exchanging data in parallel. The methodology is simple: inside the present communicator a group of processes sharing the same color is defined and separated from the rest of processes. The communicator of the new group and the old group are explicitly linked by a method dealing with such inter-communicator matter.

#include <stream.h>
#include "stdio.h"
#include "../../netstream.hh"

int main(int argc,char ** argv) {
     NetStream netstream;

     char     msg[20];
     char     msg1[20];
     int      myrank, my_new_rank;
     int      local_root, remote_root, target;
     int      tag=99;
     NET_Comm new_comm, inter_communicator, my_comm;
     int      number_of_processes, half_size;
     int      color, key;

     NetStream::init(argc,argv);    // Init the comm system

            // Get the process ID of this process
     netstream << my_pid(&myrank);
            // Get the number of processes
     number_of_processes = netstream.pnumber();
            // Half the number of processes
     half_size           = number_of_processes/2;
            // The key does not need to be unique
            // nor starting at 0. It's useful for sorting
            // ranks inside new groups
     key                 = myrank;
     if (number_of_processes>=2)   // The first step is creating both groups.
    {
       if (myrank<half_size)  // First group is composed by processes 0..half_size-1
         color=0;   // Color shared by all the processes in the first  group
       else
         color=1;   // Color shared by all the processes in the second group

                // Get the communicator of the netstream
        my_comm  = netstream.get_communicator();
                // CREATE THE GROUPS
        new_comm = netstream.create_group(my_comm,color,key);
                // Set default communicator for I/O
        netstream.set_communicator(new_comm);
                // Find process ID in new group.
                // Notice that we invoke it as a method!
        my_new_rank = netstream.my_pid();

        cout << "\nProcess nš:  " << my_new_rank << " group: "
             << color << " ...old process nš: " << myrank << flush;

        // Do not forget to synchronize to begin communication!!!
        netstream << barrier;

    // Now we send a message to the last  process of the our group
    // and to the last process of the other group.
    if (color==0)
    {
            local_root  = 0;
            remote_root = half_size;
                    // Now we need an intercommunicator descriptor
            inter_communicator = netstream.create_inter_group
                        (new_comm,local_root,my_comm,remote_root,tag);
            if (my_new_rank==0)
            {
                strcpy(msg,"initial msg");
            target=half_size-1;
                cout      << "\nTarget process: "<< target << "\tSender process: "
                          << myrank << flush;
                netstream << set_target(target)  << set_source(0);
                netstream << msg;
            }
            else
            {
                if (my_new_rank==half_size-1)
                {
                    netstream << set_source(0)<< set_target(0);
                    netstream >> msg1;
                    cout <<"\n*Intramessage received: " << msg1 << flush;
                    strcpy(msg,"inter-msg");
                    netstream.set_communicator(inter_communicator);
                    target = number_of_processes-half_size-1;
                    cout << "\n*Intercomm target process: "<< target
                         << " Intercomm sender process: "  << my_new_rank << flush;
                    netstream << set_target(target) << set_source(0);
                    // The new communicator was selected as default before
                    netstream << msg;
                    cout << "\n***Intermsg sent: " << msg << flush;
                }
            }
    }
    else //The other group (color==1)
    {
        local_root  = 0;
        remote_root = 0;
            inter_communicator = netstream.create_inter_group
                        (new_comm,local_root,my_comm,remote_root,tag);
            if (my_new_rank==number_of_processes-half_size-1)
            {
                netstream.set_communicator(inter_communicator);
                // it is not necessary to modify the target attribute:
                netstream << set_target(0) << set_source(half_size-1);
                netstream >> msg1;
                cout << "\n***Intermessage received:" << msg1 << flush;
            }
    }
     }
     else
     {
        cout << "\nUnable to make groups. Number of processes smaller than 2."
             << flush;
     }
     NetStream::finalize();
} // main



Enrique Alba 2001-11-15