【问题标题】:call cuda from c results in errors从 c 调用 cuda 会导致错误
【发布时间】:2014-03-14 01:00:09
【问题描述】:

我收到的错误是:

‘blockIdx’未在此范围内声明 “

“>”标记之前的预期主表达式

“

“>”标记之前的预期主表达式

(“”指的是内核调用>>)

另外,在我收到的主要功能中:

错误:无法将参数“1”转换为“void”的“float*”到“float” kernel_wrapper(float*, float*, int, int)

cu 文件:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <math.h>
#include <curand_kernel.h>
#include <cuda_runtime.h>
#include <cuda.h>

.....
__global__ void kernel(float* A,float *B, curandState* globalState, int Asize,int Bsize)
{
...

void kernel_wrapper(float* A_host,float* B_host, int Asize ,int Bsize)
{
...
//allocate host memory 
    A_host=(float*)malloc(Asize*sizeof(float));
    B_host=(float*)malloc(Bsize*sizeof(float));

    //allocate device memory
    float* A_dev,*B_dev;
    cudaMalloc((void**) &A_dev,Asize* sizeof(float));
    cudaMalloc((void**) &B_dev,Bsize* sizeof(float));
....

 kernel<<<1,1>>>(A_host,B_host, devStates,Asize,Bsize);
...

c 文件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include "solve.cu"


extern void kernel_wrapper(float* A,float* B, int Asize ,int Bsize);
...
int main()
{...
A = (float*)malloc(N*N*sizeof(float));
B = (float*)malloc(N*HS*sizeof(float));
...
kernel_wrapper(A,B,Asize ,Bsize);
...

我编译为:

 g++ -o mycode myfile.c -I/usr/local/cuda-5.5/include -L/usr/local/cuda-5.5/lib64 -lcurand -lcutil -lcudpp -lcuda -lstdc+

【问题讨论】:

  • A和B是如何声明的?而blockIdx的代码呢?
  • 还有:g++是用来编译c++源的,这个是C还是C++?
  • @David Kernin:我声明为 float* A = NULL;和 B 一样,然后我像上面一样分配(A = (float*)malloc(NNsizeof(float));)。文件是 c,但我使用 g++ 来处理 cu包含 iostream 等的文件。
  • 如果那是 C,它应该用 gcc 而不是 g++ 编译,并且你不能链接到 stdc++。还编译 .cu 文件,如下 Robert 所述。如果它只包含 cpp 代码,那么 g++ 也可以工作。
  • @David Kernin:好的,我将文件重命名为 cpp,当我执行 g++ -c -I/usr/local/cuda-5.5/include myfile.cpp 时,它显示所有错误为我在帖子里

标签: c cuda


【解决方案1】:

您不能在.c 文件中包含包含设备代码(例如内核)的solve.cu,然后使用g++ 正确编译它

设备代码必须由nvcc编译

相反,您需要分别编译这两个文件,然后将它们链接在一起。

我建议将您的 myfile.c 重命名为 myfile.cpp

另外删除这行从你的myfile.cpp:

#include "solve.cu"

然后编译:

nvcc -c solve.cu
g++ -c -I/usr/local/cuda-5.5/include  myfile.cpp 
g++ -o mycode solve.o myfile.o -L/usr/local/cuda-5.5/lib64 -lcudart -lcurand -lcutil -lcudpp -lcuda

对于最后一个问题,您传递的是双指针 (**):

kernel_wrapper(&A,&B,Asize ,Bsize);

原型需要单指针的地方 (*):

extern void kernel_wrapper(float* A,float* B, int Asize ,int Bsize);

A 和 B 已经属于 float * 类型,所以在我看来你应该直接传递它们:

kernel_wrapper(A,B,Asize ,Bsize);

编辑:回答以下问题。

问题是指针A_host 和B_host(kernel_wrapper 的参数)被按值传递给内核包装函数,内核包装函数正在为那些指针,但是反映分配存储的新修改的指针没有(不能)被传递回调用函数(即调用kernel_wrapper的函数)。

您可以在调用函数中为A_host 和B_host 分配存储空间,然后传递指针(然后不需要malloc kernel_wrapper 中的那些指针),或者您可以将内核包装器修改为如下:

void kernel_wrapper(float** A_host,float** B_host, int Asize ,int Bsize)
{
...
//allocate host memory 
    *A_host=(float*)malloc(Asize*sizeof(float));
    *B_host=(float*)malloc(Bsize*sizeof(float));

    //allocate device memory
    float* A_dev,*B_dev;
    cudaMalloc((void**) &A_dev,Asize* sizeof(float));
    cudaMalloc((void**) &B_dev,Bsize* sizeof(float));
....
 cudaMemcpy(A_dev, *A_host, Asize*sizeof(float), cudaMemcpyHostToDevice);
 cudaMemcpy(B_dev, *B_host, Bsize*sizeof(float), cudaMemcpyHostToDevice);

 kernel<<<1,1>>>(A_dev,B_dev, devStates,Asize,Bsize);
...

您还需要修改 .cpp 文件中的调用行:

int main()
{...
  float *A, *B;
  int Asize = N*N;
  int Bsize = N*NHS;
...
  kernel_wrapper(&A,&B,Asize ,Bsize);
...

您的代码现在发布的方式是,您对A 和B 分别执行两次malloc 操作,这不是必需的。

【讨论】:

  • :当我使用 g++ -c -I.... myfile.cpp 进行编译时,它给了我帖子中的所有错误。
  • 不要链接到 stdc++
  • @Robert Crovella:好的,好点,我删除了它。现在我只接受最后一个错误 cannot convert ‘float**’ to ‘float*’ for argument ‘1’
  • 我不写答案,因为罗伯特已经写了我必须写的所有内容,这将毫无意义。
  • 这只是一个基本的 C/C++ 问题。我已经更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 2020-05-29
  • 2012-10-22
  • 2019-11-21
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多