gpt4 book ai didi

c++ - 如何通过Boost.MPI发送2d Boost.MultiArray的子​​数组?

转载 作者:行者123 更新时间:2023-12-02 10:02:07 25 4
gpt4 key购买 nike

我需要使用Boost.MPI发送对Boost.MultiArray的2d子数组的引用。
现在,我有以下代码:

matrix_type::array_view<2>::type
current_process_batch = matrix[boost::indices[range(bias, finish_line)][range(0, width)]];
world.send(rank, BEGIN_TAG, current_process_batch);


但是我也有以下错误试图执行它:
/usr/local/include/boost/serialization/access.hpp:116:11: error: no member named 'serialize' in 'boost::detail::multi_array::multi_array_view<double, 2>'
t.serialize(ar, file_version);

谁能帮助我将其发送到另一个进程?

最佳答案

您需要实现序列化。

这是一个通用的multi_array<T. Dims>序列化器:

namespace boost::serialization {
template <typename Ar, typename T, size_t Dims>
void save(Ar& ar, boost::multi_array<T, Dims> const& ma, unsigned /*version*/) {
std::array<int, Dims> shape;
std::copy_n(ma.shape(), Dims, shape.begin());
ar & make_nvp("shape", shape)
& make_nvp("data", make_array(ma.data(), ma.num_elements()));
}

template <typename Ar, typename T, size_t Dims>
void load(Ar& ar, boost::multi_array<T, Dims>& ma, unsigned /*version*/) {
std::array<int, Dims> shape;
ar & make_nvp("shape", shape);

ma.resize(shape);
ar & make_nvp("data", make_array(const_cast<T*>(ma.data()), ma.num_elements()));
}

template <typename Ar, typename T, size_t Dims>
void serialize(Ar& ar, boost::multi_array<T, Dims>& ma, unsigned version) {
split_free(ar, ma, version);
}
}

看到它 Live On Coliru
auto make_multi_array() {
boost::multi_array<int, 2> ma(boost::extents[7][4]);
std::iota(ma.data(), ma.data() + ma.num_elements(), 10);
return ma;
}

int main() {
auto const original = make_multi_array();

{
std::ofstream os("array.txt");
boost::archive::text_oarchive oa(os);

oa << original;
}

std::cout << std::ifstream("array.txt").rdbuf() << "\n";

{
std::ifstream is("array.txt");
boost::archive::text_iarchive ia(is);

boost::multi_array<int, 2> restored;
ia >> restored;

assert(restored == original);
}
}

版画
22 serialization::archive 17 0 0 0 0 2 7 4 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

更新: View

嗯已经接受了吗?后来才发现我实际上没有很好地理解您的问题。您想序列化 View 。你不能,真的。您不能“反序列化 View ”。

您最多可以执行 将 View 序列反序列化为

Note also that

  • serializing the whole array could be (much) more efficient if the size difference isn't huge

  • the view types are not public interface for the library, i.e. it may break in future versions of Boost. If in doubt, serialize the arrays themselves



