admin管理员组文章数量:1395198
I'd like to use C++ typed map
s instead of Python dict
s, where the map
's keys are integers and values are typed Cython memoryviews. A minimal (non)working example is:
# distutils: language=c++
from libcpp.unordered_map cimport unordered_map as Map
cdef Map[int, int[:,:]] P;
where I get the compilation error
test.pyx:5:8: Reference-counted type 'int[:, :]' cannot be used as a template argument
Is there any way to specify objects of this type? I'd like to take full advantage of Cython's speed advantages, and that means using typed containers!
I'd like to use C++ typed map
s instead of Python dict
s, where the map
's keys are integers and values are typed Cython memoryviews. A minimal (non)working example is:
# distutils: language=c++
from libcpp.unordered_map cimport unordered_map as Map
cdef Map[int, int[:,:]] P;
where I get the compilation error
test.pyx:5:8: Reference-counted type 'int[:, :]' cannot be used as a template argument
Is there any way to specify objects of this type? I'd like to take full advantage of Cython's speed advantages, and that means using typed containers!
Share Improve this question edited Mar 27 at 4:34 InSync 11.1k4 gold badges18 silver badges56 bronze badges asked Mar 27 at 2:11 apizzimentiapizzimenti 4772 gold badges8 silver badges20 bronze badges1 Answer
Reset to default 0As the error says: "Reference-counted type 'int[:, :]
' cannot be used as a template argument", your example does not work because memoryviews are Python objects with reference counting, while C++ templates expect plain C++ types.
Depending on your applications, you first have to decide in which side is the memory managed, Python or C++?
If the memory is managed in C++ and used in Python, one can use a plain C++ container to hold the data, in your example, Map[int, vector[int]]
. If one wants to treat the vector in Map
as 2D arrays, one can use python memoryviews to view the vectors' underlying pointers, for example:
import numpy as np
from libcpp.vector cimport vector
cdef vector[int] a = [1, 2, 3, 4]
cdef int[:] va = <int[:4]>&a[0]
np_arr = np.asarray(va).reshape(2, 2)
print(np_arr)
# OWNDATA is False indicates momeory is not managed by numpy, but C++
print(np_arr.flags)
# Modify elements in the array will change the viewed vectors.
np_arr[1, 1] *= 10
print(a)
If the memory is managed in Python and used in C++, for example, numpy arrays hold the data and a std::unordered_map
holds the underlying data pointers:
import numpy as np
from libcpp.unordered_map cimport unordered_map as Map
cdef int[:, ::1] v0 = np.array([1, 2, 3, 4]).reshape(2, 2)
cdef int[:, ::1] v1 = np.array([5, 6, 7, 8]).reshape(2, 2)
# Treat the underlying data as 1D arrays
cdef Map[int, int*] P;
P[0] = &v0[0, 0]
P[1] = &v1[0, 0]
# Modify pointers in the map will change the elements of the underlying numpy arrays
P.at(0)[3] *= 10
print(np.asarray(v0))
In my experience, making it first who is responsible for the memory and exchanging data when necessary is a good practice and also efficient.
Warning: when using the memory through views or pointers, one has to make sure the underlying memory is not released.
本文标签: Cython specify typed memoryview as template type for C mapStack Overflow
版权声明:本文标题:Cython: specify typed memoryview as template type for C++ map - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744116477a2591536.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论