1

練習用の簡単なCUDAプログラムを作成しました。ある配列から別の配列にデータをコピーするだけです。

import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np
from pycuda.compiler import SourceModule

# Global constants
N = 2**20 # size of array a
a = np.linspace(0, 1, N)
e = np.empty_like(a)
block_size_x = 512

# Instantiate block and grid sizes.
block_size = (block_size_x, 1, 1)
grid_size = (N / block_size_x, 1)

# Create the CUDA kernel, and run it.
mod = SourceModule("""
  __global__ void D2x_kernel(double* a, double* e, int N) {
    int tid = blockDim.x * blockIdx.x + threadIdx.x;
    if (tid > 0 && tid < N - 1) {
      e[tid] = a[tid];
    }
  }
""")
func = mod.get_function('D2x_kernel')
func(a, cuda.InOut(e), np.int32(N), block=block_size, grid=grid_size)
print str(e) 

ただし、次のエラーが発生します。pycuda._driver.LogicError: cuLaunchKernel failed: invalid value

カーネル関数の2番目の引数double* eを削除し、引数なしでカーネルを呼び出すとe、エラーはなくなります。何故ですか?このエラーはどういう意味ですか?

4

1 に答える 1

2

あなたのa配列はデバイスメモリに存在しないので、PyCUDAはカーネル呼び出しへの最初の引数を無視(または処理)し、通過するだけだeN思います...したがって、カーネルは3つの引数を期待していたため、エラーが発生します。受け取ったのは2つだけです。カーネル定義から削除double* eすると、表示されるエラーメッセージが削除される場合がありますが、それでもカーネルは正しく機能しません。

これに対する簡単な修正は、カーネルを起動する前にデバイスにコピーするようにPyCUDAに指示aする呼び出しをラップすることです。つまり、カーネル起動ラインは次のようになります。cuda.In()a

func(cuda.In(a), cuda.InOut(e), np.int32(N), block=block_size, grid=grid_size)

a編集:また、カーネルがの最初と最後の要素をにコピーしていないことに気づいていますeか?あなたのif (tid > 0 && tid < N - 1)声明はそれを妨げています。配列全体では、である必要がありますif (tid < N)

于 2012-11-02T17:13:08.567 に答える