I have the following cuda Kernel :
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];
}
}
When I call a function f
it print the wrong value. But when I do the multiplication directly, it works.
Both portions are highlighted in the comments.
Here is the function which is passed :
__device__
void func(int *x)
{
*x = (*x) * 10;
}
Here is how the kernel call is happening :
template <typename Func>
void for_each (int start,int end,Func f)
{
for_each_kernel<<<26,1024>>> (d_v,end-start+1,f);
}
Each of a[i] is initialized to i.
The value that I am printing is a[10]
, which should print 100.
But it is printing 32767 which is 2^15 - 1.
The complete example code which exhibits the problem is as follows:
#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;
}