私は答えを見つけることができませんが、それは単純なものでなければなりません。私はセルオートマトンの状態を計算する必要があるプログラムを書いています.CUDAがどのように機能するかを理解するために、最初に非常に単純なプログラムを作成しようとしました. 行列を取り、すべてのスレッドはそのセルと、このセルの上下にあるセルの値をインクリメントする必要があります。したがって、次のマトリックスを指定すると:
[0 0 0 0 0 0 0]
[0 0 0 0 0 0 0]
[0 0 0 0 0 0 0]
[0 0 0 0 0 0 0]
[0 0 0 0 0 0 0]
[0 0 0 0 0 0 0]
[0 0 0 0 0 0 0]
次の結果が得られることを期待しています。
[2 2 2 2 2 2 2]
[3 3 3 3 3 3 3]
[3 3 3 3 3 3 3]
[3 3 3 3 3 3 3]
[3 3 3 3 3 3 3]
[3 3 3 3 3 3 3]
[2 2 2 2 2 2 2]
最初の行の値は 2 です。これは、最初の行の値をもう一度インクリメントできる行がないためです。同様の方法で、最後の行の値は 2です。
しかし、次のような行列を取得しています。
[2 2 2 2 2 2 2]
[3 3 3 3 3 3 3]
[3 3 3 3 3 3 3]
[3 3 3 3 2 2 2]
[2 2 2 2 2 2 2]
[2 2 2 2 3 3 3]
[2 2 2 2 2 2 2]
そして、4行目、5行目、6行目に2の値がある理由を理解できません.2ではなく3でなければなりません.
ここに私のコードがあります:
import numpy
import pycuda.autoinit
import pycuda.driver as cuda
from pycuda.compiler import SourceModule
w = 7
mod = SourceModule("""
__global__ void diffusion( int* result, int width, int height) {
int xIndex = blockDim.x * blockIdx.x + threadIdx.x;
int yIndex = blockDim.y * blockIdx.y + threadIdx.y;
int flatIndex = xIndex + width * yIndex;
int topIndex = xIndex + width * (yIndex - 1);
int bottomIndex = xIndex + width * (yIndex + 1);
int inc = 1;
result[flatIndex] += inc;
result[bottomIndex] += inc;
result[topIndex] += inc;
}
""")
diff_func = mod.get_function("diffusion")
def diffusion(res):
height, width = numpy.int32(len(res)), numpy.int32(len(res[0]))
diff_func(
cuda.InOut(res),
width,
height,
block=(w,w,1)
)
def run(res, step):
diffusion(res)
print res
res = numpy.array([[0 \
for _ in xrange(0, w)]\
for _ in xrange(0, w)], dtype='int32')
run(res, 0)
もう 1 つ興味深い点: 次の行のいずれかをコメントすると、次のようになります。
result[bottomIndex] += inc;
result[topIndex] += inc;
すべてが期待どおりに機能し、予期しない値はありません。場合によっては、CUDA が 1 つのスレッドで隣接する 3 つのセルの値を処理できないようです。