Newer
Older
#include <iostream>
#include <cstdlib>
#include <ginac/ginac.h>
#include <fstream> // debug?
#include <signal.h> // necessaire ?
#include <sys/wait.h> // necessaire ?
#include <mpi.h>
#include <unistd.h> // debug
#ifdef TAUPROF
#include <TAU.h>
#endif
namespace gi = GiNaC;
/*
libginac-dev ginac-tools
mpic++ -O3 -g -Wall -o tensormatrix_mpi tensormatrix_mpi.cpp -lginac -Wno-unused-variable
*/
/* Arguments:
tensormatrix_mpi [N] [Function name] [Nb of foremen]
Function names being:
- M/m: Master-Worker -> multiply_1level_mw
- A/a: Master-Worker, addition on a slave -> multiply_1level_mw_addslave
- H/h: Hierarchical master-worker -> multiply_1level_mw_hierarch
- C/c: Combined -> multiply_combined
/*******************************************************************************
* Global variables *
*******************************************************************************/
unsigned int nbforemen = NBFOREMEN; /* Number of foremen to use with the hierarchical M/W */
unsigned int maxresult = MAXRESULT; /* Maximum results in the result queue, addslave version */
/*******************************************************************************
* Main function *
*******************************************************************************/
int main( int argc, char** argv ){
tensor3D_t T;
matrix_int_t J;
int N = DEFAULTN;
char tostart = DEFAULTFUNCTION;
gi::ex Tpara = 0;
gi::ex Tseq = 0;
double tv_start, tv_para, tv_seq;
int rank;
#ifdef TAUPROF
TAU_INIT(&argc, &argv);
TAU_PROFILE_SET_NODE(0);
#endif
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// std::cout << "Process " << rank << " has pid " << getpid() << std::endl;
/* Parse the command line */
if( argc >= 2 ) {
if( argv[1][0] == 'h' ) {
if( 0 == rank ) help();
MPI_Finalize();
return EXIT_SUCCESS;
}
N = atoi( argv[1] );
if( argc >= 3 ) {
switch( argv[2][0] ) {
case 'M':
case 'm':
tostart = 'm';
break;
case 'A':
case 'a':
tostart = 'a';
break;
case 'H':
case 'h':
tostart = 'h';
break;
case 'C':
case 'c':
tostart = 'c';
break;
case 'S':
case 's':
tostart = 's';
break;
case '1':
case '2':
tostart = argv[2][0];
break;
default:
std::cout << "Wrong function name. Using " << tostart << std::endl;
break;
}
if( argc >= 4 ) {
nbforemen = atoi( argv[3] ); /* these two variables are obtained from the same CI parameter but since they are */
maxresult = atoi( argv[3] ); /* used in two functions for two purposes, use two different names */
/* Initialize the tensor with symbolic values */
create_tensor_3D( T, N, N, N );
/* Initialize the simplectic matrix */
init_simplectic( J, N, N );
/* Compute it in parallel */
tv_start = getTime();
Tpara = multiply_1level_mw( T, N );
case 'a':
Tpara = multiply_1level_mw_addslave( T, N );
/*case 'h':
Tpara = multiply_1level_mw_hierarch( T, J, N );
break;
case 'c':
Tpara = multiply_combined( T, J, N );
case 's':
Tpara = multiply_seq( T, J, N );
break;
case '1':
Tpara = multiply_1level( T, J, N );
break;
default:
std::cerr << "Wrong function called" << std::endl;
}
tv_para = getTime();
/* Local verification */
if( 0 == rank ) {
#if DEBUG
Tseq = multiply_1level( T, J, N );
tv_seq = getTime();
std::cout << "Tpara3=" << Tpara << ";" << std::endl;
std::cout << "Tseq=" << Tseq << ";" << std::endl;
#endif
std::cout << "Time: ";
std::cout << "parallel " << ( tv_para - tv_start ) / 1e6 << " ";
#if DEBUG
std::cout << "sequential " << ( tv_seq - tv_para ) / 1e6 << " ";
/* this verification does not work, the manual one (copy-paste in ginsh) works */
std::cout << "Equal? " << ( Tseq.is_equal( Tpara ) ? "yes" : "no" ) << std::endl;
#endif
std::cout << std::endl;
// std::cout << "Difference? " << ( Tseq -= Tpara ) << std::endl;
}
MPI_Finalize();
return EXIT_SUCCESS;
}