CUDA пишет только в первые несколько элементов массива - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть структура данных с именем mol, которую я пытаюсь выполнить с использованием ядра CUDA. Это выглядит так:

typedef struct {
    float x, y, z;
} VecR;

typedef struct {
  VecR r, rv, ra;
} Mol;

Я инициализирую указатель (Mol *mol), выделяю пространство в объединенной памяти, инициализирую массив на хосте, чтобы в итоге получилось нечто подобное передается в ядро:

mol[foo] = {r = {x = -3.3927002, y = 1.72338998, z = 1.32186997}, rv = {x = 0.0281415954, y = 0.162121773, z = 0.606185317}, ra = {x = 0, y = 0, z = 0}}

Затем я передаю его этому ядру, которое должно выполнять вычисления для каждого из элементов и сохранять значения в соответствующих местах в массиве:

__global__ void computeForces(Mol *mol) {
    int j1 = blockIdx.x * blockDim.x + threadIdx.x;
    int j2 = 0;
    VecR dr;
    real fcVal, rr, rrCut, rri, rri3;
    rrCut = Sqr(rCut);
    mol[j1].ra.x = 0;
    mol[j1].ra.y = 0;
    mol[j1].ra.z = 0;
        for (j2 = 0; j2 < nMol && j2!=j1; j2++) {
        dr.x = mol[j1].r.x, mol[j2].r.x;
        dr.y = mol[j1].r.y, mol[j2].r.y;
        dr.z = mol[j1].r.z, mol[j2].r.z;
        rr = VLenSq(dr); //This just the sum square of the values in dr
        //Cutoff
        if (rr < rrCut) {
            rri = 1. / rr;
            rri3 = Cube(rri);
            fcVal = 48. * rri3 * (rri3 - 0.5) * rri;
            Mol anchor = mol[j1];
            float fcValdrx = fcVal*dr.x;
            float fcValdry = fcVal*dr.y;
            float fcValdrz = fcVal*dr.z;
            atomicAdd(&(mol[j2].ra.x), -fcValdrx);
            atomicAdd(&(mol[j2].ra.y), -fcValdry);
            atomicAdd(&(mol[j2].ra.z), -fcValdrz);
        }
    }
}

В итоге я должен получить ra.x, ra.y, ra.z порядка 1e0 или 1e-1 для каждого элемента массива. Однако, это не так. Для первых нескольких (возможно, 10) элементов в mol значения ra.x, ra.y, ra.z являются огромными, казалось бы, случайными числами (порядка 1e40). Для остальных элементов I я получаю 0 для этих значений.

Мне кажется, что я не обращаюсь к памяти правильно, но я недостаточно знаком с деталями функций управления памятью CUDA, чтобы точно понять, что происходит. Я изучил __threadfence() и __syncthreads(), но все еще не уверен, как именно их применять.

...