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