Commit f0055edc authored by Camille Coti's avatar Camille Coti
Browse files

Combined algorithm

parent df19e6c1
......@@ -28,8 +28,8 @@ NP = 5
MPISRC = masterworker.cpp mw_addslave.cpp \
perf.cpp sequential.cpp tensormatrix_mpi.cpp \
utils.cpp utils_parall.cpp profiling.cpp
#mw_combined.cpp hierarchical.cpp
utils.cpp utils_parall.cpp profiling.cpp mw_combined.cpp
# hierarchical.cpp
MPIOBJ= $(MPISRC:.cpp=.o)
......
......@@ -25,8 +25,8 @@ typedef enum {
/* This one is a "regular" master. It returns either when it is done, or when it decides to switch to another algorithm.
*/
end_code_t multiply_combined_master_initial( tensor3D_t& T, matrix_int_t& J, unsigned int size, gi::ex& Tens, MPI_Comm comm = MPI_COMM_WORLD ) {
unsigned int a1, a2, a3, b1;
end_code_t multiply_combined_master_initial( tensor3D_t& T, unsigned int size, gi::ex& Tens, MPI_Comm comm = MPI_COMM_WORLD ) {
unsigned int a1, a2, a4;
gi::ex A;
gi::lst symbols;
......@@ -52,6 +52,7 @@ end_code_t multiply_combined_master_initial( tensor3D_t& T, matrix_int_t& J, uns
j = 0;
int receivedresults = 0;
unsigned int N = size/2;
std::vector<parameters_t> input;
std::vector<std::string> results_s;
......@@ -59,20 +60,17 @@ end_code_t multiply_combined_master_initial( tensor3D_t& T, matrix_int_t& J, uns
/* Build a list of argument sets */
for( a1 = 0 ; a1 < size; a1++ ){
for( a4 = 0 ; a4 < N ; a4++ ){
i=i+1;
for( a2 = 0; a2 < size ; a2++ ){
j=j+1;
for( a3 = 0 ; a3 < size ; a3++ ){
A = T[a1][a2][a3];
for( b1 = 0 ; b1 < size ; b1++ ){
parameters_t p( A, a1, a2, a3, b1 );
input.push_back( p );
}
for( a2 = 0; a2 < N ; a2++ ){
j=j+1;
for( a1 = 0 ; a1 < N ; a1++ ){
parameters_t p( a4, a2, a1 );
input.push_back( p );
}
}
}
}
/* Compute the set of symbols */
/* Could be done while the first slave is working */
......@@ -90,31 +88,29 @@ end_code_t multiply_combined_master_initial( tensor3D_t& T, matrix_int_t& J, uns
/* Distribute the work */
while( input.size() > 0 ) {
t_start = rdtsc();
t_start = rdtsc();
MPI_Recv( &len, 1, MPI_UNSIGNED, MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status );
src = status.MPI_SOURCE;
t_wait = rdtsc() - t_start;
times[ times_idx] = t_wait;
times_idx = ( times_idx + 1 ) % ( np - 1 );
if( !initialround )
t_average = std::accumulate( times.begin(), times.end(), 0.0 )/(double)(np - 1);
std::cout << "wait " << t_wait << std::endl;
t_wait = rdtsc() - t_start;
times[ times_idx] = t_wait;
times_idx = ( times_idx + 1 ) % ( np - 1 );
if( !initialround )
t_average = std::accumulate( times.begin(), times.end(), 0.0 )/(double)(np - 1);
if( status.MPI_TAG == TAG_PULL ) {
/* Nothing else will come: just send wome work */
send_work( input, src, comm );
if( initialround ){
running++;
if( np - 1 == running ) initialround = false; // everyone is at work
}
if( initialround ){
running++;
if( np - 1 == running ) initialround = false; // everyone is at work
}
} else {
if( status.MPI_TAG == TAG_RES ){
src = status.MPI_SOURCE;
/* The first message contains the length of what is coming next */
if( len != 0 ) {
if( len > expr_c_size ) {
......@@ -125,67 +121,67 @@ end_code_t multiply_combined_master_initial( tensor3D_t& T, matrix_int_t& J, uns
/* Receive the result */
MPI_Recv( expr_c, len, MPI_CHAR, src, TAG_EXPR, comm, &status );
/* put it in the result queue */
std::string s( expr_c );
if( algo == ALGO_MW) {
send_work( input, src, comm );
if( algo == ALGO_MW) {
send_work( input, src, comm );
}
/* Process what I have just received */
if( ALGO_MW == algo ) {
t_start = rdtsc();
gi::ex received = de_linearize_expression( s, symbols );
Tens += received;
t_add = rdtsc() - t_start;
std::cout << "Add " << t_add << std::endl;
if( ALGO_MW == algo ) {
t_start = rdtsc();
gi::ex received = de_linearize_expression( s, symbols );
Tens += received;
t_add = rdtsc() - t_start;
std::cout << "Add " << t_add << std::endl;
#if DEBUG
results.push_back( received );
results_s.push_back( s );
receivedresults++;
results.push_back( received );
results_s.push_back( s );
receivedresults++;
#endif
if( !initialround && t_add > t_average ) {
/* We are spending too much time adding these results. Now we are going to ask a worker to do this. */
std::cout << "The master spent too much time computing the sum. Switch to ADDSLAVE algorithm" << std::endl;
algo = ALGO_ADDSLAVE;
}
} else {
if( ALGO_ADDSLAVE == algo ) {
results_s.push_back( s );
send_work_addslave( input, results_s, src );
} else {
std::cout << "ERROR: unknown algorithm on the master " << algo << std::endl;
}
}
if( !initialround && t_add > t_average ) {
/* We are spending too much time adding these results. Now we are going to ask a worker to do this. */
std::cout << "The master spent too much time computing the sum. Switch to ADDSLAVE algorithm" << std::endl;
algo = ALGO_ADDSLAVE;
}
} else {
if( ALGO_ADDSLAVE == algo ) {
results_s.push_back( s );
send_work_addslave( input, results_s, src );
} else {
std::cout << "ERROR: unknown algorithm on the master " << algo << std::endl;
}
}
} else {
/* Send more work */
send_work( input, src, comm );
}
} else{
std::cerr << "Wrong tag received " << status.MPI_TAG << std::endl;
}
}
}
/* Wait until everyone is done */
/* Wait until everyone is done */
running = np - 1; // all the slaves are running
while( running > 0 ) {
MPI_Recv( &len, 1, MPI_UNSIGNED, MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status );
src = status.MPI_SOURCE;
if( len != 0 ) {
if( len > expr_c_size ) {
expr_c_size = len;
if( NULL != expr_c ) free( expr_c );
expr_c = (char*)malloc( expr_c_size ); // The \0 was added by the slave
}
/* Receive the result */
MPI_Recv( expr_c, len, MPI_CHAR, src, TAG_EXPR, comm, &status );
......@@ -222,9 +218,9 @@ end_code_t multiply_combined_master_initial( tensor3D_t& T, matrix_int_t& J, uns
/* The traditional slave */
void multiply_combined_slave_initial( tensor3D_t& T, matrix_int_t& J, int size, MPI_Comm comm = MPI_COMM_WORLD ) {
void multiply_combined_slave_initial( tensor3D_t& T, int size, MPI_Comm comm = MPI_COMM_WORLD ) {
gi::ex Tens;
int a1, a2, a3, b1;
int a1, a2, a4;
// gi::ex A;
unsigned int len = 0;
......@@ -248,21 +244,19 @@ void multiply_combined_slave_initial( tensor3D_t& T, matrix_int_t& J, int size,
while( true ){
/* Receive a set of parameters */
t_start = rdtsc();
t_start = rdtsc();
MPI_Recv( &params, 1, DT_PARAMETERS, ROOT, MPI_ANY_TAG, comm, &status );
t_wait = rdtsc() - t_start;
t_wait = rdtsc() - t_start;
if( status.MPI_TAG == TAG_WORK ){
a1 = params.a1;
a2 = params.a2;
a3 = params.a3;
b1 = params.b1;
gi::symbol A( std::string( params.A ) );
a4 = params.a4;
t_start = rdtsc();
Tens = one_level1_product( &T, size, a4, a2, a1 );
t_compute = rdtsc() - t_start;
t_start = rdtsc();
Tens = one_level1_product( &T, &J, A, size, a1, a2, a3, b1 );
t_compute = rdtsc() - t_start;
/* TODO if we waited for too long */
if( t_wait > t_compute ) {}
......@@ -273,7 +267,7 @@ void multiply_combined_slave_initial( tensor3D_t& T, matrix_int_t& J, int size,
/* Receive a set of expressions to add */
/* Number of expressions received */
int nb = params.a1;
int nb = params.a4;
/* Length of each string */
......@@ -291,22 +285,22 @@ void multiply_combined_slave_initial( tensor3D_t& T, matrix_int_t& J, int size,
results_s.push_back( std::string( c_str ) );
free( c_str );
}
/* Delinearize all the expressions and add them */
Tens = add_expressions( results_s, symbols );
/* Send the result */
send_result( Tens );
} else {
if( status.MPI_TAG == TAG_END ){
return;
} else {
if( status.MPI_TAG == TAG_END ){
return;
} else {
std::cerr << "Wrong tag received on slave " << status.MPI_TAG << std::endl;
}
}
}
}
}
}
}
......@@ -315,31 +309,31 @@ void multiply_combined_slave_initial( tensor3D_t& T, matrix_int_t& J, int size,
* Combined master-worker *
*******************************************************************************/
gi::ex multiply_combined_master( tensor3D_t& T, matrix_int_t& J, int size ) { // simpler: same dimension everywhere
gi::ex multiply_combined_master( tensor3D_t& T, int size ) { // simpler: same dimension everywhere
gi::ex Tens = 0;
end_code_t rc;
/* Initially: start as a traditional M/W */
rc = multiply_combined_master_initial( T, J, size, Tens );
rc = multiply_combined_master_initial( T, size, Tens );
switch( rc ){
case FINISHED:
return Tens;
return Tens;
}
return Tens;
}
void multiply_combined_worker( tensor3D_t& T, matrix_int_t& J, int size ) { // simpler: same dimension everywhere
void multiply_combined_worker( tensor3D_t& T, int size ) { // simpler: same dimension everywhere
gi::ex Tens = 0;
std::cout << "worker" << std::endl;
multiply_combined_slave_initial( T, J, size );
multiply_combined_slave_initial( T, size );
}
gi::ex multiply_combined( tensor3D_t& T, matrix_int_t& J, int size ) { // simpler: same dimension everywhere
gi::ex multiply_combined( tensor3D_t& T, int size ) { // simpler: same dimension everywhere
int rank;
gi::ex Tens = 0;
......@@ -352,9 +346,9 @@ gi::ex multiply_combined( tensor3D_t& T, matrix_int_t& J, int size ) { // simpl
/* Here we go */
if( 0 == rank ) {
Tens = multiply_combined_master( T, J, size );
Tens = multiply_combined_master( T, size );
} else {
multiply_combined_worker( T, J, size );
multiply_combined_worker( T, size );
}
/* Finalize */
......
......@@ -26,7 +26,7 @@ gi::ex multiply_2levels( tensor3D_t&, matrix_int_t&, int );
gi::ex multiply_1level_mw( tensor3D_t&, int );
gi::ex multiply_1level_mw_addslave( tensor3D_t&, int );
gi::ex multiply_1level_mw_hierarch( tensor3D_t&, matrix_int_t&, int );
gi::ex multiply_combined( tensor3D_t&, matrix_int_t&, int );
gi::ex multiply_combined( tensor3D_t&, int );
/*******************************************************************************
* Default values *
......
......@@ -139,10 +139,10 @@ int main( int argc, char** argv ){
break;
/*case 'h':
Tpara = multiply_1level_mw_hierarch( T, J, N );
break;
case 'c':
Tpara = multiply_combined( T, J, N );
break;*/
case 'c':
Tpara = multiply_combined( T, N );
break;
case 's':
Tpara = multiply_seq( T, J, N );
break;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment