7 #ifndef cf3_common_PE_scatter_hpp
8 #define cf3_common_PE_scatter_hpp
71 T* out_buf=out_values;
72 if ((irank==root)&&(in_values==out_values)) {
77 MPI_CHECK_RESULT(MPI_Scatter, (const_cast<T*>(in_values), in_n*stride, type, out_buf, in_n*stride, type, root, comm));
80 if ((irank==root)&&(in_values==out_values)) {
81 memcpy(out_values,out_buf,nproc*in_n*stride*
sizeof(
T));
103 scattervm_impl(
const Communicator& comm,
const T* in_values,
const int* in_n,
const int* in_map,
T* out_values,
int& out_n,
const int *out_map,
const int root,
const int stride )
114 int *in_nstride=(
int*)0;
115 int *in_disp=(
int*)0;
120 in_nstride=
new int[nproc];
121 in_disp=
new int[nproc];
123 for(
int i=0; i<nproc-1; i++) {
124 in_nstride[i]=stride*in_n[i];
125 in_disp[i+1]=in_disp[i]+in_nstride[i];
127 in_nstride[nproc-1]=in_n[nproc-1]*stride;
128 in_sum=in_disp[nproc-1]+stride*in_n[nproc-1];
132 if (stride==1) {
for(
int i=0; i<in_sum; i++) in_buf[i]=in_values[in_map[i]]; }
133 else {
for(
int i=0; i<(
const int)(in_sum/stride); i++) memcpy(&in_buf[stride*i],&in_values[stride*in_map[i]],stride*
sizeof(
T)); }
135 in_buf=(
T*)in_values;
140 const int out_sum=stride*out_n;
141 const int out_nstride=stride*out_n;
145 if ((out_map!=0)||(in_values==out_values)) {
152 MPI_CHECK_RESULT(MPI_Scatterv, (in_buf, in_nstride, in_disp, type, out_buf, out_nstride, type, root, comm));
156 if (stride==1) {
for(
int i=0; i<out_sum; i++) out_values[out_map[i]]=out_buf[i]; }
157 else {
for(
int i=0; i<(
const int)(out_sum/stride); i++) memcpy(&out_values[stride*out_map[i]],&out_buf[stride*i],stride*
sizeof(
T)); }
159 }
else if (in_values==out_values) {
160 memcpy(out_values,out_buf,out_sum*
sizeof(
T));
165 if (irank==root)
if (in_map!=0)
delete[] in_buf;
195 T* out_buf=out_values;
197 const int size=stride*nproc*in_n>1?stride*nproc*in_n:1;
221 scatter(
const Communicator& comm,
const std::vector<T>& in_values, std::vector<T>& out_values,
const int root,
const int stride=1)
229 cf3_assert( in_values.size() % (nproc*stride) == 0 );
230 if (((in_values!=out_values)&&(irank!=root))||(out_values.size()==0)) {
231 out_values.resize(in_values.size()/nproc);
232 out_values.reserve(in_values.size()/nproc);
237 detail::scatterc_impl(comm, (
T*)(&in_values[0]), in_values.size()/(nproc*stride), (
T*)(&out_values[0]), root, stride);
244 out_values.resize(in_values.size()/nproc);
245 out_values.reserve(in_values.size()/nproc);
254 scatter(
const Communicator& comm,
const T* in_values,
const int *in_n,
const int *in_map,
T* out_values,
int& out_n,
const int *out_map,
const int root,
const int stride=1);
272 return scatter(comm,in_values,in_n,0,out_values,out_n,0,root,stride);
280 scatter(
const Communicator& comm,
const std::vector<T>& in_values,
const std::vector<int>& in_n,
const std::vector<int>& in_map, std::vector<T>& out_values,
int& out_n,
const std::vector<int>& out_map,
const int root,
const int stride=1);
296 scatter(
const Communicator& comm,
const std::vector<T>& in_values,
const std::vector<int>& in_n, std::vector<T>& out_values,
int& out_n,
const int root,
const int stride=1)
299 std::vector<int> in_map(0);
300 std::vector<int> out_map(0);
305 if ((irank==root)&&(&in_values[0]==&out_values[0]))
307 std::vector<T> out_tmp(0);
308 scatter(comm,in_values,in_n,in_map,out_tmp,out_n,out_map,root,stride);
309 out_values.assign(out_tmp.begin(),out_tmp.end());
313 scatter(comm,in_values,in_n,in_map,out_values,out_n,out_map,root,stride);
336 scatter(
const Communicator& comm,
const T* in_values,
const int *in_n,
const int *in_map,
T* out_values,
int& out_n,
const int *out_map,
const int root,
const int stride)
346 if (out_map!=0)
throw cf3::common::ParallelError(
FromHere(),
"Trying to perform communication with receive map while receive counts are unknown, this is bad usage of parallel environment.");
352 T* out_buf=out_values;
356 for (
int i=0; i<out_sum; i++) out_sum_tmp=out_map[i]>out_sum_tmp?out_map[i]:out_sum_tmp;
357 out_sum=out_sum_tmp+1;
390 scatter(
const Communicator& comm,
const std::vector<T>& in_values,
const std::vector<int>& in_n,
const std::vector<int>& in_map, std::vector<T>& out_values,
int& out_n,
const std::vector<int>& out_map,
const int root,
const int stride)
405 if (out_map.size()!=0)
throw cf3::common::ParallelError(
FromHere(),
"Trying to perform communication with receive map while receive counts are unknown, this is bad usage of parallel environment.");
411 if (out_values.size() == 0 ){
412 if (out_map.size()!=0) {
415 if (out_sum!=0) out_sum++;
417 out_values.resize(stride*out_sum);
418 out_values.reserve(stride*out_sum);
423 detail::scattervm_impl(comm, (
T*)(&in_values[0]), &in_n[0], (in_map.empty() ?
nullptr : &in_map[0]), (
T*)(&out_values[0]), out_n, (out_map.empty() ?
nullptr : &out_map[0]), root, stride);
425 detail::scattervm_impl(comm, (
T*)0, &in_n[0], (in_map.empty() ?
nullptr : &in_map[0]), (
T*)(&out_values[0]), out_n, (out_map.empty() ?
nullptr : &out_map[0]), root, stride);
437 #endif // cf3_common_PE_scatter_hpp
MPI_Datatype Datatype
datatype
Datatype get_mpi_datatype(const T &ref_of_type)
ACCESS AND REGISTRATION MECHANISM.
#define boost_foreach
lowercase version of BOOST_FOREACH
void scattervm_impl(const Communicator &comm, const T *in_values, const int *in_n, const int *in_map, T *out_values, int &out_n, const int *out_map, const int root, const int stride)
T * scatter(const Communicator &comm, const T *in_values, const int in_n, T *out_values, const int root, const int stride=1)
Top-level namespace for coolfluid.
void scatterc_impl(const Communicator &comm, const T *in_values, const int in_n, T *out_values, const int root, const int stride)
MPI_Comm Communicator
communicator
#define MPI_CHECK_RESULT(MPIFunc, Args)
Macro for checking return values of any mpi calls and throws exception on error.