如何将numpy数组正确传递给Cython函数? [英] how to pass numpy array to Cython function correctly?

查看:265
本文介绍了如何将numpy数组正确传递给Cython函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这在很多地方都有描述,但是我根本无法使它正常工作.我正在从Cython调用C ++函数:

This is described in many places but i simply cannot get it to work. I am calling a C++ function from Cython:

cimport numpy as np
cdef extern from "test.h" namespace "mytest":
   void test(double *A, int m)

cdef int foo():
  cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)
  # pass ptr to first element of 'a'
  test(&a[0], len(a))
  return 0

foo()

test.cpp就是:

test.cpp is just:

#include <stdio.h>
namespace mytest {
    void test(double *A, int m)
    {
    for (int i = 0; i < m; i++)
    {
        printf("%d is %f\n", i, A[i]);
    }
    }
}

test.h只有:

namespace mytest {
  void test(double *A, int m);
}

这似乎可行,但是何时需要np.ascontiguousarray?是否足够:

This seems to work but when is np.ascontiguousarray needed? Is it sufficient to do:

cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)

还是您需要:

cdef np.ndarray[double,mode="c"] a = np.ascontiguousarray(np.array([1,2,3,4,5],dtype=float))

第二个,更重要的是,如何将其推广到2d数组?

second and more importantly, how can this generalize to 2d arrays?

处理2d数组

这是我尝试将2d numpy数组传递给C ++的方法,但不起作用:

Here is my attempt at passing 2d numpy arrays to C++ which does not work:

cdef np.ndarray[double,mode="c",ndim=2] a = np.array([[1,2],[3,4]],dtype=float)

称为:

test(&a[0,0], a.shape[0], a.shape[1])

在cpp代码中:

void test(double *A, int m, int n) 
{ 
  printf("reference 0,0 element\n");
  printf("%f\n", A[0][0]);
}

更新:正确答案

正确的答案是对数组使用线性索引,而不是[][]语法.打印二维数组的正确方法是:

The correct answer is to use linear indexing for the array and not the [][] syntax. The correct way to print the 2d array is:

for (int i = 0; i < m; i++)
{
    for (int j = 0; j < n; j++)
    {
    printf("%d, %d is %f\n", i, j, A[i*m + j]);
    }
}

推荐答案

对于2D数组,您只需要ndim关键字:

For 2D arrays, you just need the ndim keyword:

cdef np.ndarray[double, mode="c", ndim=2]

结果可能会或可能不会与原始照片共享内存.如果它与原始磁盘共享内存,则该阵列可能不是连续的,或者可能具有异常的跨步配置.在这种情况下,将缓冲区直接传递给C/C ++将会是灾难性的.

The result may or may not share memory with the original. If it shares memory with the original, then the array may not be contiguous, or may have an unusual striding configuration. In this case, passing the buffer to C/C++ directly will be disastrous.

除非您的C/C ++代码准备处理非连续数据,否则您应该始终使用ascontiguousarray(在这种情况下,您需要将所有相关的跨步数据从Cython传递到C函数).如果输入数组已经是连续的,则不会进行复制.确保将兼容的dtype传递给ascontiguousarray,这样就不会冒第二份副本的风险(例如,必须从连续的float数组转换为连续的double数组).

You should always use ascontiguousarray unless your C/C++ code is prepared to deal with non-contiguous data (in which case you will need to pass in all relevant stride data from Cython into the C function). If the input array is already contiguous, no copy will be made. Make sure to pass a compatible dtype to ascontiguousarray so that you don't risk a second copy (e.g. having to convert from a contiguous float array to a contiguous double array).

这篇关于如何将numpy数组正确传递给Cython函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