C++ 来自cuda内核的函数调用无法正常工作
我有以下cuda内核:C++ 来自cuda内核的函数调用无法正常工作,c++,cuda,C++,Cuda,我有以下cuda内核: template <class T,typename Func> __global__ void for_each_kernel (T* d_v,int N,Func f) { int idx = blockIdx.x*blockDim.x + threadIdx.x; int num_threads = gridDim.x * blockDim.x; __shared__ T s_x[1024]; for(int i =
template <class T,typename Func>
__global__
void for_each_kernel (T* d_v,int N,Func f)
{
int idx = blockIdx.x*blockDim.x + threadIdx.x;
int num_threads = gridDim.x * blockDim.x;
__shared__ T s_x[1024];
for(int i = idx; i < N; i += num_threads)
{
s_x[threadIdx.x] = d_v[i];
f(&s_x[threadIdx.x]); // This Does Not Work Correctly
//s_x[threadIdx.x] *= 10; // This Works Correctly
d_v[i] = s_x[threadIdx.x];
}
}
下面是内核调用的发生方式:
template <typename Func>
void for_each (int start,int end,Func f)
{
for_each_kernel<<<26,1024>>> (d_v,end-start+1,f);
}
问题是您正在将一个
\uuu设备\uu
函数指针从主机传递到内核。直接从主机获取设备符号的地址是非法的。您必须使用cudaMemcpyFromSymbol
获取主机端设备符号的地址。
在当前代码中,您必须创建一个主机端函数指针,指向\uuu设备\uu
函数,并将其传递给内核。可按如下方式进行:
#include <cstdio>
using namespace std;
__device__
void func(int *x)
{
*x = (*x) * 10;
}
template <class T,typename Func>
__global__
void for_each_kernel (T* d_v,int N,Func f)
{
int idx = blockIdx.x*blockDim.x + threadIdx.x;
int num_threads = gridDim.x * blockDim.x;
__shared__ T s_x[1024];
for(int i = idx; i < N; i += num_threads)
{
s_x[threadIdx.x] = d_v[i];
f(&s_x[threadIdx.x]);
//s_x[threadIdx.x] *= 10;
d_v[i] = s_x[threadIdx.x];
}
}
template <class T>
class device_vector
{
T *d_v;
int numEle;
public :
device_vector (T *h_v,int N)
{
cudaMalloc ((T**)&d_v,N*sizeof(T));
cudaMemcpy(d_v, h_v, N * sizeof(T), cudaMemcpyHostToDevice);
numEle = N;
}
void set (T data,int index)
{
cudaMemcpy (&d_v[index],&data,sizeof(T),cudaMemcpyHostToDevice);
}
T get (int index)
{
T temp;
cudaMemcpy (&temp,&d_v[index],sizeof(T),cudaMemcpyDeviceToHost);
return temp;
}
void getRange (T *dest,T *start,int N)
{
cudaMemcpy (dest,start,sizeof(T)*N,cudaMemcpyDeviceToHost);
}
// Only Provide Start And End Vertices Fot Which you Want To Do Some Operation
template <typename Func>
void for_each (int start,int end,Func f)
{
for_each_kernel<<<26,1024>>> (d_v,end-start+1,f);
}
};
int a[1<<28];
int main ()
{
int N = 1<<28;
for (int i=0;i<N;i++)
a[i] = i;
device_vector<int> d (a,N);
d.for_each (0,N-1,func);
printf ("Getting Element At Index %d : %d \n",100,d.get(10));
return 0;
}
//Declare function pointer
typedef void(*pFunc)(int*);
//Function pointer on device
__device__ pFunc f_device = func;
int main()
{
int N = 1 << 28;
for (int i = 0; i<N; i++)
a[i] = i;
device_vector<int> d(a, N);
//Function pointer on host
pFunc f_host;
//Copy address of device function to host
cudaMemcpyFromSymbol(&f_host, f_device, sizeof(pFunc));
d.for_each(0, N - 1, f_host);
printf("Getting Element At Index %d : %d \n", 100, d.get(100));
return 0;
}
//声明函数指针
类型定义无效(*pFunc)(内部*);
//设备上的函数指针
__设备_uupfunc f_设备=func;
int main()
{
int N=1在有人告诉您错误之前,您需要提供一个完整的重新编译案例。可能是您没有将有效的设备函数传递给内核,但没有向您显示,因此无法确定。@Talonmes在我的问题中,我已经给出了我的设备函数。我还向您提供了kernel已启动。我还应该给出什么…?是的。问题在于您选择不包含在问题中的代码。@PRP-这是一个温和的提示,所有相关代码都必须包含在这个问题中。问题的价值在于让其他人知道问题是什么,而不仅仅是让您解决问题并继续前进。相关。
//Declare function pointer
typedef void(*pFunc)(int*);
//Function pointer on device
__device__ pFunc f_device = func;
int main()
{
int N = 1 << 28;
for (int i = 0; i<N; i++)
a[i] = i;
device_vector<int> d(a, N);
//Function pointer on host
pFunc f_host;
//Copy address of device function to host
cudaMemcpyFromSymbol(&f_host, f_device, sizeof(pFunc));
d.for_each(0, N - 1, f_host);
printf("Getting Element At Index %d : %d \n", 100, d.get(100));
return 0;
}