Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 来自cuda内核的函数调用无法正常工作_C++_Cuda - Fatal编程技术网

C++ 来自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 =

我有以下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 = 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;
}