簡體   English   中英

pybind11 從 C++ 修改 numpy 數組

[英]pybind11 modify numpy array from C++

編輯:現在有效,我不知道為什么。 不要以為我改變了什么

我想通過 pybind11 傳入並修改一個大的 numpy 數組。 因為它很大,所以我想避免復制它並返回一個新的。

這是代碼:

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>
#include <vector>

// C++ code
void calc_sum_cost(float* ptr, int N, int M, float* ptr_cost) {
  for(int32_t i = 1; i < N; i++) {
    for(int32_t j = 1; j < M; j++) {
      float upc = ptr[(i-1) * M + j];
      float leftc = ptr[i * M + j - 1];
      float diagc = ptr[(i-1) * M + j - 1];
      float transition_cost = std::min(upc, std::min(leftc, diagc));
      if (transition_cost == diagc) {
        transition_cost += 2 * ptr_cost[i*M + j];
      } else {
        transition_cost += ptr_cost[i*M + j];
      }
      std::cout << transition_cost << std::endl;
      ptr[i * M + j] = transition_cost;
    }
  }
}

// Interface

namespace py = pybind11;

// wrap C++ function with NumPy array IO
py::object wrapper(py::array_t<float> array,
                  py::array_t<float> arrayb) {
  // check input dimensions
  if ( array.ndim()     != 2 )
    throw std::runtime_error("Input should be 2-D NumPy array");

  auto buf = array.request();
  auto buf2 = arrayb.request();
  if (buf.size != buf2.size) throw std::runtime_error("sizes do not match!");

  int N = array.shape()[0], M = array.shape()[1];

  float* ptr = (float*) buf.ptr;
  float* ptr_cost = (float*) buf2.ptr;
  // call pure C++ function
  calc_sum_cost(ptr, N, M, ptr_cost);
  return py::cast<py::none>(Py_None);
}

PYBIND11_MODULE(fast,m) {
  m.doc() = "pybind11 plugin";
  m.def("calc_sum_cost", &wrapper, "Calculate the length of an array of vectors");
}

我認為py::array::forcecast導致轉換,因此保持輸入矩陣不變(在 python 中)。 當我刪除它時,雖然出現運行時錯誤,但當我刪除::c_style時,它運行但再次在 python 中,numpy 數組是相同的。

基本上我的問題是如何使用 pybind11 傳遞和修改 numpy 數組?

我只是有同樣的問題。 如果從Python傳遞了一個與C ++參數匹配的類型的numpy數組,則沒有轉換發生,並且可以就地修改數據,即在numpy np.float32數組中傳遞py::array_t<float>參數。 如果您碰巧傳入np.float64數組(默認類型),則pybind11會由於py::array::forcecast模板參數( py::array_t<T>上的默認值)進行轉換,因此僅C ++函數獲取numpy數組的轉換后的副本,並且返回后所有更改都將丟失。

您應該定義包裝器 function 以通過引用傳遞參數:

py::object wrapper(py::array_t<float> &array,
                  py::array_t<float> &arrayb)

正如索爾的回答所示,您應該傳遞類型為np.float32的 numpy 數組以匹配 C++ 數組類型,否則您無法將傳遞的 arrays 從 Python 更改為 C++ 88340084.65

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM