构建具有形状和步幅的 std::vector 的基于 xtensor 的适配器需要什么?

问题描述 投票:0回答:1

我正在构建 xtensor 示例 “嵌入形状和步幅的结构”,将其用于具有自己的标头信息的图像类。我已经做到了这一点:

#include <xtensor/xadapt.hpp>
#include <xtensor/xstrides.hpp>

// see https://github.com/xtensor-stack/xtensor/blob/master/docs/source/external-structures.rst
template <class T>
struct raw_tensor {
    using container_type = std::vector<T>;
    using shape_type = std::vector<std::size_t>;
    container_type 
        m_data;
    shape_type 
        m_shape,
        m_strides,
        m_backstrides;
    static constexpr xt::layout_type 
        layout = xt::layout_type::dynamic;
};

template <class T>
class raw_tensor_adaptor;

template <class T>
struct xt::xcontainer_inner_types<raw_tensor_adaptor<T>> {
    using container_type = typename raw_tensor<T>::container_type;
    using inner_shape_type = typename raw_tensor<T>::shape_type;
    using inner_strides_type = inner_shape_type;
    using inner_backstrides_type = inner_shape_type;
    using shape_type = inner_shape_type;
    using strides_type = inner_shape_type;
    using backstrides_type = inner_shape_type;
    static constexpr layout_type layout = raw_tensor<T>::layout;
};

template <class T>
struct xt::xiterable_inner_types<raw_tensor_adaptor<T>>
    : xcontainer_iterable_types<raw_tensor_adaptor<T>> {
};

template <class T>
class raw_tensor_adaptor : public xt::xcontainer<raw_tensor_adaptor<T>>,
                           public xt::xcontainer_semantic<raw_tensor_adaptor<T>> {

public:

    using self_type = raw_tensor_adaptor<T>;
    using base_type = xt::xcontainer<self_type>;
    using semantic_base = xt::xcontainer_semantic<self_type>;

    raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
    raw_tensor_adaptor& operator=(const raw_tensor_adaptor&) = default;    
    raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
    raw_tensor_adaptor& operator=(raw_tensor_adaptor&&) = default;

    template <class E>
    raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
        semantic_base::assign(e);
    }

    template <class E>
    self_type& operator=(const xt::xexpression<E>& e) {
        return semantic_base::operator=(e);
    }   
    
};

int main() {

raw_tensor<double> i,j,k;       // this works
using tensor_type = raw_tensor_adaptor<double>;
// tensor_type a, b, c;         // but not this if un-commented
//   .... init a, b, c
// tensor_type d = a + b - c;   raw_tensor < int > a;
return 0;
    
}

使用仅声明类

main()
对象的
raw_tensor<double>
函数,编译可以顺利完成。

在 Linux(使用 gcc-11)上,我可以通过执行以下操作(重新)运行此示例:

$ cd /tmp && mkdir -p xtensor-test && cd xtensor-test
$ git clone https://github.com/xtensor-stack/xtensor.git
$ git clone https://github.com/xtensor-stack/xtl.git
$ vi xtensor-test.cpp # insert the code block above and save
$ g++ -o xtensor-test xtensor-test.cpp -Ixtensor/include -Ixtl/include

但是,我不能做这些事情:

  1. add
    resize()
    accessor 方法:当我在类中添加
    resize()
    函数(没有模板参数
    T
    )时,这不起作用,因为内部类型和成员
    shape_type
    m_shape
    等未知。但这是唯一超载的地方
    resize()
    ,对吗?
  2. 添加网页中声明适配器对象的
    using tensor_type = raw_tensor_adaptor<double>;

    tensor_type a, b, c;

当我声明这些适配器时,

a, b, c
行会生成以下错误:

include/xtensor/xiterable.hpp:288:19: error: no type named 'xexpression_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:35:15: error: no type named 'reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:36:15: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:37:15: error: no type named 'size_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:47:48: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:111:26: error: 'at' has not been declared in 'using base_type = class 
include/xtensor/xaccessible.hpp:112:35: error: 'operator[]' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:113:26: error: 'back' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:114:26: error: 'front' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:115:26: error: 'periodic' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:79:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:80:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:82:15: error: no type named 'reference' in 'struct  xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:83:15: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:86:15: error: no type named 'size_type' in 'struct  xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:88:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:89:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:107:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:108:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:140:32: error: 'at' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:141:32: error: 'shape' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:142:41: error: 'operator[]' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:143:32: error: 'back' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:144:32: error: 'front' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:146:32: error: 'periodic' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:182:15: error: no type named 'storage_type' in 'struct
include/xtensor/xsemantic.hpp:64:15: error: no type named 'temporary_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’

来自

xtensor
标题和

xtensor-test.cpp:70:13: error: no matching function for call to ‘raw_tensor_adaptor<double>::raw_tensor_adaptor()’
 tensor_type a, b, c;            // but not this if un-commented
             ^
xtensor-test.cpp:55:5: note: candidate: ‘template<class E> raw_tensor_adaptor<T>::raw_tensor_adaptor(const xt::xexpression<E>&)’
     raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
     ^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:55:5: note:   template argument deduction/substitution failed:
