00001 #include "ParGraph.hpp"
00002 #include <iostream>
00003 #include <stdlib.h>
00004
00005 namespace ParGraph {
00006 comm_layer_t _libbase;
00007
00008
00009 inline void ParGraph_common_init()
00010 {
00011 int tmp;
00012
00013 MPI_Comm_rank(_libbase._comm,&tmp);
00014 _libbase._rank = size_t(tmp);
00015 MPI_Comm_size(_libbase._comm,&tmp);
00016 _libbase._size = size_t(tmp);
00017 }
00018
00019 void ParGraph_init( int& argc, char**& argv )
00020 {
00021 int mpi_is_init;
00022 MPI_Initialized(&mpi_is_init);
00023
00024 _libbase._mpi_was_init = mpi_is_init;
00025
00026 if ( !mpi_is_init )
00027 MPI_Init(&argc,&argv);
00028
00029 MPI_Comm_dup(MPI_COMM_WORLD, &_libbase._comm);
00030
00031 ParGraph_common_init();
00032 }
00033
00034 void ParGraph_init(int& argc, char**& argv, MPI_Comm& user_comm)
00035 {
00036 _libbase._mpi_was_init = 1;
00037
00038 MPI_Comm_dup(user_comm, &_libbase._comm);
00039
00040 ParGraph_common_init();
00041 }
00042
00043 void ParGraph_finalize()
00044 {
00045 MPI_Barrier(_libbase._comm);
00046 MPI_Comm_free(&_libbase._comm);
00047
00048 if ( !_libbase._mpi_was_init )
00049 {
00050 MPI_Finalize();
00051 }
00052 }
00053
00054 bool PG_ReduceOr( bool b )
00055 {
00056 int val = b ? -1 : 0;
00057 int res;
00058
00059 MPI_Allreduce( &val, &res, 1, MPI_INT, MPI_LOR, _libbase.comm() );
00060
00061 return res != 0 ? true : false;
00062 }
00063
00064 bool PG_ReduceAnd( bool b )
00065 {
00066 int val = b ? -1 : 0;
00067 int res;
00068
00069 MPI_Allreduce( &val, &res, 1, MPI_INT, MPI_LAND, _libbase.comm() );
00070
00071 return res != 0 ? true : false;
00072 }
00073
00074 size_t PG_ReduceAdd( size_t local )
00075 {
00076 size_t global;
00077 MPI_Allreduce( &local, &global, 1, MPI_UNSIGNED, MPI_SUM, _libbase.comm() );
00078 return global;
00079 }
00080
00081 AllGatherBuffer::AllGatherBuffer()
00082 {
00083 recv_buffer_parts = new int[ _libbase.size() ];
00084 recv_size = new int[ _libbase.size() ];
00085
00086 recv_buffer = 0;
00087 cur_recv_position = 0;
00088 whole_recv_size = 0;
00089
00090 send_buffer = 0;
00091 send_size = 0;
00092 send_maxsize = 0;
00093 send_position = 0;
00094 }
00095
00096 AllGatherBuffer::~AllGatherBuffer()
00097 {
00098 if( send_buffer != 0 ) delete[] send_buffer;
00099 if( recv_buffer != 0 ) delete[] recv_buffer;
00100 delete[] recv_buffer_parts;
00101 delete[] recv_size;
00102 }
00103
00104 void
00105 AllGatherBuffer::communicate()
00106 {
00107 if( recv_buffer != 0 ) delete[] recv_buffer;
00108
00109 MPI_Allgather( &send_size, 1, MPI_INT, recv_size, 1, MPI_INT, _libbase.comm() );
00110
00111 size_t size = 0;
00112 for( unsigned int i = 0 ; i < _libbase.size() ; i++ )
00113 {
00114 recv_buffer_parts[i] = size;
00115 size += recv_size[i];
00116 }
00117 recv_buffer = new char[ size ];
00118 cur_recv_position = 0;
00119 whole_recv_size = size;
00120 last_recv_proc = 0;
00121
00122 MPI_Allgatherv( (int*) send_buffer, send_size, MPI_CHAR,
00123 recv_buffer, recv_size, recv_buffer_parts, MPI_CHAR, _libbase.comm() );
00124
00125 send_size = 0;
00126 send_maxsize = 0;
00127 send_position = 0;
00128
00129 if( send_buffer != 0 )
00130 {
00131 delete[] send_buffer;
00132 send_buffer = 0;
00133 }
00134 }
00135
00136 AllToAllBuffer::AllToAllBuffer()
00137 {
00138 send_buffer = new char*[ _libbase.size() ];
00139 recv_buffer_parts = new int[ _libbase.size() ];
00140 send_size = new int[ _libbase.size() ];
00141 recv_size = new int[ _libbase.size() ];
00142 send_maxsize = new int[ _libbase.size() ];
00143 send_position = new int[ _libbase.size() ];
00144
00145 recv_buffer = 0;
00146 cur_recv_position = 0;
00147 whole_recv_size = 0;
00148
00149 for( unsigned int i = 0 ; i < _libbase.size() ; i++ )
00150 {
00151 send_buffer[i] = 0;
00152 send_size[i] = 0;
00153 send_maxsize[i] = 0;
00154 send_position[i] = 0;
00155 }
00156 }
00157
00158 AllToAllBuffer::~AllToAllBuffer()
00159 {
00160 for( unsigned int i = 0 ; i < _libbase.size() ; i++ )
00161 {
00162 free( send_buffer[ i ] );
00163 }
00164 delete[] send_buffer;
00165 delete[] send_size;
00166 delete[] send_maxsize;
00167 delete[] send_position;
00168 delete[] recv_buffer;
00169 delete[] recv_buffer_parts;
00170 delete[] recv_size;
00171 }
00172
00173 void
00174 AllToAllBuffer::communicate()
00175 {
00176 if( recv_buffer != 0 ) delete[] recv_buffer;
00177
00178 MPI_Alltoall( send_size, 1, MPI_INT, recv_size, 1, MPI_INT, _libbase.comm() );
00179
00180 size_t size = 0;
00181 for( proc_t i = 0 ; i < _libbase.size() ; i++ )
00182 {
00183 recv_buffer_parts[i] = size;
00184 size += recv_size[i];
00185 }
00186 recv_buffer = new char[ size ];
00187 whole_recv_size = size;
00188 last_recv_proc = 0;
00189 cur_recv_position = 0;
00190
00191 MPI_Alltoallv( 0, send_size, (int*) send_buffer, MPI_CHAR,
00192 recv_buffer, recv_size, recv_buffer_parts, MPI_CHAR, _libbase.comm() );
00193
00194 for( proc_t i = 0 ; i < _libbase.size() ; i++ )
00195 {
00196 free( send_buffer[ i ] );
00197 send_buffer[ i ] = 0;
00198 send_size[i] = 0;
00199 send_maxsize[i] = 0;
00200 send_position[i] = 0;
00201 }
00202 }
00203 }