gpt4 book ai didi

arrays - 基于共享内存的1d模具CUDA实现中的负数组索引

转载 作者:行者123 更新时间:2023-12-04 13:22:55 25 4
gpt4 key购买 nike

我目前正在使用CUDA编程,并且正在尝试从我在网上找到的研讨会(可以在here上找到)中学习幻灯片。我遇到的问题是幻灯片48。在此可以找到以下代码:

__global__ void stencil_1d(int *in, int *out) {

__shared__ int temp[BLOCK_SIZE + 2 * RADIUS];

int gindex = threadIdx.x + blockIdx.x * blockDim.x;
int lindex = threadIdx.x + RADIUS;

// Read input elements into shared memory
temp[lindex] = in[gindex];
if (threadIdx.x < RADIUS) {
temp[lindex - RADIUS] = in[gindex - RADIUS];
temp[lindex + BLOCK_SIZE] = in[gindex + BLOCK_SIZE];
}

....

添加一些上下文。我们有一个名为 in的数组,其长度称为 N。然后,我们有另一个数组 out,其长度为 N+(2*RADIUS),其中对于此特定示例, RADIUS的值为 3。这个想法是将 in数组复制到 out数组中,但是将 in数组从 3数组的开始位置放置在 out位置,即 out = [RADIUS][in][RADIUS],请参见幻灯片中的图形表示。

困惑出现在以下行中:
 temp[lindex - RADIUS] = in[gindex - RADIUS];

如果gindex是 0,那么我们有 in[-3]。我们如何从数组中的负索引中读取?任何帮助将不胜感激。

最佳答案

pQB的答案是正确的。您应该将输入数组指针偏移RADIUS

为了说明这一点,我在下面提供了一个完整的示例。希望对其他用户有帮助。

(我想说的是,共享内存加载后,您将需要一个__syncthreads()。我在下面的示例中添加了它)。

#include <thrust/device_vector.h>

#define RADIUS 3
#define BLOCKSIZE 32

/*******************/
/* iDivUp FUNCTION */
/*******************/
int iDivUp(int a, int b){ return ((a % b) != 0) ? (a / b + 1) : (a / b); }

/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}

/**********/
/* KERNEL */
/**********/
__global__ void moving_average(unsigned int *in, unsigned int *out, unsigned int N) {

__shared__ unsigned int temp[BLOCKSIZE + 2 * RADIUS];

unsigned int gindexx = threadIdx.x + blockIdx.x * blockDim.x;

unsigned int lindexx = threadIdx.x + RADIUS;

// --- Read input elements into shared memory
temp[lindexx] = (gindexx < N)? in[gindexx] : 0;
if (threadIdx.x < RADIUS) {
temp[threadIdx.x] = (((gindexx - RADIUS) >= 0)&&(gindexx <= N)) ? in[gindexx - RADIUS] : 0;
temp[threadIdx.x + (RADIUS + BLOCKSIZE)] = ((gindexx + BLOCKSIZE) < N)? in[gindexx + BLOCKSIZE] : 0;
}

__syncthreads();

// --- Apply the stencil
unsigned int result = 0;
for (int offset = -RADIUS ; offset <= RADIUS ; offset++) {
result += temp[lindexx + offset];
}

// --- Store the result
out[gindexx] = result;
}

/********/
/* MAIN */
/********/
int main() {

const unsigned int N = 55 + 2 * RADIUS;

const unsigned int constant = 4;

thrust::device_vector<unsigned int> d_in(N, constant);
thrust::device_vector<unsigned int> d_out(N);

moving_average<<<iDivUp(N, BLOCKSIZE), BLOCKSIZE>>>(thrust::raw_pointer_cast(d_in.data()), thrust::raw_pointer_cast(d_out.data()), N);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());

thrust::host_vector<unsigned int> h_out = d_out;

for (int i=0; i<N; i++)
printf("Element i = %i; h_out = %i\n", i, h_out[i]);

return 0;

}

关于arrays - 基于共享内存的1d模具CUDA实现中的负数组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26625038/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com