00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
#include "PLMPI.h"
00041
#include "string.h"
00042
#include <plearn/base/plerror.h>
00043
#include <stdio.h>
00044
00045
namespace PLearn {
00046
using namespace std;
00047
00048
00049 streambuf* PLMPI::new_cin_buf = 0;
00050
00051
#if USING_MPI
00052
bool PLMPI::using_mpi =
true;
00053
#else
00054 bool PLMPI::using_mpi =
false;
00055
#endif
00056
00057 bool PLMPI::synchronized =
true;
00058
00059 int PLMPI::size = 0;
00060 int PLMPI::rank = 0;
00061
00062 PStream PLMPI::mycout;
00063 PStream PLMPI::mycerr;
00064 PStream PLMPI::mycin;
00065
00066 int PLMPI::tag = 2909;
00067
00068 void PLMPI::exchangeBlocks(
double* data,
int n,
int blocksize,
double* buffer)
00069 {
00070
00071
int blockstart = PLMPI::rank*blocksize;
00072
00073
int theblocksize = blocksize;
00074
int diff=n-blockstart;
00075
if (blocksize>diff) theblocksize=diff;
00076
if (theblocksize<=0)
00077
PLERROR(
"PLMPI::exchangeBlocks with block of size %d (b=%d,n=%d,r=%d,N=%d)",
00078 theblocksize,blocksize,n,PLMPI::rank,PLMPI::size);
00079
00080
if (blocksize*PLMPI::size==n && buffer)
00081 {
00082 memcpy(buffer,&data[blockstart],theblocksize*
sizeof(
double));
00083
#if USING_MPI
00084
MPI_Allgather(buffer,blocksize,MPI_DOUBLE,
00085 data,blocksize,MPI_DOUBLE,MPI_COMM_WORLD);
00086
#endif
00087
}
00088
else
00089 {
00090
for (
int i=0;i<PLMPI::size;i++)
00091 {
00092
int bstart = i*blocksize;
00093 diff = n-bstart;
00094
int bsize = blocksize;
00095
if (bsize>diff) bsize=diff;
00096
00097
00098
00099
00100
00101
00102
#if USING_MPI
00103
MPI_Bcast(&data[bstart],bsize,MPI_DOUBLE,i,MPI_COMM_WORLD);
00104
#endif
00105
00106 }
00107 }
00108
00109 }
00110
00111 void PLMPI::exchangeBlocks(
float* data,
int n,
int blocksize,
float* buffer)
00112 {
00113
00114
int blockstart = PLMPI::rank*blocksize;
00115
00116
int theblocksize = blocksize;
00117
int diff=n-blockstart;
00118
if (blocksize>diff) theblocksize=diff;
00119
if (theblocksize<=0)
00120
PLERROR(
"PLMPI::exchangeBlocks with block of size %d (b=%d,n=%d,r=%d,N=%d)",
00121 theblocksize,blocksize,n,PLMPI::rank,PLMPI::size);
00122
00123
if (blocksize*PLMPI::size==n && buffer)
00124 {
00125 memcpy(buffer,&data[blockstart],theblocksize*
sizeof(
float));
00126
#if USING_MPI
00127
MPI_Allgather(buffer,blocksize,MPI_FLOAT,
00128 data,blocksize,MPI_FLOAT,MPI_COMM_WORLD);
00129
#endif
00130
}
00131
else
00132 {
00133
for (
int i=0;i<PLMPI::size;i++)
00134 {
00135
int bstart = i*blocksize;
00136 diff = n-bstart;
00137
int bsize = blocksize;
00138
if (bsize>diff) bsize=diff;
00139
00140
00141
00142
00143
00144
00145
#if USING_MPI
00146
MPI_Bcast(&data[bstart],bsize,MPI_FLOAT,i,MPI_COMM_WORLD);
00147
#endif
00148
00149 }
00150 }
00151
00152 }
00153
00154 void PLMPI::exchangeColumnBlocks(
Mat sourceBlock,
Mat destBlocks)
00155 {
00156
#if USING_MPI
00157
int width = sourceBlock.
width();
00158
int length = sourceBlock.
length();
00159
00160
int total_width = destBlocks.
width();
00161
00162
if (total_width%PLMPI::size == 0)
00163 {
00164
for (
int i=0; i<length; i++)
00165 {
00166 MPI_Allgather(sourceBlock[i],width,PLMPI_REAL,
00167 destBlocks[i],width,PLMPI_REAL,MPI_COMM_WORLD);
00168 }
00169 }
00170
else
00171 {
00172
int size_minus_one = PLMPI::size-1;
00173
int* counts = (
int*)malloc(
sizeof(
int)*PLMPI::size);
00174
int* displs = (
int*)malloc(
sizeof(
int)*PLMPI::size);
00175
int* ptr_counts = counts;
00176
int* ptr_displs = displs;
00177
int norm_width = total_width / PLMPI::size + 1;
00178
int last_width = total_width - norm_width*size_minus_one;
00179
if (last_width<=0)
00180
PLERROR(
"In PLMPI::exchangeColumnsBlocks: unproper choice of processes (%d) for matrix width (%d) leads "
00181
"to width = %d for first mats and width = %d for last mat.",PLMPI::size,total_width,norm_width,last_width);
00182
00183
if (PLMPI::rank==size_minus_one)
00184 {
00185
if (width!=last_width)
00186
PLERROR(
"In PLMPI::exchangeColumnsBlocks: width of last block is %d, should be %d.",width,last_width);
00187 }
00188
else
00189
if (width!=norm_width)
00190
PLERROR(
"In PLMPI::exchangeColumnsBlocks: width of block %d is %d, should be %d.",PLMPI::rank,width,last_width);
00191
for (
int i=0;i<size_minus_one;i++)
00192 {
00193 *ptr_counts++ = norm_width;
00194 *ptr_displs++ = norm_width*i;
00195 }
00196
00197 *ptr_counts = last_width;
00198 *ptr_displs = norm_width*size_minus_one;
00199
for (
int i=0; i<length; i++)
00200 {
00201 MPI_Allgatherv(sourceBlock[i],width,PLMPI_REAL,
00202 destBlocks[i],counts,displs,PLMPI_REAL,MPI_COMM_WORLD);
00203 }
00204 free(counts);
00205 free(displs);
00206 }
00207
#else
00208
PLWARNING(
"PLMPI::exchangeColumnsBlocks: in order to use this function, you should recompile with the flag USING_MPI set to 1.");
00209
#endif
00210
}
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 }