如何通过Boost.MPI发送2d Boost.MultiArray的子阵列?
How to send subarray of 2d Boost.MultiArray via Boost.MPI?
>我需要使用 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);
}
}
在科里鲁现场观看
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
更新:视图
嗯,已经接受了?晚了才注意到我实际上并没有很好地阅读你的问题。您想要序列化视图。你不能,真的。您不能"反序列化视图"。
您最多能做的就是反序列化 INTO 视图。
另请注意
如果大小差异不是很大,序列化整个数组可能会(更有效(
视图类型不是库的公共接口,即它可能会在未来版本的 Boost 中中断。如有疑问,请序列化数组本身
这里有一些更多的机器:
添加对
detail::multi_array::multi_array_view<...>
的支持,因为它只能反序列化为匹配形状的现有视图添加对仅序列化
detail::multi_array::const_multi_array_view<...>
的支持。出于显而易见的原因,所述视图只能反序列化为非常量视图。使用子视图扩展演示,该子视图在序列化后修补初始数组,因此我们可以验证将补丁读取到恢复数组的等效视图中是否具有与原始视图相同的效果(在检查补丁是否创建了预期的不匹配
20 != 999
之后(。
住在科里鲁
#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
}
}
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- OpenMP阵列性能较差
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 如何通过Boost.MPI发送2d Boost.MultiArray的子阵列?
- 如何从2d Boost.MultiArray获取子阵列?
- 使用Boost交换Python和C numpy阵列
- 使用Boost :: Join合并多个阵列
- 用Boost Hana反映C风格的阵列
- 将阵列传递到Boost Vector元组中
- 在Boost :: Multi_array中,这是子阵列的类型
- boost::多阵列内存管理和范围
- boost::进程间更新阵列的最快方法
- 为boost中的动态阵列定义自定义步进器
- 内存映射2D阵列使用boost
- Boost多阵列分段故障
- 如何为Boost多阵列释放内存