[PyCUDA] TypeError: ‘numpy.int32’ does not have the buffer interface
PyCUDAを使い始めています。チュートリアルも完全には動いてない状況です。
○環境
- Mac OS X Marverics
- Python 2.7 64bit(Anaconda)
- PyCuda 2014.01
- CUDA6.5
さて、今日詰まったのは、
# TypeError: 'numpy.int32' does not have the buffer interface
発生箇所というと、チュートリアル中の[Advanced Topics]->[Structures]です。
class DoubleOpStruct: mem_size = 8 + numpy.intp(0).nbytes def __init__(self, array, struct_arr_ptr): self.data = cuda.to_device(array) self.shape, self.dtype = array.shape, array.dtype cuda.memcpy_htod(int(struct_arr_ptr), numpy.int32(array.size)) cuda.memcpy_htod(int(struct_arr_ptr) + 8, numpy.intp(int(self.data))) def __str__(self): return str(cuda.from_device(self.data, self.shape, self.dtype)) struct_arr = cuda.mem_alloc(2 * DoubleOpStruct.mem_size) do2_ptr = int(struct_arr) + DoubleOpStruct.mem_size array1 = DoubleOpStruct(numpy.array([1, 2, 3], dtype=numpy.float32), struct_arr) array2 = DoubleOpStruct(numpy.array([0, 4], dtype=numpy.float32), do2_ptr) print("original arrays", array1, array2)
どうやらbuffer interfaceというのがPythonにはあるそうですが、上手く解決できていないのでしょうか?
簡単に調べたところ、バージョンによって、紆余曲折があるのようなないような。。。(Pythonをまだあまり知らず)
解決方法としては、numpy.getbufferでバッファインターフェイスを取得すると、動きました。
# cuda.memcpy_htod(int(struct_arr_ptr), numpy.int32(array.size)) cuda.memcpy_htod(int(struct_arr_ptr), numpy.getbuffer(numpy.int32(array.size)))
ただし、これが本当の正解であるのかわからず。。。
print関数も上手く動かないので、print命令へ変更。(仕様?)
ソースコード全てを載せておきます。自己責任で。
import pycuda.gpuarray as gpuarray import pycuda.driver as cuda import pycuda.autoinit import numpy from pycuda.compiler import SourceModule mod = SourceModule(""" struct DoubleOperation { int datalen, __padding; // so 64-bit ptrs can be aligned float *ptr; }; __global__ void double_array(DoubleOperation *a) { a = &a[blockIdx.x]; for (int idx = threadIdx.x; idx < a->datalen; idx += blockDim.x) { a->ptr[idx] *= 2; } } """) class DoubleOpStruct: mem_size = 8 + numpy.intp(0).nbytes def __init__(self, array, struct_arr_ptr): self.data = cuda.to_device(array) self.shape, self.dtype = array.shape, array.dtype cuda.memcpy_htod(int(struct_arr_ptr), numpy.getbuffer(numpy.int32(array.size))) cuda.memcpy_htod(int(struct_arr_ptr) + 8, numpy.getbuffer(numpy.intp(int(self.data)))) def __str__(self): return str(cuda.from_device(self.data, self.shape, self.dtype)) struct_arr = cuda.mem_alloc(2 * DoubleOpStruct.mem_size) do2_ptr = int(struct_arr) + DoubleOpStruct.mem_size array1 = DoubleOpStruct(numpy.array([1, 2, 3], dtype=numpy.float32), struct_arr) array2 = DoubleOpStruct(numpy.array([0, 4], dtype=numpy.float32), do2_ptr) print "original arrays", array1, array2 func = mod.get_function("double_array") func(struct_arr, block = (32, 1, 1), grid=(2, 1)) print "doubled arrays", array1, array2 func(numpy.intp(do2_ptr), block = (32, 1, 1), grid=(1, 1)) print "doubled second only", array1, array2, "\n"
出力結果
original arrays [ 1. 2. 3.] [ 0. 4.] doubled arrays [ 2. 4. 6.] [ 0. 8.] doubled second only [ 2. 4. 6.] [ 0. 16.]
-
前の記事
PyCUDAをWindows7にインストール 2014.09.20
-
次の記事
o’zzio MXA232150SDSにGTX750Tiカードを装着 2014.09.23