mirror of https://github.com/QMCPACK/qmcpack.git
284 lines
6.8 KiB
C++
284 lines
6.8 KiB
C++
#if COMPILATION_INSTRUCTIONS
|
|
OMPI_CXX=$CXX mpicxx $CXXFLAGS -I$HOME/prj/alf/boost $0 -o $0x -lboost_serialization&&mpirun -n 2 $0x&&rm $0x;exit
|
|
#endif
|
|
|
|
#include<complex>
|
|
|
|
#include "mpi3/main_environment.hpp"
|
|
#include "mpi3/process.hpp"
|
|
|
|
#include "../array.hpp"
|
|
|
|
namespace mpi3 = boost::mpi3;
|
|
namespace multi = boost::multi;
|
|
|
|
void test_1D(mpi3::communicator& comm){
|
|
|
|
auto const rank = comm.rank();
|
|
switch(rank){
|
|
case 0:
|
|
multi::array<double, 1> v(100);
|
|
std::iota(v.begin(), v.end(), 0.0);
|
|
assert( v.strided(2).size() == 50 and v.strided(2)[9] == 18 );
|
|
comm.send(v.strided(2).begin(), v.strided(2).end(), 1);
|
|
break;
|
|
case 1:
|
|
multi::array<double, 1> w(50);
|
|
comm.receive(w.begin(), w.end(), 0);
|
|
assert( w[9] == 18 );
|
|
break;
|
|
default: assert(0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void test_2D(mpi3::communicator& comm){
|
|
|
|
auto const v = std::invoke([] {
|
|
multi::array<double, 2> v({4, 5});
|
|
std::iota(begin(v.elements()), end(v.elements()), 0.0);
|
|
return v;
|
|
});
|
|
|
|
auto&& vpart = v({1, 4}, {1, 3});
|
|
switch(comm.rank()) {
|
|
case 0:
|
|
comm.send(begin(vpart), end(vpart), 1);
|
|
return;
|
|
case 1:
|
|
multi::array<double, 2> w(extensions(vpart), 99.0);
|
|
comm.receive(begin(w), end(w), 0);
|
|
assert( w == vpart );
|
|
return;
|
|
}
|
|
assert(0);
|
|
|
|
}
|
|
|
|
void test_2D_complex(mpi3::communicator& comm){
|
|
using complex = std::complex<double>;
|
|
|
|
multi::array<complex, 2> v({4, 5}); using std::get;
|
|
if(auto const x = v.extensions()) {
|
|
auto const [is, js] = x;
|
|
for(auto i: is) {
|
|
for(auto j: js) {
|
|
v[i][j] = complex(i, j);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch(comm.rank()) {
|
|
case 0:
|
|
comm.send(begin(v), end(v), 1);
|
|
break;
|
|
case 1:
|
|
multi::array<complex, 2> w(extensions(v), 99.0);
|
|
comm.receive(begin(w), end(w), 0);
|
|
assert( w[2][3] == std::complex<double>(2.0, 3.0) );
|
|
break;
|
|
default: assert(0);
|
|
}
|
|
}
|
|
|
|
void test_3D(mpi3::communicator& comm){
|
|
|
|
auto const v = std::invoke([]{
|
|
multi::array<double, 3> v({4, 5, 7});
|
|
std::iota(begin(v.elements()), end(v.elements()), 0.0);
|
|
return v;
|
|
});
|
|
|
|
auto&& vpart = v({1, 4}, {1, 3}, {3, 6});
|
|
|
|
switch(comm.rank()){
|
|
case 0:
|
|
comm.send(begin(vpart), end(vpart), 1);
|
|
return;
|
|
case 1:
|
|
multi::array<double, 3> w(extensions(vpart), 99.0);
|
|
comm.receive(begin(w), end(w), 0); assert( w == vpart );
|
|
return;
|
|
}
|
|
assert(0);
|
|
}
|
|
|
|
void test_2D_strides(mpi3::communicator& comm){
|
|
|
|
multi::array<double, 2> v({4, 5});
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
|
|
std::cout << std::endl;
|
|
switch(comm.rank()) {
|
|
case 0:
|
|
comm.send_n(v({1, 3}, {2, 4}).begin(), v({1, 3}, {2, 4}).size(), 1);
|
|
return;
|
|
case 1:
|
|
multi::array<double, 2> w({4, 5}, 99.0);
|
|
comm.receive(w({1, 3}, {2, 4}).begin(), w({1, 3}, {2, 4}).end(), 0);
|
|
assert( w({1, 3}, {2, 4}) == v({1, 3}, {2, 4}) );
|
|
return;
|
|
}
|
|
assert(0);
|
|
}
|
|
|
|
/*
|
|
void test_3D(mpi3::communicator& comm){
|
|
|
|
switch(comm.rank()){
|
|
case 0:{
|
|
multi::array<double, 3> v({4, 5, 6});
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.);
|
|
comm.send_n(v.begin(), v.size(), 1);
|
|
return;
|
|
}
|
|
case 1:{
|
|
multi::array<double, 3> v({4, 5, 6});
|
|
comm.receive_n(v.begin(), v.size(), 0);
|
|
for(auto const& e : v.elements()) std::cout<< e <<',';
|
|
std::cout<<std::endl;
|
|
// for(auto&& row: v){for(auto&& e: row) std::cout<< e <<','; std::cout<<std::endl;}
|
|
return;
|
|
}
|
|
}
|
|
assert(0);
|
|
|
|
}
|
|
*/
|
|
|
|
void test_vector_nonpod(mpi3::communicator& comm) {
|
|
std::vector<std::string> v(10);
|
|
|
|
if(comm.rank() == 0) {
|
|
v[2] = "hola";
|
|
comm.send_n(v.begin(), v.size(), 1);
|
|
} else if(comm.rank() == 1) {
|
|
comm.receive_n(v.begin(), v.size(), 0);
|
|
assert( v[2] == "hola" );
|
|
} else { assert(0); }
|
|
|
|
return;
|
|
}
|
|
|
|
int mpi3::main(int, char*[], mpi3::environment& env) {
|
|
|
|
auto world = env.world();
|
|
|
|
test_1D(world);
|
|
test_2D_strides(world);
|
|
test_2D(world);
|
|
test_2D_complex(world);
|
|
test_3D(world);
|
|
|
|
{
|
|
auto self = env.get_self_instance();
|
|
auto const v = std::invoke({
|
|
multi::array<double, 2> v({4, 5});
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
return v;
|
|
});
|
|
multi::array<double, 2> w({4, 2}, 0.0);
|
|
|
|
self.gather_n(v({0, 4}, {2, 4}).begin(), v({0, 4}, {2, 4}).size(), w.begin());
|
|
|
|
using std::cout; using std::endl;
|
|
std::cout<<"v()="<<std::endl;
|
|
for(auto&& r: v){for(auto&& e: r) cout<< e <<'\t'; cout<<endl;}
|
|
|
|
auto vv = v({0, 4}, {2, 4}).decay();
|
|
std::cout<<"vv()="<<std::endl;
|
|
for(auto&& r: vv){for(auto&& e: r) cout<< e <<'\t'; cout<<endl;}
|
|
|
|
std::cout<<"w="<<std::endl;
|
|
for(auto&& r : w){for(auto&& e: r) cout<< e <<'\t'; cout<<endl;}
|
|
std::cout<<std::endl;
|
|
}
|
|
{
|
|
auto self = env.get_self_instance();
|
|
auto const v = []{
|
|
multi::array<double, 2> v({4, 5});
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
return v;
|
|
}();
|
|
multi::array<double, 2> w({5, 4}, 0.0);
|
|
self.gather_n(v.rotated().begin(), v.rotated().size(), w.begin());
|
|
assert( v.rotated() == w );
|
|
}
|
|
|
|
multi::array<double, 1> v(100);
|
|
{
|
|
mpi3::type t(v.begin());
|
|
assert( t.size() == sizeof(double) );
|
|
assert( t.extent() == sizeof(double) );
|
|
}
|
|
{
|
|
assert( v.strided(2).size() == 50 );
|
|
mpi3::type t(v.strided(2).begin());
|
|
assert( t.size() == sizeof(double) );
|
|
assert( t.extent() == sizeof(double)*2 );
|
|
}
|
|
{
|
|
auto self = env.get_self_instance();
|
|
multi::array<double, 1> v(10);
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
multi::array<double, 1> w(10);
|
|
self.gather_n(v.begin(), v.size(), w.begin());
|
|
assert( w == v );
|
|
}
|
|
{
|
|
auto self = env.get_self_instance();
|
|
auto const v = std::invoke([] {
|
|
multi::array<double, 1> v(60);
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
return v;
|
|
});
|
|
multi::array<double, 1> w(30);
|
|
assert( v.strided(2).size() == 30 );
|
|
|
|
self.gather_n(v.strided(2).begin(), v.strided(2).size(), w.data_elements());
|
|
assert( v.strided(2) == w );
|
|
}
|
|
{
|
|
auto self = env.get_self_instance();
|
|
auto const v = std::invoke([] {
|
|
multi::array<double, 1> v(30);
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
return v;
|
|
});
|
|
multi::array<double, 1> w(10);
|
|
self.gather_n(v({10, 30}).strided(2).begin(), v({10, 30}).strided(2).size(), w.data_elements());
|
|
assert( v({10, 30}).strided(2) == w );
|
|
}
|
|
{
|
|
auto self = env.get_self_instance();
|
|
auto const v = std::invoke([] {
|
|
multi::array<double, 2> v({4, 5});
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
return v;
|
|
});
|
|
multi::array<double, 2> w({2, 5}, 0.0);
|
|
|
|
self.gather_n(v.strided(2).begin(), v.strided(2).size(), w.begin());
|
|
|
|
assert( v.strided(2) == w );
|
|
}
|
|
{
|
|
auto self = env.get_self_instance();
|
|
auto const v = std::invoke([] {
|
|
multi::array<double, 3> v({6, 4, 5});
|
|
std::iota(v.elements().begin(), v.elements().end(), 0.0);
|
|
return v;
|
|
});
|
|
multi::array<double, 3> w({3, 4, 5}, 0.0);
|
|
|
|
for(auto const& e : v.elements()) std::cout<< e <<',';
|
|
std::cout << std::endl;
|
|
|
|
self.gather_n(v.strided(2).begin(), v.strided(2).size(), w.begin());
|
|
|
|
assert( v.strided(2) == w );
|
|
}
|
|
|
|
return 0;
|
|
}
|