1

PyCUDAのヘルプでは、空またはゼロの配列を作成する方法は説明されていますが、既存の numpy 配列をページロック メモリに移動 (?) する方法は説明されていません。numpy 配列のポインターを取得してに渡す必要がありpycuda.driver.PagelockedHostAllocationますか? そして、どうすればそれを行うことができますか?

アップデート

<--狙撃 -->

更新 2

助けてくれてありがとうタロンミー。現在、メモリ転送はページロックされていますが、プログラムは次のエラーで終了します。

PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
cuMemFreeHost failed: invalid context

これは更新されたコードです:

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import numpy as np
import ctypes
from pycuda import driver, compiler, gpuarray
from pycuda.tools import PageLockedMemoryPool
import pycuda.autoinit

memorypool = PageLockedMemoryPool()

indata = np.random.randn(5).astype(np.float32)
outdata = gpuarray.zeros(5, dtype=np.float32)

pinnedinput = memorypool.allocate(indata.shape,np.float32)

source = indata.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
dest = pinnedinput.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
sz = indata.size * ctypes.sizeof(ctypes.c_float)
ctypes.memmove(dest,source,sz)


kernel_code = """
 __global__ void kernel(float *indata, float *outdata) {
 int globalid = blockIdx.x * blockDim.x + threadIdx.x ;
 outdata[globalid] = indata[globalid]+1.0f;

 }
 """

mod = compiler.SourceModule(kernel_code)
kernel = mod.get_function("kernel")

kernel(
 driver.In(pinnedinput), outdata,
 grid = (5,1),
 block = (1, 1, 1),
)
print indata
print outdata.get()
memorypool.free_held()
4

3 に答える 3

3

ソース配列から、pycuda から返されたページ ロック割り当てを保持する配列にデータをコピーする必要があります。これを行う最も簡単な方法は、次の方法ctypesです。

import numpy
import ctypes

x=numpy.array([1,2,3,4],dtype=numpy.double)
y=numpy.zeros_like(x)

source = x.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
dest = y.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
sz = x.size * ctypes.sizeof(ctypes.c_double)

ctypes.memmove(dest,source,sz)

print y

このnumpy.ctypesインターフェイスを使用して、配列データを保持するために使用されるメモリへのポインターを取得し、次にctypes.memmove2 つの異なる ndarray 間でコピーするために使用できます。ネイキッド C ポインターを使用する場合の通常の注意事項がすべて適用されるため、注意が必要ですが、使用するのは簡単です。

于 2011-10-09T18:06:21.627 に答える
1

メモリ ブロックはまだアクティブです。固定された配列を明示的に解放できます。

print memorypool.active_blocks
pinnedinput.base.free()
print memorypool.active_blocks
memorypool.free_held()
于 2015-05-04T19:28:21.213 に答える