【问题标题】:Making a memoryview C-contiguous Fortran-contiguous使 memoryview C-contiguous Fortran-contiguous
【发布时间】:2017-12-21 22:34:11
【问题描述】:

我在我的 Python 代码中使用 C 连续内存视图,我想使用需要 Fortran 连续内存视图的 dgemm。 我想使用 here 找到的 PyMemoryView_GetContiguous 函数,但我不知道如何访问它。

有人知道我必须执行哪个导入吗?

我不想使用函数 copy_fortran(),因为它确实会减慢我的代码速度。

【问题讨论】:

  • 一个评论,因为这有点猜测:看起来您当前的矩阵以行主要顺序存储,这是您认为您想要的转置。但是您可以在 dgemm 中使用 C(T)=(AB)(T)=B(T)A(T) 和转置选项来避免更改内存布局吗? (其中(T)表示转置)
  • 这就是我最终解决问题的方法。谢谢!

标签: python fortran cython contiguous


【解决方案1】:

PyMemoryView_GetContiguous 看起来不会因为 Cython 标准的一部分而暴露出来,不幸的是。不过,它应该相当容易包装:

from cpython.buffer cimport PyBUF_READ # we'll need this later

cdef extern from "Python.h":
    # copy the signature replacing PyObject* with object to let Cython
    # handle the reference counting
    object PyMemoryView_GetContiguous(object, int, char)

def test(double[:,::1] c_contig):
   f_contig = PyMemoryView_GetContiguous(c_contig, PyBuf_READ,'F')
   # .... do something useful

请注意,这仍将涉及复制所有内存(这绝对是不可避免的!)因此不太可能比 copy_fortran 快得多。


但有一个问题 - PyMemoryView_GetContiguous 不会返回可写的内存视图,除非它不必制作副本,并且 Cython 要求分配给类型化内存视图的内容是可写的,因此您只能将其用作 Python 对象.

您可以获得指向第一个元素的指针 - 创建的基础对象是 bytes/str 对象,因此您可以获得 char* 然后将其转换为您需要的任何指针。这应该足以调用您的 Fortran 函数:

cdef char* as_bytes = f_contig.obj
some_function(<double*>as_bytes)

【讨论】:

    猜你喜欢
    • 2020-05-30
    • 2018-08-01
    • 2021-08-17
    • 2016-10-02
    • 2016-12-22
    • 2017-01-18
    • 2019-02-26
    • 2013-03-15
    • 2019-05-18
    相关资源
    最近更新 更多