【问题标题】:How to have a list of memory views in Cython?如何在 Cython 中有一个内存视图列表?
【发布时间】:2019-07-06 16:23:33
【问题描述】:

我的函数接受不同大小的 numpy 数组列表:

def function1(list list_of_numpy_arrays):

现在我在做:

cdef int[:] a_view = list_of_numpy_arrays[index]

问题是我必须多次索引列表,因此开销大大增加了时间(10 倍)。我正在寻找像cdef int[:] a[5] 这样的东西,我可以在其中拥有一组内存视图,这样我就可以避免索引 python 列表的开销。

如果有解决方案,我也可以传入列表列表。

def function2(list list_of_lists):

【问题讨论】:

  • 一些需要考虑的潜在问题。 1) 列表中是否有固定或最大数量的 numpy 数组? 2)是否有可能使所有的numpy数组都具有相同的形状,还是会导致过多的内存浪费? 3) 数组是否需要在 python 中作为 numpy 数组进行访问,还是仅在调用 function1 之后在 cython 端处理数据? 4)你需要能够使用[]语法来获取每个numpy数组,还是一个函数调用就足够了?
  • 1) 我可以将最大数量设为 20,但也可以更少。 2) 每个数组的大小是前一个数组的一半。 3) 我不必在 Python 中索引数组,但需要引用它们才能在 Cython 中再次调用它们。 4)我不确定你的意思,但我需要按索引获取每个 numpy 数组。
  • 如果你有这样的可预测数组大小(每个大小的一半),我会考虑为整个事情使用一个大的一维数组,并为每个“子数组”——这可能比我的回答更有意义......
  • 没错,这确实更有意义。感谢您的建议。

标签: python cython memoryview


【解决方案1】:

您所追求的在 Cython 中是不可能实现的。如果你想要一些表现良好的东西,我可能会创建一个 C 结构,其中包含来自 memoryview 的相关信息,然后改用它。这不是一个非常优雅的解决方案,但它会提供与使用 memoryviews 类似的性能;我不建议将其作为一种常见模式,但如果您的数据需要一次性解决问题,那没关系。

cdef struct FakeMemoryView:
    int* data
    int stride
    int length

如果您准备强制 C 连续内存查看 (int[::1]),那么您可以放弃 stride,因为它会被认为是一个。可以使用var.data[i*var.stride] 对数据进行索引。在您的函数开始时,您循环遍历您的 Python 列表以创建这些 FakeMemoryViews 的数组,然后从那时起您只需使用此数组:

def function1(list list_of_numpy_arrays):
    assert len(list_of_numpy_arrays) == 5

    cdef FakeMemoryView new_list[5]

    # initialize the list
    cdef int[:] mview
    for i in range(5):
        mview = list_of_numpy_arrays[i]
        new_list[i].data = &mview[0]
        new_list[i].stride = mview.strides[0]
        new_list[i].length = mview.shape[0]

    # example access - zero the first lot of data
    for i in range(new_list[0].length):
        new_list[0].data[i*new_list[0].stride] = 0

如果您事先不知道列表的长度,那么您需要使用mallocfree 自己处理内存。

此解决方案不处理 Numpy 数组的引用计数 - 因此您不应允许在持有 FakeMemoryViews 时释放 Numpy 数组。不要为多个函数调用存储数组,也不要开始从输入列表中删除数组。

【讨论】:

    猜你喜欢
    • 2019-11-20
    • 1970-01-01
    • 2016-07-15
    • 2020-11-18
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多