#ifdef MOAB_HAVE_MPI
#endif
#include <ctime>
#include <iostream>
#include <sstream>
const char BRIEF_DESC[] =
"Example of gather scatter with tuple lists \n";
using namespace std;
int main(
int argc,
char** argv )
{
#ifdef MOAB_HAVE_MPI
MPI_Init( &argc, &argv );
ProcConfig pc( MPI_COMM_WORLD );
int size = pc.proc_size();
int rank = pc.proc_rank();
LONG_DESC <<
"This program does a gather scatter with a list of tuples. \n"
" It tries to see how much communication costs in terms of time and memory. \n"
<< "It starts with creating a list of tuples to be sent from each processor, \n to a "
"list of other processors.\n"
<< "The number of tuples and how many tasks to communicate to are controlled by "
"input parameters.\n"
<< "After communication, we verify locally if we received what we expected. \n";
int num_comms = 2;
opts.
addOpt<
int >(
"num_comms,n",
"each task will send to about num_comms other tasks some tuples (default 2)",
&num_comms );
int num_tuples = 4;
opts.
addOpt<
int >(
"num_tuples,t",
"each task will send to some task about num_tuples tuples (default 4)",
&num_tuples );
int reportrank =
size + 1;
opts.
addOpt<
int >(
"reporting_rank,r",
"this rank will report the tuples sent and the tuples received; it could "
"be higher than num_procs, then no reporting",
&reportrank );
if( rank == reportrank || ( reportrank >=
size && 0 == rank ) )
{
cout <<
" There are " <<
size <<
" tasks in example.\n";
cout << " We will send groups of " << num_tuples << " from each task towards " << num_comms
<< " other tasks.\n";
}
gs_data::crystal_data* cd = pc.crystal_router();
long total_n_tuples = num_comms * num_tuples;
num_comms--;
else
num_comms++;
num_tuples *= 2;
num_tuples /= 2;
TupleList tl;
tl.initialize( 1, 1, 0, 1, num_tuples * num_comms );
tl.enableWriteAccess();
unsigned int n = tl.get_n();
for( int i = 0; i < num_comms; i++ )
{
int sendTo = rank + i *
size / 2 + 1;
long intToSend = 1000 * rank + 100000 * sendTo;
for( int j = 0; j < num_tuples; j++ )
{
n = tl.get_n();
tl.vi_wr[n] = sendTo;
tl.vl_wr[n] = intToSend + j;
tl.vr_wr[n] = 10000. * rank + j;
tl.inc_n();
}
}
if( rank == reportrank )
{
cout << "rank " << rank << "\n";
tl.print( " before sending" );
}
clock_t tt = clock();
double secs = 0;
if( rank == reportrank || ( reportrank >=
size && 0 == rank ) )
{
secs = ( clock() - tt ) / (double)CLOCKS_PER_SEC;
}
if( rank == reportrank )
{
cout << "rank " << rank << "\n";
tl.print( " after transfer" );
}
unsigned int received = tl.get_n();
for( int i = 0; i < (int)received; i++ )
{
int from = tl.vi_rd[i];
long valrec = tl.vl_rd[i];
int remainder = valrec - 100000 * rank - 1000 * from;
if( remainder < 0 || remainder >= num_tuples * 4 )
cout << " error: tuple " << i << " received at proc rank " << rank << " from proc " << from << " has value "
<< valrec << " remainder " << remainder << "\n";
}
if( rank == reportrank || ( reportrank >=
size && 0 == rank ) )
{
cout << "communication of about " << total_n_tuples << " tuples/per proc took " << secs << " seconds"
<< "\n";
tt = clock();
}
MPI_Finalize();
#else
std::cout << " Build with MPI for this example to work\n";
#endif
return 0;
}