22 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
23 int my_num = a_data.size();
27 amrex::ParallelAllReduce::Sum(num, MPI_COMM_WORLD);
29 std::vector<T> a_data_all(num);
31 std::vector<int> nsites_procs(nprocs);
32 MPI_Allgather(&my_num, 1, amrex::ParallelDescriptor::Mpi_typemap<int>::type(),
33 nsites_procs.data(), 1, amrex::ParallelDescriptor::Mpi_typemap<int>::type(),
36 std::vector<int> nsites_disp(nprocs);
37 for (
int i = 0; i < nprocs; i++)
40 for (
int j = 0; j < i; j++) nsites_disp[i] += nsites_procs[j];
43 MPI_Datatype mpi_type = amrex::ParallelDescriptor::Mpi_typemap<T>::type();
45 a_data.data(), my_num, mpi_type,
46 a_data_all.data(), nsites_procs.data(), nsites_disp.data(), mpi_type,
49 a_data.swap(a_data_all);
54inline void Bcast( std::string &s,
55 int root = amrex::ParallelDescriptor::IOProcessorNumber())
57 using namespace amrex;
59 int me = ParallelDescriptor::MyProc();
62 int len = (me == root) ?
static_cast<int>(s.size()) : 0;
63 ParallelDescriptor::Bcast(&len, 1, root);
71 ParallelDescriptor::Bcast(s.data(), len, root);
79 std::vector<std::string> &out)
81 using namespace amrex;
83 int nprocs = ParallelDescriptor::NProcs();
84 int me = ParallelDescriptor::MyProc();
87 int local_len =
static_cast<int>(local.size());
88 std::vector<int> lengths(nprocs);
90 for (
int p = 0; p < nprocs; ++p) {
91 int len = (me == p) ? local_len : 0;
92 ParallelDescriptor::Bcast(&len, 1, p);
97 std::vector<int> offsets(nprocs, 0);
98 int total_len = lengths[0];
99 for (
int i = 1; i < nprocs; ++i) {
100 offsets[i] = offsets[i-1] + lengths[i-1];
101 total_len += lengths[i];
105 std::vector<char> local_buf(local_len);
107 std::memcpy(local_buf.data(), local.data(), local_len);
110 std::vector<char> all_buf(total_len);
111 for (
int p = 0; p < nprocs; ++p) {
112 int len = lengths[p];
116 std::memcpy(all_buf.data() + offsets[p], local_buf.data(), len);
119 ParallelDescriptor::Bcast(all_buf.data() + offsets[p], len, p);
124 for (
int i = 0; i < nprocs; ++i) {
125 out[i] = std::string(all_buf.data() + offsets[i], lengths[i]);