using partial typemaps from numpy.i

时间:2015-08-07 02:09:46

标签: python c++ numpy swig

I have a function that needs only one of the dimensions of an input array, so I am ignore a dimension in a 2D numpy array. Is there a way to do this?

Header:

#ifndef __nparrtest_h__
#define __nparrtest_h__
class NPArrTest {
public:
    static void Print2D(int n, int m, const int* graph);
};
#endif

Cpp:

#include "NPArrTest.h"
#include <stdio.h>
void NPArrTest::Print2D(int n, int m, const int* graph) {
     printf("n: %d m: %d\n",n,m);
}

swig interface file:

%module NPArrTest
%{
    #define SWIG_FILE_WITH_INIT
    #include "NPArrTest.h"
%}
%include "numpy.i"
%init %{
  import_array1();
%}
%numpy_typemaps(int,    NPY_INT   , int)
//Something like the below:
%apply int DIM2, int* IN_ARRAY2 {int m, const int* graph};
%include "NPArrTest.h"

I can't get %apply (int DIM1, int* IN_ARRAY2) {(int m, const int* graph)}; or %apply int* IN_ARRAY2 {const int* graph}; to work (the ladder to just pass the 2D array).

How can I pass only a single dimension length value of the 2D array to the c++ function?

>

P.S. Is there an easy way to allow this conversion?

TypeError: Cannot cast array data from dtype('int64') to dtype('int32') according to the rule 'safe'

1 个答案:

答案 0 :(得分:0)

我对输出数组做了类似的修改,其中一个维度是固定的。下面的代码是我为numpy.i

所做的扩展的一部分
#ifdef SWIGPYTHON
%{
#ifndef SWIG_FILE_WITH_INIT
#  define NO_IMPORT_ARRAY
#endif
#include "stdio.h"
#include <numpy/arrayobject.h>
%}

%include "numpy.i"

%define %numpy_ex_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)

/* Typemap suite for (DATA_TYPE** DYNARGOUTVIEW_ARRAY2_FIXED[ANY], DIM_TYPE* DIM1)
 */
%typemap(in,numinputs=0,noblock=1)
(DATA_TYPE* DYNARGOUTVIEW_ARRAY2_FIXED[ANY], DIM_TYPE* DIM1)
{
  size_t secondDim = $1_dim0;
  size_t firstDim;
  DATA_TYPE* tempData;
  $1 = &tempData;
  $2 = &firstDim;
}
%typemap(out)
void DYNARGOUTVIEW_ARRAY2_FIXED_##DATA_TYPECODE
{
  npy_intp dims[2] = {(npy_intp) firstDim, (npy_intp) secondDim};
%#ifdef __GNUC__
  __extension__
%#endif
  PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE,(void*)(tempData));
  if (!array) SWIG_fail;
  $result = SWIG_Python_AppendOutput($result,array);
}

%enddef    /* %numpy_ex_typemaps() macro */

%numpy_ex_typemaps(double            , NPY_DOUBLE   , size_t)
%numpy_ex_typemaps(float             , NPY_FLOAT    , size_t)
%numpy_ex_typemaps(signed char       , NPY_BYTE     , size_t)

应用类型映射时,必须匹配两个类型映射,例如

%apply (double* DYNARGOUTVIEW_ARRAY2_FIXED[ANY], size_t* DIM1) {(double* coefs[3], size_t* length)};
%apply void DYNARGOUTVIEW_ARRAY2_FIXED_NPY_DOUBLE {void getFilter}

你的功能看起来像这样。

void getFilter(double* coefs[3], size_t* length);

通过查看原始的numpy.i文件可以清楚地看到如何将其更改为输入。