python - 如何使用 SWIG 将 numpy 数组转换为 vector<int>& (引用)

标签 python c++ numpy vector swig

我的目标:

在 python 中创建 3 个 numpy 数组(其中 2 个将使用特定值进行初始化),然后通过 swig 将所有三个数组作为 vector 引用发送到 C++ 函数中(这是为了避免复制数据并降低效率)。进入 C++ 函数后,将 2 个数组相加,并将它们的和放入第三个数组中。

vec_ref.h

#include <vector>
#include <iostream>

void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2);

vec_ref.cpp

#include "vec_ref.h"
#include <cstring> // need for size_t
#include <cassert>

void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2) {
    std::cout << "inside add_vec_ref" << std::endl;
    assert(src1.size() == src2.size());
    dst.resize(src1.size());

    for (size_t i = 0; i < src1.size(); i++) {
        dst[i] = src1[i] + src2[i];
    }
}

vec_ref.i

%module vec_ref
%{
    #define SWIG_FILE_WITH_INIT
    #include "vec_ref.h"
%}

%include "numpy.i"
%init %{
import_array();
%}

%include "std_vector.i"
%template(vecInt) std::vector<int>;
// %template(vecIntRef) std::vector<int> &; 

// %apply (std::vector<int> * INPLACE_ARRAY1, int DIM1) {(std::vector<int> * dst, int a),(std::vector<int> * src1, int b),(std::vector<int> * src2, int c)};
// %apply (std::vector<int> * INPLACE_ARRAY1) {(std::vector<int> * dst),(std::vector<int> * src1),(std::vector<int> * src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1) {(std::vector<int> & dst),(std::vector<int> & src1),(std::vector<int> & src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1, int DIM1) {(std::vector<int> & dst, int a),(std::vector<int> & src1, int b),(std::vector<int> & src2, int c)};

%include "vec_ref.h"

生成文件

all:
    rm -f *.so *.o *_wrap.* *.pyc *.gch vec_ref.py
    swig -c++ -python vec_ref.i
    g++ -O0 -g3 -fpic -c vec_ref_wrap.cxx vec_ref.h vec_ref.cpp -I/home/lmckeereid/tools/anaconda3/pkgs/python-3.7.3-h0371630_0/include/python3.7m/
    g++ -O0 -g3 -shared vec_ref_wrap.o vec_ref.o -o _vec_ref.so

测试器.py

import vec_ref as vec
import numpy as np

a = np.array([1,2,3], dtype=np.intc)
b = np.array([4,5,6], dtype=np.intc)
c = np.zeros(len(a), dtype=np.intc)

print('---Before---\na:', a)
print('b:', b)
print('c:', c)

vec.add_vec_ref(c,a,b)

print('---After---\na:', a)
print('b:', b)
print('c:', c)

输出:

---Before---
a: [1 2 3]
b: [4 5 6]
c: [0 0 0]
Traceback (most recent call last):
  File "tester.py", line 12, in <module>
    vec.add_vec_ref(c,a,b)
TypeError: in method 'add_vec_ref', argument 1 of type 'std::vector< int,std::allocator< int > > &'

我已经尝试了 vec_ref.i 中找到的所有注释掉的 %apply 和 %template 指令,但它们不起作用。

是否有一些我应该包含但没有包含的类型映射?

最佳答案

我同意@pschill:如果不复制数据就不可能获得 std::vector 。

一种替代方法是使用 std::span class template (在 C++20 中引入),或类似的 span库中定义的类模板。

创建 std::span<int>将提供 numpy 中现有数据的 View 数组,并提供many convenient member functions (例如 C++ 中的 operator[] 、迭代器、 front()back() 等)。

创建跨度永远不会从 numpy 数组复制数据。

关于python - 如何使用 SWIG 将 numpy 数组转换为 vector<int>& (引用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58494850/

相关文章:

python - 如何从 Flask 中的不同蓝图调用方法?

python - 我从哪里获得 Authorized Gmail API 服务实例? ( python ,Gmail API)

c++ - C++类中的运算符重载函数

c++ - 在 Windows 中使用 OpenCV 3.0 从文件夹加载图像

python - 根据值的集合成员资格为 numpy 数组创建掩码

python - 正则表达式查找器 : search twice on the same symbols

JavaCV透视校正

python - Numpy 索引问题.....高级索引 X[0] 在这里做什么?

python - 在 numpy 中对巨大的密集矩阵进行操作

python - 如何打印特定用户的 fav_genre 字段