这是更多的机器:
  • 添加了对detail::multi_array::multi_array_view<...>的支持,因为它可以反序列化INTO仅匹配形状的现有 View
  • 仅对序列化添加了对detail::multi_array::const_multi_array_view<...>的支持。出于明显的原因,只能将该 View 反序列化为非const View 。
  • 用一个 subview 扩展了该演示,该 subview 在序列化后修补了初始阵列,因此我们可以验证将修补程序读入还原后的阵列的等效 View 中是否具有与原始阵列相同的效果(检查修补程序是否创建了预期的功能之后)不匹配20 != 999)。

  • Live On Coliru
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/serialization/array.hpp>
    #include <boost/serialization/nvp.hpp>
    #include <boost/serialization/array_wrapper.hpp>
    #include <boost/multi_array.hpp>
    #include <iostream>
    #include <fstream>

    namespace boost::serialization {
    template <typename Ar, typename T, size_t Dims>
    void save(Ar& ar, boost::detail::multi_array::const_multi_array_view<T, Dims> const& ma, unsigned /*version*/) {
    std::array<int, Dims> shape;
    std::copy_n(ma.shape(), Dims, shape.begin());
    ar & make_nvp("shape", shape);

    for (auto i = 0; i < shape[0]; ++i) {
    for (auto j = 0; j < shape[1]; ++j) {
    ar & make_nvp("item", ma[i][j]);
    }
    }
    }

    template <typename Ar, typename T, size_t Dims>
    void load(Ar&, boost::detail::multi_array::const_multi_array_view<T, Dims>&, unsigned) {
    static_assert(not Ar::is_loading::value, "const_multi_array_view immutable");
    }

    template <typename Ar, typename T, size_t Dims>
    void serialize(Ar& ar, boost::detail::multi_array::const_multi_array_view<T, Dims>& ma, unsigned version) {
    split_free(ar, ma, version);
    }

    template <typename Ar, typename T, size_t Dims>
    void save(Ar& ar, boost::detail::multi_array::multi_array_view<T, Dims> const& ma, unsigned /*version*/) {
    std::array<int, Dims> shape;
    std::copy_n(ma.shape(), Dims, shape.begin());
    ar & make_nvp("shape", shape);

    for (auto i = 0; i < shape[0]; ++i) {
    for (auto j = 0; j < shape[1]; ++j) {
    ar & make_nvp("item", ma[i][j]);
    }
    }
    }

    template <typename Ar, typename T, size_t Dims>
    void load(Ar& ar, boost::detail::multi_array::multi_array_view<T, Dims>& ma, unsigned /*version*/) {
    std::array<int, Dims> shape;
    ar & make_nvp("shape", shape);

    if (!std::equal(begin(shape), end(shape), ma.shape()))
    throw std::logic_error("multi_array_view shape mismatch");

    for (auto i = 0; i < shape[0]; ++i) {
    for (auto j = 0; j < shape[1]; ++j) {
    ar & make_nvp("item", ma[i][j]);
    }
    }
    }

    template <typename Ar, typename T, size_t Dims>
    void serialize(Ar& ar, boost::detail::multi_array::multi_array_view<T, Dims>& ma, unsigned version) {
    split_free(ar, ma, version);
    }

    template <typename Ar, typename T, size_t Dims>
    void save(Ar& ar, boost::multi_array<T, Dims> const& ma, unsigned /*version*/) {
    std::array<int, Dims> shape;
    std::copy_n(ma.shape(), Dims, shape.begin());
    ar & make_nvp("shape", shape)
    & make_nvp("data", make_array(ma.data(), ma.num_elements()));
    }

    template <typename Ar, typename T, size_t Dims>
    void load(Ar& ar, boost::multi_array<T, Dims>& ma, unsigned /*version*/) {
    std::array<int, Dims> shape;
    ar & make_nvp("shape", shape);

    ma.resize(shape);
    ar & make_nvp("data", make_array(const_cast<T*>(ma.data()), ma.num_elements()));
    }

    template <typename Ar, typename T, size_t Dims>
    void serialize(Ar& ar, boost::multi_array<T, Dims>& ma, unsigned version) {
    split_free(ar, ma, version);
    }
    }

    auto make_multi_array() {
    boost::multi_array<int, 2> ma(boost::extents[7][4]);
    std::iota(ma.data(), ma.data() + ma.num_elements(), 10);
    return ma;
    }

    int main() {
    using range = boost::multi_array_types::index_range;
    auto original = make_multi_array();
    auto const SLICE = boost::indices[range(1,3)][range(1,3)];

    {
    std::ofstream os("array.txt");
    boost::archive::text_oarchive oa(os);

    // only serialize initial array:
    oa << original;

    // modify through a sub-view
    auto sub = original[SLICE];
    original[2][2] = 999;

    // serialize the patch
    oa << sub;

    auto const& const_original = original;
    auto const_sub = const_original[SLICE];
    oa << const_sub; // compiles
    }

    std::cout << std::ifstream("array.txt").rdbuf() << "\n";

    {
    std::ifstream is("array.txt");
    boost::archive::text_iarchive ia(is);

    // only deserialize initial array:
    boost::multi_array<int, 2> restored;
    ia >> restored;

    assert(restored != original); // entry overwritten with 999

    assert(restored.num_elements() == original.num_elements());
    auto [o_2_2, r_2_2] = std::mismatch(
    original.data(), original.data()+original.num_elements(),
    restored.data());

    assert(*o_2_2 == 999);
    assert(*r_2_2 == 20);

    // now patch in the sub array at the same sub-view:
    auto sub = restored[SLICE];
    ia >> sub;

    // now everything is equal
    assert(restored == original); // now matches!
    assert(*r_2_2 == 999);

    auto const& const_restored = restored;
    auto const_sub = const_restored[SLICE];
    //ia >> const_sub; // WON'T COMPILE
    }
    }

    关于c++ - 如何通过Boost.MPI发送2d Boost.MultiArray的子​​数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62108353/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com