SWIG 输入文件和带有 numpy 的向量。使用 % 应用?
Posted
技术标签:
【中文标题】SWIG 输入文件和带有 numpy 的向量。使用 % 应用?【英文标题】:SWIG input files and Vectors with numpy. Using %apply? 【发布时间】:2015-09-21 17:28:32 【问题描述】:我正在尝试让我的 C++ 代码使用 Swig 提供一个 numpy 数组。一切都设置得很好,但是当我通过 python 运行我的代码时,我得到了一个 SwigPyObject。我似乎想不出正确的 SWIG 输入文件。我的函数如下所示:
double*** runshapes(vector<vector<vector<double> > > &array3d,
double T,
double lam,
double Vel)...
我的 .i 文件如下所示:
%module runshapes
%
#define SWIG_FILE_WITH_INIT
#include "runshapes.h"
%
%include "numpy.i"
%init %
import_array();
%
%include "std_vector.i"
%include "std_string.i"
// Instantiate templates used by example
namespace std
%template(DoubleVector) vector<double>;
%template(VecVecdouble) vector< vector<double> >;
%template(VecVecVecdouble) vector< vector< vector<double> > >;
%include "runshapes.h"
它似乎理解向量,但输出(应该是 3D 数组)作为 SwigPyObject 输出。
如果这样可以简化问题,我可以将输出设为 3D 矢量 :)
感谢您的帮助! 克里斯蒂娜
【问题讨论】:
嘿,@克里斯蒂娜。使用std::vector
总是会复制数据,不可能使用指针创建std::vector
而无需复制。我通常使用llvm
中的ArrayRef
或为std::vector 制作一个包装器,并使用numpy.i
中的常规方法进行swigging。如果您愿意,我可以为此发布解决方案。挺好看的
【参考方案1】:
我通常使用 POD 类型使用 NumPy 类型映射来包装接口,如下所示。
vector3.h
#pragma once
#include <stddef.h>
int runshapes_wrap(const double* idata,
const size_t inx,
const size_t iny,
const size_t inz,
double** odata,
size_t* onx,
size_t* ony,
size_t* onz);
vector3.cpp
#include "vector3.h"
#include <stdio.h>
#include <malloc.h>
int runshapes_wrap(const double* idata,
const size_t inx,
const size_t iny,
const size_t inz,
double** odata,
size_t* onx,
size_t* ony,
size_t* onz)
// Note this one allocates
size_t nx = 10;
size_t ny = 20;
size_t nz = 30;
*odata = (double*) malloc(sizeof(double)*nx*ny*nz);
*onx = nx;
*ony = ny;
*onz = nz;
// Do whatever
printf("inx,iny,inz: %zu, %zu, %zu\n",nx,ny,nz);
return 0;
vector3.i
%module(docstring="This is a Python wrapper for Sofus") swig_vector
%
#define SWIG_FILE_WITH_INIT
#include "vector3.h"
%
%include "numpy.i"
%init
%
import_array();
%
%apply (double** ARGOUTVIEWM_ARRAY3, size_t* DIM1, size_t* DIM2, size_t* DIM3) (double** odata, size_t* onx, size_t* ony, size_t* onz)
%apply (double* IN_ARRAY3, int DIM1, int DIM2, int DIM3) (const double* idata, const size_t inx, const size_t iny, const size_t inz);
%include "vector3.h"
请注意,类型映射 ARGOUTVIEWM_ARRAY3 确保在 Python 中删除相应的 NumPy 数组时删除分配的数据。使用模板,这可以变得非常紧凑,但是您需要为每个模板实例化一个类型映射。
# setup.py
from distutils.core import setup, Extension
setup(name="swig_vector",
py_modules=['swig_vector'],
ext_modules=[Extension("_swig_vector",
["vector3.i", "vector3.cpp"],
swig_opts=['-c++'],
extra_compile_args=['--std=c++11']
)]
)
使用python setup.py build_ext --inplace
执行最后一个脚本会生成准备好测试功能的库
【讨论】:
以上是关于SWIG 输入文件和带有 numpy 的向量。使用 % 应用?的主要内容,如果未能解决你的问题,请参考以下文章
带有 SWIG 的 C++ 数组到 Numpy 的 TypeError 问题
如何使用 SWIG 将 numpy 数组转换为 vector<int>&(参考)
使用 SWIG 控制器将 python 中的 numpy 函数传递给 C++