6 #ifndef CNTR_DISTRIBUTED_ARRAY_IMPL_H 7 #define CNTR_DISTRIBUTED_ARRAY_IMPL_H 27 tid_map_=std::vector<int>(0);
30 if(data_!=0)
delete [] data_;
34 blocksize_=g.blocksize_;
43 memcpy(data_, g.
data(),
sizeof(T)*len);
50 if(
this==&g)
return *
this;
51 if(data_!=0)
delete [] data_;
61 memcpy(data_, g.
data(),
sizeof(T)*len);
89 assert(0<=maxlen && 0<=n);
100 memset(data_, 0,
sizeof(T)*len);
105 MPI_Comm_size(MPI_COMM_WORLD, &ntasks_);
106 MPI_Comm_rank(MPI_COMM_WORLD, &tid_);
118 int remainer,buckets;
119 for(
int i=0;i<ntasks_;i++){
120 remainer = n - nr_alloced;
121 buckets = (ntasks_ - i);
122 int size=remainer/ buckets;
123 for(
int k=0;k<size;k++){
124 tid_map_[nr_alloced+k]=i;
172 return data_+j*blocksize_;
187 if(data_!=0) memset(data_, 0,
sizeof(T)*maxlen_*n_);
207 assert(0<=blocksize && 0<=blocksize_ && 0<= (
int) maxlen_);
209 blocksize_=blocksize;
226 for(
int i=0;i<n_;i++){
227 if(tid_map_[i]==tid_){
232 return rank_totblock;
248 int rank_firstblock=0;
250 for(
int i=0;i<n_;i++){
251 if(tid_map_[i]==tid_){
256 return rank_firstblock;
275 #else // CNTR_USE_MPI==1 293 assert(0<=dest && 0<=ntasks_-1);
294 int root=tid_map_[j];
299 size_t int_per_t=
sizeof(T)/
sizeof(
int);
300 size_t len=int_per_t*blocksize_;
301 if(tid_map_[j]==tid_){
302 MPI_Send((
int*) block(j), len, MPI_INT, dest, tag, MPI_COMM_WORLD);
307 MPI_Recv((
int*) block(j), len, MPI_INT, root, tag, MPI_COMM_WORLD,
327 assert(0<=dest && 0<=ntasks_-1);
328 for(
int j=0;j<n_;j++) mpi_send_block(j,dest);
346 int root=tid_map_[j];
347 size_t int_per_t=
sizeof(T)/
sizeof(
int);
348 assert(int_per_t*
sizeof(
int)==
sizeof(T));
349 size_t len=int_per_t*blocksize_;
351 MPI_Bcast((
int*)block(j), len, MPI_INT, root, MPI_COMM_WORLD);
372 size_t int_per_t =
sizeof(T) /
sizeof(
int);
373 assert(int_per_t *
sizeof(
int) ==
sizeof(T));
374 int element_size = blocksize_ * int_per_t;
376 std::vector<int> recvcount(ntasks_, 0);
377 for(
int j=0;j<n_;j++) {
378 int tid_ = tid_map_[j];
379 recvcount[tid_] += 1;
382 std::vector<int> displs(ntasks_, 0);
383 for(
int rank = 1; rank < ntasks_; rank++) {
384 displs[rank] = displs[rank - 1] + recvcount[rank - 1];
387 for(
int rank = 0; rank < ntasks_; rank++) {
388 recvcount[rank] *= element_size;
389 displs[rank] *= element_size;
395 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, data_,
396 recvcount.data(), displs.data(), MPI_INT, MPI_COMM_WORLD);
399 #endif // CNTR_USE_MPI std::vector< int > tid_map(void) const
int firstblock_rank(void)
Return first blocks on rank.
void clear(void)
Clear all data
void mpi_bcast_block(int j)
MPI broadcast of j-th block
distributed_array & operator=(const distributed_array &g)
T * block(int j)
Returns the pointer to block j.
Auxiliary data structure for handling set of data blocks and includes usual MPI processes on them...
void mpi_bcast_all(void)
MPI Allgather equivalent for the distributed array
int numblock_rank(void)
Return number of blocks on rank.
int blocksize(void) const
void reset_blocksize(int blocksize)
Reset the block size for each block.
void mpi_send_block(int j, int dest)
Sends the j-th block to the MPI rank dest