xtensor-test.cpp:70:13: note:   candidate expects 1 argument, 0 provided
 tensor_type a, b, c;            // but not this if un-commented
             ^
xtensor-test.cpp:51:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(raw_tensor_adaptor<T>&&) [with T = double]’
     raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
     ^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:51:5: note:   candidate expects 1 argument, 0 provided
xtensor-test.cpp:49:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(const raw_tensor_adaptor<T>&) [with T = double]’
     raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
     ^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:49:5: note:   candidate expects 1 argument, 0 provided
xtensor-test.cpp:49:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(const raw_tensor_adaptor<T>&) [with T = double]’
     raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
     ^~~~~~~~~~~~~~~~~~

来自

.cpp
文件

网页表示定义语义并实现特定于 raw_tensor 结构的方法和函数。但我感觉我做错了地方。

有人让这个示例与 raw_tensor_adaptor 实例一起使用吗? 非常感谢!

c++ stdvector xtensor adaptor
1个回答
0
投票

1。定义内部类型

您需要正确定义 xtensor 所需的内部类型和方法,以确保您的适配器类与 xtensor 库顺利工作。类型应该与 xtensor 期望的类型一致。您已经部分定义了 xcontainer_inner_types 和 xiterable_inner_types,但缺少一些关键类型和方法。

这是 raw_tensor_adaptor 类的精炼版本,具有完整的定义:

#include <vector>
#include <xtensor/xadapt.hpp>
#include <xtensor/xstrides.hpp>

template <class T>
struct raw_tensor {
    using container_type = std::vector<T>;
    using shape_type = std::vector<std::size_t>;
    container_type m_data;
    shape_type m_shape;
    shape_type m_strides;
    shape_type m_backstrides;
    static constexpr xt::layout_type layout = xt::layout_type::dynamic;
};

template <class T>
class raw_tensor_adaptor;

template <class T>
struct xt::xcontainer_inner_types<raw_tensor_adaptor<T>> {
    using container_type = typename raw_tensor<T>::container_type;
    using inner_shape_type = typename raw_tensor<T>::shape_type;
    using shape_type = inner_shape_type;
    using strides_type = inner_shape_type;
    using backstrides_type = inner_shape_type;
    using storage_type = container_type;
    using reference = T&;
    using const_reference = const T&;
    using size_type = typename container_type::size_type;
    using difference_type = typename container_type::difference_type;
    static constexpr layout_type layout = raw_tensor<T>::layout;
};

template <class T>
struct xt::xiterable_inner_types<raw_tensor_adaptor<T>>
    : xt::xcontainer_iterable_types<raw_tensor_adaptor<T>> {
};

template <class T>
class raw_tensor_adaptor : public xt::xcontainer<raw_tensor_adaptor<T>>,
                           public xt::xcontainer_semantic<raw_tensor_adaptor<T>> {

public:
    using self_type = raw_tensor_adaptor<T>;
    using base_type = xt::xcontainer<self_type>;
    using semantic_base = xt::xcontainer_semantic<self_type>;

    raw_tensor_adaptor() = default;

    raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
    raw_tensor_adaptor& operator=(const raw_tensor_adaptor&) = default;    
    raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
    raw_tensor_adaptor& operator=(raw_tensor_adaptor&&) = default;

    template <class E>
    raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
        semantic_base::assign(e);
    }

    template <class E>
    self_type& operator=(const xt::xexpression<E>& e) {
        return semantic_base::operator=(e);
    }

    // Implement the resize method
    void resize(const typename raw_tensor<T>::shape_type& new_shape) {
        // Update shape and possibly resize data if needed
        m_shape = new_shape;
        // TODO: Implement resizing logic for m_data based on new_shape and strides
    }

    // Accessor methods
    auto shape() const {
        return m_shape;
    }

    auto& data() {
        return m_data;
    }

private:
    raw_tensor<T> m_raw_tensor;
};

2。实现方法和函数

在精炼后的 raw_tensor_adaptor 类中,我添加了默认构造函数并实现了调整大小方法。您需要确保 resize 方法和其他访问器方法在 m_shape、m_data 和其他成员上正确运行。

3.确保正确的类型定义

确保在 raw_tensor_adaptor 的 xcontainer_inner_types 中正确定义了引用、const_reference、size_type 和 storage_type 等类型。

4。编译

通过这些更改,您应该能够编译程序而不会出现遇到的错误。确保 xtensor 和 xtl 库已正确包含并且是最新的。

用法示例

完成这些更改后,您应该能够声明 raw_tensor_adaptor 对象并执行加法等操作:

int main() {
    raw_tensor<double> raw1, raw2, raw3;
    using tensor_type = raw_tensor_adaptor<double>;
    tensor_type a, b, c;
    // Initialize a, b, and c as needed
    // tensor_type d = a + b - c;  // Ensure that operator+ and operator- are correctly implemented
    return 0;
}

如果您打算使用必要的算术运算(operator+、operator-等),请确保实现它们,因为 xtensor 不会自动提供这些运算。

通过执行这些步骤,您应该能够为自定义张量结构创建一个可用的 xtensor 适配器。

© www.soinside.com 2019 - 2024. All rights reserved.