Cython数组中的值会随机更改。

huangapple go评论59阅读模式
英文:

The value in cython array is changed randomly

问题

以下是您提供的代码的中文翻译:

这是我的Cython代码。

self.point_index_array 属性是一个数组,其值从0开始递增。

> [0, 1, 2, 3, 4, 5, .....]

当首次声明时,这些值是正常的,但当从另一个函数中访问该数组时,前四个元素的值会自动更改。

Python 和 Cython 版本

  • Python 3.9.13
  • Cython 0.29.34

这是我的伪代码

cdef class KdTree:
    cdef uint32_t* point_index_array

    def __cinit__(KdTree self):
        self.point_index_array = NULL

    def __init__(KdTree self, 
                 np.ndarray points not None, 
                 int num_of_leaf=16):
        cdef np.ndarray[uint32_t, ndim=1] point_index_list
        point_index = np.arange(0, self.num_of_points, dtype=np.uint32)
        point_index_list = np.ascontiguousarray(point_index.ravel(), dtype=np.uint32)
        self.point_index_array = <uint32_t*>point_index_list.data

        # kdtree...

        # 这是正常的
        self.print_index_array()

    def print_index_array(self):
        for index in range(10):
          print(f"index {index} => {self.point_index_array[index]}")

    def neighbor_search(self, float distance):
        # self.point_index_array 中的值会改变
        self.print_index_array()

正常输出(__init__

> index 0 => 390
index 1 => 469
index 2 => 493
index 3 => 492
index 4 => 396
index 5 => 490
index 6 => 397
index 7 => 117
index 8 => 484
index 9 => 9

异常输出(neighbor_search

> index 0 => 1171518192
index 1 => 504
index 2 => 1174758304
index 3 => 504
index 4 => 396
index 5 => 490
index 6 => 397
index 7 => 117
index 8 => 484
index 9 => 9

我不明白为什么会发生这种情况。您能告诉我我漏掉了什么吗?

英文:

Here is my cython code.

self.point_index_array attribute is array whose values increase by 1 from 0.

> [0, 1, 2, 3, 4, 5, .....]

The values are normal when first declared, but when the array is accessed from another function, the values of the first four elements are automatically changed.

python and cython version

  • Python 3.9.13
  • Cython 0.29.34

Here is my sudo code

cdef class KdTree:
    cdef uint32_t* point_index_array

    def __cinit__(KdTree self):
        self.point_index_array = NULL

    def __init__(KdTree self, 
                 np.ndarray points not None, 
                 int num_of_leaf=16):
        cdef np.ndarray[uint32_t, ndim=1] point_index_list
        point_index = np.arange(0, self.num_of_points, dtype=np.uint32)
        point_index_list = np.ascontiguousarray(point_index.ravel(), dtype=np.uint32)
        self.point_index_array = <uint32_t*>point_index_list.data
    
        # kdtree...

        # its normal
        self.print_index_array()

    def print_index_array(self):
        for index in range(10):
          print(f"index {index} => {self.point_index_array[index]}")


    def neighbor_search(self, float distance):
        # values in self.point_index_array are changed 
        self.print_index_array()

normal output is (__init__)

> index 0 => 390
index 1 => 469
index 2 => 493
index 3 => 492
index 4 => 396
index 5 => 490
index 6 => 397
index 7 => 117
index 8 => 484
index 9 => 9

abnormal output is (neighbor_search)

> index 0 => 1171518192
index 1 => 504
index 2 => 1174758304
index 3 => 504
index 4 => 396
index 5 => 490
index 6 => 397
index 7 => 117
index 8 => 484
index 9 => 9

I don't understand why this happens at all.

Could you let me know what I'm missing?

答案1

得分: 0

Here is the translated content:

@slothrop 感谢您的赏识!

"point_index_list" 变量是前面代码中的 Python 对象,因此被垃圾收集器移除了。

因此,我将此对象保存到类属性中。

cdef class KdTree:
  cdef uint32_t* point_index_array
  cdef readonly np.ndarray point_index_list

  def __init__(KdTree self, 
                np.ndarray points 不为 None, 
                int num_of_leaf=16):

    point_index = np.arange(0, self.num_of_points, dtype=np.uint32)

    # 这段代码将防止 point_index_list 被 CG(垃圾收集)
    self.point_index_list = np.ascontiguousarray(point_index.ravel(), dtype=np.uint32)
    self.point_index_array = <uint32_t*>self.point_index_list.data

(Note: I've left the code parts as is, as per your request, and only translated the surrounding text.)

英文:

@slothrop thanks for your appreciate!

"point_index_list" variable is python object in previous code, so it was removed by GC.

so, i save this object to class attribute.

cdef class KdTree:
  cdef uint32_t* point_index_array
  cdef readonly np.ndarray point_index_list

  def __init__(KdTree self, 
                np.ndarray points not None, 
                int num_of_leaf=16):

    point_index = np.arange(0, self.num_of_points, dtype=np.uint32)

    # this code will prevent CG of point_index_list
    self.point_index_list = np.ascontiguousarray(point_index.ravel(), dtype=np.uint32)
    self.point_index_array = <uint32_t*>self.point_index_list.data

huangapple
  • 本文由 发表于 2023年5月21日 16:24:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76298936.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定