diff --git a/example/cartesian_communicator.cpp b/example/cartesian_communicator.cpp index cff2428..e06f150 100644 --- a/example/cartesian_communicator.cpp +++ b/example/cartesian_communicator.cpp @@ -16,13 +16,20 @@ #include namespace mpi = boost::mpi; +// Curly brace init make this useless, but +// - Need to support obsolete like g++ 4.3.x. for some reason +// - Can't conditionnaly compile with bjam (unless you find +// the doc, and read it, which would only make sense if you +// actually wan't to use bjam, which does not (make sense)) +typedef mpi::cartesian_dimension cd; + int test_main(int argc, char* argv[]) { mpi::environment env; mpi::communicator world; if (world.size() != 24) return -1; - mpi::cartesian_dimension dims[] = {{2, true}, {3,true}, {4,true}}; + mpi::cartesian_dimension dims[] = {cd(2, true), cd(3,true), cd(4,true)}; mpi::cartesian_communicator cart(world, mpi::cartesian_topology(dims)); for (int r = 0; r < cart.size(); ++r) { cart.barrier(); diff --git a/include/boost/mpi/collectives/all_gather.hpp b/include/boost/mpi/collectives/all_gather.hpp index cd467a9..4adaeb9 100644 --- a/include/boost/mpi/collectives/all_gather.hpp +++ b/include/boost/mpi/collectives/all_gather.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include namespace boost { namespace mpi { @@ -57,7 +58,7 @@ all_gather_impl(const communicator& comm, const T* in_values, int n, int oasize = oa.size(); BOOST_MPI_CHECK_RESULT(MPI_Allgather, (&oasize, 1, MPI_INTEGER, - oasizes.data(), 1, MPI_INTEGER, + c_data(oasizes), 1, MPI_INTEGER, MPI_Comm(comm))); // Gather the archives, which can be of different sizes, so // we need to use allgatherv. @@ -68,7 +69,7 @@ all_gather_impl(const communicator& comm, const T* in_values, int n, packed_iarchive::buffer_type recv_buffer(std::accumulate(oasizes.begin(), oasizes.end(), 0)); BOOST_MPI_CHECK_RESULT(MPI_Allgatherv, (const_cast(oa.address()), int(oa.size()), MPI_BYTE, - recv_buffer.data(), oasizes.data(), offsets.data(), MPI_BYTE, + c_data(recv_buffer), c_data(oasizes), c_data(offsets), MPI_BYTE, MPI_Comm(comm))); for (int src = 0; src < nproc; ++src) { int nb = sizes ? sizes[src] : n; @@ -110,8 +111,9 @@ template void all_gather(const communicator& comm, const T& in_value, std::vector& out_values) { + using detail::c_data; out_values.resize(comm.size()); - ::boost::mpi::all_gather(comm, in_value, out_values.data()); + ::boost::mpi::all_gather(comm, in_value, c_data(out_values)); } template @@ -125,8 +127,9 @@ template void all_gather(const communicator& comm, const T* in_values, int n, std::vector& out_values) { + using detail::c_data; out_values.resize(comm.size() * n); - ::boost::mpi::all_gather(comm, in_values, n, out_values.data()); + ::boost::mpi::all_gather(comm, in_values, n, c_data(out_values)); } } } // end namespace boost::mpi diff --git a/include/boost/mpi/collectives/all_gatherv.hpp b/include/boost/mpi/collectives/all_gatherv.hpp index d62cc7b..064412f 100644 --- a/include/boost/mpi/collectives/all_gatherv.hpp +++ b/include/boost/mpi/collectives/all_gatherv.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -68,9 +69,10 @@ void all_gatherv(const communicator& comm, const T& in_value, T* out_values, const std::vector& sizes) { + using detail::c_data; assert(sizes.size() == comm.size()); assert(sizes[comm.rank()] == 1); - detail::all_gatherv_impl(comm, &in_value, out_values, sizes.data(), 0, is_mpi_datatype()); + detail::all_gatherv_impl(comm, &in_value, out_values, c_data(sizes), 0, is_mpi_datatype()); } template @@ -78,8 +80,9 @@ void all_gatherv(const communicator& comm, const T* in_values, T* out_values, const std::vector& sizes) { + using detail::c_data; assert(int(sizes.size()) == comm.size()); - detail::all_gatherv_impl(comm, in_values, out_values, sizes.data(), 0, is_mpi_datatype()); + detail::all_gatherv_impl(comm, in_values, out_values, c_data(sizes), 0, is_mpi_datatype()); } template @@ -87,10 +90,11 @@ void all_gatherv(const communicator& comm, std::vector const& in_values, std::vector& out_values, const std::vector& sizes) { + using detail::c_data; assert(int(sizes.size()) == comm.size()); assert(int(in_values.size()) == sizes[comm.rank()]); out_values.resize(std::accumulate(sizes.begin(), sizes.end(), 0)); - ::boost::mpi::all_gatherv(comm, in_values.data(), out_values.data(), sizes); + ::boost::mpi::all_gatherv(comm, c_data(in_values), c_data(out_values), sizes); } @@ -99,10 +103,11 @@ void all_gatherv(const communicator& comm, const T& in_value, T* out_values, const std::vector& sizes, const std::vector& displs) { + using detail::c_data; assert(sizes.size() == comm.size()); assert(displs.size() == comm.size()); detail::all_gatherv_impl(comm, &in_value, 1, out_values, - sizes.data(), displs.data(), is_mpi_datatype()); + c_data(sizes), c_data(displs), is_mpi_datatype()); } template @@ -110,10 +115,11 @@ void all_gatherv(const communicator& comm, const T* in_values, T* out_values, const std::vector& sizes, const std::vector& displs) { + using detail::c_data; assert(sizes.size() == comm.size()); assert(displs.size() == comm.size()); detail::all_gatherv_impl(comm, in_values, out_values, - sizes.data(), displs.data(), is_mpi_datatype()); + c_data(sizes), c_data(displs), is_mpi_datatype()); } template @@ -121,11 +127,12 @@ void all_gatherv(const communicator& comm, std::vector const& in_values, std::vector& out_values, const std::vector& sizes, const std::vector& displs) { + using detail::c_data; assert(sizes.size() == comm.size()); assert(displs.size() == comm.size()); assert(in_values.size() == sizes[comm.rank()]); out_values.resize(std::accumulate(sizes.begin(), sizes.end(), 0)); - ::boost::mpi::all_gatherv(comm, in_values.data(), out_values.data(), sizes, displs); + ::boost::mpi::all_gatherv(comm, c_data(in_values), c_data(out_values), sizes, displs); } } } // end namespace boost::mpi diff --git a/include/boost/mpi/collectives/gather.hpp b/include/boost/mpi/collectives/gather.hpp index 6ebfda5..386bfdd 100644 --- a/include/boost/mpi/collectives/gather.hpp +++ b/include/boost/mpi/collectives/gather.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include namespace boost { namespace mpi { @@ -69,7 +70,7 @@ gather_impl(const communicator& comm, const T* in_values, int n, T* out_values, int oasize = oa.size(); BOOST_MPI_CHECK_RESULT(MPI_Gather, (&oasize, 1, MPI_INTEGER, - oasizes.data(), 1, MPI_INTEGER, + c_data(oasizes), 1, MPI_INTEGER, root, MPI_Comm(comm))); // Gather the archives, which can be of different sizes, so // we need to use gatherv. @@ -80,7 +81,7 @@ gather_impl(const communicator& comm, const T* in_values, int n, T* out_values, packed_iarchive::buffer_type recv_buffer(is_root ? std::accumulate(oasizes.begin(), oasizes.end(), 0) : 0); BOOST_MPI_CHECK_RESULT(MPI_Gatherv, (const_cast(oa.address()), int(oa.size()), MPI_BYTE, - recv_buffer.data(), oasizes.data(), offsets.data(), MPI_BYTE, + c_data(recv_buffer), c_data(oasizes), c_data(offsets), MPI_BYTE, root, MPI_Comm(comm))); if (is_root) { for (int src = 0; src < nproc; ++src) { @@ -135,10 +136,11 @@ void gather(const communicator& comm, const T& in_value, std::vector& out_values, int root) { + using detail::c_data; if (comm.rank() == root) { out_values.resize(comm.size()); } - ::boost::mpi::gather(comm, in_value, out_values.data(), root); + ::boost::mpi::gather(comm, in_value, c_data(out_values), root); } template diff --git a/include/boost/mpi/collectives/scatter.hpp b/include/boost/mpi/collectives/scatter.hpp index 2645612..0c91b1e 100644 --- a/include/boost/mpi/collectives/scatter.hpp +++ b/include/boost/mpi/collectives/scatter.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace boost { namespace mpi { @@ -83,8 +84,8 @@ fill_scatter_sendbuf(const communicator& comm, T const* values, template T* non_const_data(std::vector const& v) { - T const* cptr = v.data(); - return const_cast(cptr); + using detail::c_data; + return const_cast(c_data(v)); } // Dispatch the sendbuf among proc. @@ -109,8 +110,8 @@ dispatch_scatter_sendbuf(const communicator& comm, packed_iarchive::buffer_type recvbuf; recvbuf.resize(myarchsize); BOOST_MPI_CHECK_RESULT(MPI_Scatterv, - (non_const_data(sendbuf), non_const_data(archsizes), offsets.data(), MPI_BYTE, - recvbuf.data(), recvbuf.size(), MPI_BYTE, + (non_const_data(sendbuf), non_const_data(archsizes), c_data(offsets), MPI_BYTE, + c_data(recvbuf), recvbuf.size(), MPI_BYTE, root, MPI_Comm(comm))); // Unserialize if ( in_values != 0 && root == comm.rank()) { @@ -137,7 +138,7 @@ scatter_impl(const communicator& comm, const T* in_values, T* out_values, if (root == comm.rank()) { std::vector nslots(comm.size(), n); - fill_scatter_sendbuf(comm, in_values, nslots.data(), (int const*)0, sendbuf, archsizes); + fill_scatter_sendbuf(comm, in_values, c_data(nslots), (int const*)0, sendbuf, archsizes); } dispatch_scatter_sendbuf(comm, sendbuf, archsizes, in_values, out_values, n, root); } @@ -163,7 +164,8 @@ void scatter(const communicator& comm, const std::vector& in_values, T& out_value, int root) { - ::boost::mpi::scatter(comm, in_values.data(), out_value, root); + using detail::c_data; + ::boost::mpi::scatter(comm, c_data(in_values), out_value, root); } template diff --git a/include/boost/mpi/collectives/scatterv.hpp b/include/boost/mpi/collectives/scatterv.hpp index eb9f41d..57e073c 100644 --- a/include/boost/mpi/collectives/scatterv.hpp +++ b/include/boost/mpi/collectives/scatterv.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace boost { namespace mpi { @@ -71,8 +72,8 @@ scatterv_impl(const communicator& comm, const T* in_values, T* out_values, int o std::vector skipped; if (displs) { skipped.resize(nproc); - offsets2skipped(sizes, displs, skipped.data(), nproc); - displs = skipped.data(); + offsets2skipped(sizes, displs, c_data(skipped), nproc); + displs = c_data(skipped); } fill_scatter_sendbuf(comm, in_values, sizes, (int const*)0, sendbuf, archsizes); } @@ -99,7 +100,8 @@ scatterv(const communicator& comm, const T* in_values, const std::vector& sizes, const std::vector& displs, T* out_values, int out_size, int root) { - scatterv_impl(comm, in_values, out_values, out_size, sizes.data(), displs.data(), + using detail::c_data; + scatterv_impl(comm, in_values, out_values, out_size, c_data(sizes), c_data(displs), root, is_mpi_datatype()); } @@ -109,7 +111,8 @@ scatterv(const communicator& comm, const std::vector& in_values, const std::vector& sizes, const std::vector& displs, T* out_values, int out_size, int root) { - ::boost::mpi::scatterv(comm, in_values.data(), sizes, displs, + using detail::c_data; + ::boost::mpi::scatterv(comm, c_data(in_values), sizes, displs, out_values, out_size, root); } @@ -128,8 +131,9 @@ void scatterv(const communicator& comm, const T* in_values, const std::vector& sizes, T* out_values, int root) { + using detail::c_data; detail::scatterv_impl(comm, in_values, out_values, sizes[comm.rank()], - sizes.data(), (int const*)0, + c_data(sizes), (int const*)0, root, is_mpi_datatype()); } diff --git a/include/boost/mpi/detail/antiques.hpp b/include/boost/mpi/detail/antiques.hpp index 6ece779..409905f 100644 --- a/include/boost/mpi/detail/antiques.hpp +++ b/include/boost/mpi/detail/antiques.hpp @@ -13,16 +13,16 @@ // Support for some obsolette compilers namespace boost { namespace mpi { - namespace detail { - // Some old gnu compiler have no support for vector<>::data - // Use this in the mean time, the cumbersome syntax should - // serve as an incentive to get rid of this when those compilers - // are dropped. - template - T* c_data(std::vector& v) { return &(v[0]); } +namespace detail { + // Some old gnu compiler have no support for vector<>::data + // Use this in the mean time, the cumbersome syntax should + // serve as an incentive to get rid of this when those compilers + // are dropped. + template + T* c_data(std::vector& v) { return &(v[0]); } - template - T const* c_data(std::vector const& v) { return &(v[0]); } + template + T const* c_data(std::vector const& v) { return &(v[0]); } } } } diff --git a/src/cartesian_communicator.cpp b/src/cartesian_communicator.cpp index ad3178c..a46f0bc 100644 --- a/src/cartesian_communicator.cpp +++ b/src/cartesian_communicator.cpp @@ -13,6 +13,11 @@ namespace boost { namespace mpi { +namespace { + template + T* c_data(std::vector& v) { return &(v[0]); } +} + std::ostream& operator<<(std::ostream& out, cartesian_dimension const& d) { out << '(' << d.size << ','; @@ -57,8 +62,8 @@ cartesian_communicator::cartesian_communicator(const communicator& comm, } MPI_Comm newcomm; BOOST_MPI_CHECK_RESULT(MPI_Cart_create, - ((MPI_Comm)comm, dims.size(), - dims.data(), periodic.data(), + ((MPI_Comm)comm, dims.size(), + c_data(dims), c_data(periodic), int(reorder), &newcomm)); if(newcomm != MPI_COMM_NULL) { comm_ptr.reset(new MPI_Comm(newcomm), comm_free()); @@ -80,7 +85,7 @@ cartesian_communicator::cartesian_communicator(const cartesian_communicator& com MPI_Comm newcomm; BOOST_MPI_CHECK_RESULT(MPI_Cart_sub, - ((MPI_Comm)comm, bitset.data(), &newcomm)); + ((MPI_Comm)comm, c_data(bitset), &newcomm)); if(newcomm != MPI_COMM_NULL) { comm_ptr.reset(new MPI_Comm(newcomm), comm_free()); } @@ -99,7 +104,7 @@ cartesian_communicator::rank(const std::vector& coords ) const { int r = -1; assert(int(coords.size()) == ndims()); BOOST_MPI_CHECK_RESULT(MPI_Cart_rank, - (MPI_Comm(*this), const_cast&>(coords).data(), + (MPI_Comm(*this), c_data(const_cast&>(coords)), &r)); return r; } @@ -117,7 +122,7 @@ std::vector cartesian_communicator::coordinates(int rk) const { std::vector cbuf(ndims()); BOOST_MPI_CHECK_RESULT(MPI_Cart_coords, - (MPI_Comm(*this), rk, cbuf.size(), cbuf.data() )); + (MPI_Comm(*this), rk, cbuf.size(), c_data(cbuf) )); return cbuf; } @@ -130,7 +135,7 @@ cartesian_communicator::topology( cartesian_topology& topo, std::vector cdims(ndims); std::vector cperiods(ndims); BOOST_MPI_CHECK_RESULT(MPI_Cart_get, - (MPI_Comm(*this), ndims, cdims.data(), cperiods.data(), coords.data())); + (MPI_Comm(*this), ndims, c_data(cdims), c_data(cperiods), c_data(coords))); cartesian_topology res(cdims.begin(), cperiods.begin(), ndims); topo.swap(res); } @@ -167,7 +172,7 @@ cartesian_dimensions(int sz, std::vector& dims) { int leftover = sz % min; BOOST_MPI_CHECK_RESULT(MPI_Dims_create, - (sz-leftover, dims.size(), dims.data())); + (sz-leftover, dims.size(), c_data(dims))); return dims; } diff --git a/src/offsets.cpp b/src/offsets.cpp index 8080501..2382d45 100644 --- a/src/offsets.cpp +++ b/src/offsets.cpp @@ -6,6 +6,7 @@ // Authors: Alain Miniussi #include +#include namespace boost { namespace mpi { namespace detail { @@ -28,7 +29,7 @@ sizes2offsets(std::vector const& sizes, std::vector& offsets) { int sz = sizes.size(); offsets.resize(sz); - sizes2offsets(sizes.data(), offsets.data(), sz); + sizes2offsets(c_data(sizes), c_data(offsets), sz); } // Given a sequence of sizes (typically the number of records dispatched diff --git a/test/cartesian_topology_init_test.cpp b/test/cartesian_topology_init_test.cpp index acc7021..9da72ea 100644 --- a/test/cartesian_topology_init_test.cpp +++ b/test/cartesian_topology_init_test.cpp @@ -25,9 +25,12 @@ namespace mpi = boost::mpi; - BOOST_AUTO_TEST_CASE(cartesian_dimension_init) { + // Curly brace initialization syntax not supported on (very) old gnu + // This typedef keeps things shorter + typedef mpi::cartesian_dimension cd; + { // Check the basic ctor mpi::cartesian_dimension def; @@ -48,7 +51,7 @@ BOOST_AUTO_TEST_CASE(cartesian_dimension_init) // Container based ctor only available as a replacement for initializer list ctor { // seq ctor vs C array ctor - mpi::cartesian_dimension d[] = {{2,true},{3, false},{4, true}}; + mpi::cartesian_dimension d[] = {cd(2,true),cd(3, false),cd(4, true)}; std::list seq; std::copy(d, d+3, std::back_inserter(seq)); mpi::cartesian_topology t1(seq); @@ -57,7 +60,7 @@ BOOST_AUTO_TEST_CASE(cartesian_dimension_init) } { // Check range based with array based ctor. - boost::array d = {{{2,true},{3, false},{4, true}}}; + boost::array d = {{cd(2,true),cd(3, false),cd(4, true)}}; int dims[] = {2,3,4}; bool per[] = {true, false, true}; mpi::cartesian_topology t1(dims, per); @@ -67,7 +70,7 @@ BOOST_AUTO_TEST_CASE(cartesian_dimension_init) } { // Iterator based ctor vs C array based ctor - mpi::cartesian_dimension d[] = {{2,true},{3, false},{4, true}}; + mpi::cartesian_dimension d[] = {cd(2,true),cd(3, false),cd(4, true)}; std::vector vdims(d, d+3); mpi::cartesian_topology t1(vdims); mpi::cartesian_topology t2(d); diff --git a/test/cartesian_topology_test.cpp b/test/cartesian_topology_test.cpp index 8a21523..f19d72a 100644 --- a/test/cartesian_topology_test.cpp +++ b/test/cartesian_topology_test.cpp @@ -49,8 +49,8 @@ void test_coordinates_consistency( mpi::cartesian_communicator const& cc, for(int p = 0; p < cc.size(); ++p) { std::vector min(cc.ndims()); std::vector local(cc.coordinates(p)); - mpi::reduce(cc, local.data(), local.size(), - min.data(), mpi::minimum(), p); + mpi::reduce(cc, &local.front(), local.size(), + &(min[0]), mpi::minimum(), p); cc.barrier(); if (p == cc.rank()) { BOOST_CHECK(std::equal(coords.begin(), coords.end(), min.begin())); diff --git a/test/scatter_test.cpp b/test/scatter_test.cpp index 011a494..5e5ecd2 100644 --- a/test/scatter_test.cpp +++ b/test/scatter_test.cpp @@ -141,9 +141,9 @@ scatterv_test(const communicator& comm, Generator generator, std::cout << "Scatteringv " << kind << " from root " << root << "..." << std::endl; assert(mysize == sizes[comm.rank()]); - scatterv(comm, values, sizes, myvalues.data(), root); + scatterv(comm, values, sizes, &(myvalues[0]), root); } else { - scatterv(comm, myvalues.data(), mysize, root); + scatterv(comm, &(myvalues[0]), mysize, root); } for (int i = 0; i < mysize; ++i)