热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在Cython中处理C++数组(使用numpy和pytorch)

如何解决《在Cython中处理C++数组(使用numpy和pytorch)》经验,为你挑选了1个好方法。

我试图用来cython包装一个C++库(fastText如果相关的话).C++库类从磁盘加载一个非常大的数组.我的包装器从C++库中实例化一个类来加载数组,然后使用cython内存视图并将numpy.asarray数组转换为numpy数组,然后调用torch.from_numpy以创建张量.

出现的问题是如何处理为阵列释放内存.

现在,我得到pointer being freed was not allocated程序退出时.我希望这是因为C++代码和numpy/ pytorch都试图管理同一块RAM.

我可以简单地在C++库中注释掉析构函数,但这感觉就像它将导致我在路上遇到不同的问题.

我该如何处理这个问题?是否有任何关于如何使用C++处理内存共享的最佳实践文档cython

如果我修改C++库来包装在一个阵列shared_ptr,将cython(和numpy,pytorch等)共享shared_ptr正确?

如果问题是天真的,我道歉; Python垃圾收集对我来说非常神秘.

任何建议表示赞赏.



1> DavidW..:

我可以想到三种合理的方法.我将在下面概述它们(即没有任何代码将完整,但希望它将很清楚如何完成它).

1. C++拥有内存; Cython/Python拥有一个指向C++类的共享指针

(这看起来就像你一直在思考的那条线).

首先创建一个包含共享指针的Cython类

from libcpp.memory cimport shared_ptr

cdef class Holder:
    cdef shared_ptr[cpp_class] ptr

    @staticmethod
    cdef make_holder(shared_ptr[cpp_class] ptr):
       cdef holder = Holder() # empty class
       holder.ptr = ptr
       return holder

然后,您需要为其定义缓冲区协议Holder.这允许以cpp_classnumpy数组和Cython内存视图都能理解的方式直接访问分配的内存.因此,他们持有对Holder实例的引用,而实例又保持cpp_class活着.(np.asarray(holder_instance)用于创建使用实例内存的numpy数组)

缓冲协议有点涉及,但Cython有相当广泛的文档,你应该在很大程度上能够复制和粘贴他们的例子.您需要添加的两种方法Holder__getbuffer____releasebuffer__.

2. Python拥有内存; 您的C++类包含指向Python对象的指针

在此版本中,您将内存分配为numpy数组(使用Python C API接口).当您的C++类以递减方式销毁数组的引用计数时,但是如果Python保存对该数组的引用,那么该数组可以比C++类更长.

#include 
#include 

class cpp_class {
   private:
     PyObject* arr;
     double* data;
   public:
     cpp_class() {
       arr = PyArray_SimpleNew(...); // details left to be filled in
       data = PyArray_DATA(reinterpret_cast(arr));
       # fill in the data
     }

     ~cpp_class() {
         Py_DECREF(arr); // release our reference to it
     }

     PyObject* get_np_array() {
         Py_INCREF(arr); // Cython expects this to be done before it receives a PyObject
         return arr;
     }
};

有关如何从C/C++分配numpy数组的详细信息,请参阅numpy文档.如果定义复制/移动构造函数,请注意引用计数.

Cython包装器然后看起来像:

cdef extern from "some_header.hpp":
    cdef cppclass cpp_class:
       # whatever constructors you want to allow
       object get_np_array()
3. C++将数据的所有权转移到Python/Cython

在这个方案中,C++分配数组,但Cython/Python负责解除分配.一旦所有权转移,C++就不再能够访问数据.

class cpp_class {
   public:
     double* data; // for simplicity this is public - you may want to use accessors
     cpp_class() :
     data(new double[50])
     {/* fill the array as needed */}

     ~cpp_class() {
       delete [] data;
     }
};

// helper function for Cython
inline void del_cpp_array(double* a) {
   delete [] a;
}

然后使用cython.view.array该类捕获分配的内存.这有一个用于销毁的回调函数:

from cython cimport view

cdef extern from "some_header.hpp":
   cdef cppclass cpp_class:
      double* data
      # whatever constructors and other functions
   void del_cpp_array(double*)

# later
cdef cpp_class cpp_instance # create this however you like
# ...
# modify line below to match your data
arr = view.array(shape=(10, 2), itemsize=sizeof(double), format="d",
                 mode="C", allocate_buffer=False)
arr.data = cpp_instance.data
cpp_instance.data = None # reset to NULL pointer
arr.callback_free_data = del_cpp_array

arr 然后可以与memoryview或numpy数组一起使用.

你可能不得不乱用void*char*使用del_cpp_array- 我不确定Cython接口需要什么类型.


第一个选项可能是大多数要实现的工作,但几乎不需要对C++代码进行任何更改.第二个选项可能需要更改您不想要的C++代码.第三种选择很简单,但意味着C++不再能访问数据,这可能是一个缺点.


推荐阅读
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • Python实现变声器功能(萝莉音御姐音)的方法及步骤
    本文介绍了使用Python实现变声器功能(萝莉音御姐音)的方法及步骤。首先登录百度AL开发平台,选择语音合成,创建应用并填写应用信息,获取Appid、API Key和Secret Key。然后安装pythonsdk,可以通过pip install baidu-aip或python setup.py install进行安装。最后,书写代码实现变声器功能,使用AipSpeech库进行语音合成,可以设置音量等参数。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了如何在方法参数中指定一个对象的协议,以及如何调用符合该协议的方法。以一个具体的示例说明了如何在方法参数中指定一个UIView子类对象,并且该对象需要符合PixelUI协议,同时方法需要能够访问该对象的属性。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • 本文由编程笔记小编整理,主要介绍了使用Junit和黄瓜进行自动化测试中步骤缺失的问题。文章首先介绍了使用cucumber和Junit创建Runner类的代码,然后详细说明了黄瓜功能中的步骤和Steps类的实现。本文对于需要使用Junit和黄瓜进行自动化测试的开发者具有一定的参考价值。摘要长度:187字。 ... [详细]
  • 本文介绍了如何在Mac上使用Pillow库加载不同于默认字体和大小的字体,并提供了一个简单的示例代码。通过该示例,读者可以了解如何在Python中使用Pillow库来写入不同字体的文本。同时,本文也解决了在Mac上使用Pillow库加载字体时可能遇到的问题。读者可以根据本文提供的示例代码,轻松实现在Mac上使用Pillow库加载不同字体的功能。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
author-avatar
傻a2602909381
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有