【问题标题】:argument of type "int *" is incompatible with parameter of type "int" in cuda kernel call“int *”类型的参数与 cuda 内核调用中“int”类型的参数不兼容
【发布时间】:2017-05-19 03:03:28
【问题描述】:

我已经尝试了一段时间,并且遇到了已经发布的看似相似的问题,但是由于某种原因,我仍然无法清除错误。正如我所看到的那样,我实际上想将 2D 矩阵作为 1D 数组传递给内核。我不确定我的语法哪里出错了,但是在我提供给内核的变量和内核期望的参数方面存在冲突。

__global__ void calculatePath(int source, int target, int *cost, int distance){

int t_id = blockIdx.x * blockDim.x + threadIdx.x;


int dist[50];
int prev[50];
int selected[50]={0};
int num_path[50];

int d, m, min, start, j;

if ((t_id > 0) && (t_id < N)){
    dist[t_id] = IN;
    prev[t_id] = -1;
}

这是我的内核函数,它的参数都是整数,除了“cost”,它是一个指向整数数组的指针。

int main(int argc, char **argv){


int h_num_path[N];
int h_distance = 0;
int h_cost[N][N],i,j,co;
int h_source;
int h_target;

printf("\tShortest Path Algorithm(DIJKSRTRA's ALGORITHM\n\n");
for(i=0;i< N;i++)
    for(j=0;j< N;j++)
        h_cost[i][j] = IN;

//*********************
srand ( time(NULL));
for(int x=1;x< N;x++) {
    for (int y = x + 1; y < N; y++) {
        h_cost[x][y] = h_cost[y][x] = (rand() % 100) + 1;
    }
}

printf("\nEnter The Source: ");
scanf("%d", &h_source);
printf("\nEnter The target: ");
scanf("%d", &h_target);

int *d_num_path;
int *d_cost;
int *d_source;
int *d_target;
int *d_dist;
int *d_prev;
int *d_distance;

cudaMalloc(&d_num_path, sizeof(int)*N);
cudaMalloc(&d_cost, sizeof(int)*N*N);

cudaMalloc((void**) &d_source, sizeof(int));
cudaMalloc((void**) &d_target, sizeof(int));
cudaMalloc((void**) &d_dist, sizeof(int)*N);
cudaMalloc((void**) &d_distance, sizeof(int));

cudaMemcpy(d_source, &h_source, sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(d_target, &h_target, sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(d_cost, h_cost, sizeof(int)*N*N, cudaMemcpyHostToDevice);
cudaMemcpy(d_distance, &h_distance, sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(d_num_path, &h_num_path, sizeof(int)*N, cudaMemcpyHostToDevice);

clock_t before;
before = clock();

calculatePath<<<N/512 + 1, 512>>>(d_source, d_target, d_cost, d_distance);

clock_t time_taken = clock() - before;

cudaMemcpy(&h_num_path, d_num_path, sizeof(int)*N, cudaMemcpyDeviceToHost);
cudaMemcpy(&h_distance, d_distance, sizeof(int), cudaMemcpyDeviceToHost);

cudaFree(d_num_path);
cudaFree(d_cost);
cudaFree(d_source);
cudaFree(d_target);
cudaFree(d_dist);
cudaFree(d_prev);
cudaFree(d_distance);

printf("\nShortest Path: %d \n",co);
printf("%s %.4f %s", "Time taken:", time_taken/1000.0, "seconds");

return 0;

}

在内核调用中,我收到“'int *' 类型的参数与 'int' 类型的参数不兼容”的错误,但我相信我的 d_cost 已经是一个指针。我很高兴能直截了当,因为我确信我忽略了一些小事。

【问题讨论】:

  • I'm not sure where I've gone wrong in my syntax 阅读您的错误/警告argument of type “int *” is incompatible with parameter of type “int” ll
  • 这就是错误消息告诉你的内容:你相信d_cost 是一个指针,它就是。但该函数需要int
  • @JpDizzy 你知道 Argument 和 parameter 有什么区别吗?
  • cudaMalloc()的函数签名是什么?
  • 不,它不需要 C 标签,这就是我删除它的原因。两次。这是一个 CUDA 问题,代码不是 C

标签: cuda


【解决方案1】:

您遇到问题的不是d_target。其他三个参数是int*,但对应的参数声明为int

K&R 在第 25 页的 C 编程语言说:

我们通常将 parameter 用于函数定义中括号列表中命名的变量,argument 用于函数调用中使用的值。 p>

由于您的sourcetarget 只是一个整数值,因此您实际上不需要为它们定义设备端变量。只需将整数值本身作为参数传递。通过这样做,您将获得 talonmies 评论的性能改进:

(通过值传递)如果这样做,内核中会持续广播内存缓存。为简单常量传递指针只会增加延迟,因为它会强制每个线程取消引用指针以从全局内存中检索值,以及首先分配所有额外的主机端内存 API。

另外,你似乎希望参数distance 有你内核的输出值,那么它必须声明为一个指针,所以你可以在内核之后做cudaMemcpyDeviceToHost

__global__ void calculatePath(int source, int target, int *cost, int *distance) // kernel definition

caculatePath<<< (N + 511) / 512, 512 >>>(h_source, h_target, d_cost, d_distance) // kernel launch

【讨论】:

    【解决方案2】:

    您的三个参数必须是整数,但您正在传递指向整数的指针。您需要更改方法签名:

    __global__ void calculatePath(int *source, int *target, int *cost, int *distance)
    

    【讨论】:

    • 但是你不能取消引用这些指针。它们不是主机地址空间中的有效指针
    • @talonmies - 最初,这些指针没有指向任何东西(它应该在开始时设置为 NULL。)。但是 cudaMalloc() 将分配内存并且使用 cudaMemcpy() 设置值。为什么取消引用在这里不起作用?
    • @Nguaial:分配给指针的值是 GPU 内存中的地址。它们在主机中无效,如果取消引用会导致段错误
    • @Nguai - cudaMalloc 将它们分配在 GPU 内存空间中,而不是在主机内存空间中
    • @ChrisRouffer:问题是,这仍然不是一个好的答案。 正确的 答案是按值传递。如果以这种方式完成,那么内核中就会有持续的内存缓存广播。为简单常量传递指针只会增加延迟,因为它会强制每个线程取消引用指针以从全局内存中检索值,再加上所有添加的主机端 API 内存以首先分配它们
    猜你喜欢
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 1970-01-01
    相关资源
    最近更新 更多