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