我们可以使用任何方法在CUDA内核中复制数组吗?
例如:
__device__ int number_element;
__device__ void copyData(float* input, float* output){}
我想将某些输入数组中的数据复制到满足某些条件的输出,并将复制的元素数量复制到 number_element
谢谢。
答案 0 :(得分:1)
您真正描述的内容称为流压缩。推力库内置了一系列流压缩函数,可以在内核中调用。作为一个简单的例子:
#include <iostream>
#include <thrust/copy.h>
#include <thrust/execution_policy.h>
struct op
{
__host__ __device__
bool operator()(const int x) { return (x % 3) == 0; }
};
__global__ void kernel(int* input, int* output, int Nin, int* Nout)
{
auto output_end = thrust::copy_if(thrust::device, input, input + Nin, output, op());
*Nout = output_end - output;
}
int main()
{
const int N = 10;
const size_t sz = sizeof(int) * size_t(N);
int* in;
cudaMallocManaged((void **)&in, sz);
int* out;
cudaMallocManaged((void **)&out, sz);
int* Nout;
cudaMallocManaged((void **)&Nout, sizeof(int));
for(int i=0; i<N; i++) {
in[i] = 1+i;
out[i] = -1;
}
kernel<<<1,1>>>(in, out, N, Nout);
cudaDeviceSynchronize();
for(int i=0; i < *Nout; i++) {
std::cout << i << " " << out[i] << std::endl;
}
return 0;
}
编译和运行如下:
$ nvcc -std=c++11 -arch=sm_52 thrust_device_compact.cu
$ ./a.out
0 3
1 6
2 9
这可能是在内核中对少量数据执行流压缩的快速简便方法。如果您有大量数据,那么使用来自主机的推力并代表您推送内核可能更有意义。
答案 1 :(得分:0)
是的,你可以写一个。
例如,你可以按照这个答案的方式进行:Best way to copy global into shared memory,只需跳过涂抹部分。
//assumes sizeof(T) is multiple of sizeof(int) and is aligned to at least alignof(int)
//assumes single-dimention kernel
//assumes it is launched for all threads in block
template <typename T>
__device__ void memCopy(T* dest, T* src, size_t size) {
int* iDest = (int*)dest;
int* iSrc = (int*)src;
for(size_t i = threadIdx.x; i<size*sizeof(T)/sizeof(int); i+=blockDim.x)
iDest[i] = iSrc[i];
__syncthreads();
}
这假定单个块操作,旨在用于该特定块。
如果你想要一个完整的网格,你可以,但需要将它作为一个单独的内核启动,以确保所有其他块都可以看到所有写入。在这种情况下,cudaMemcpy
可能比内核调用更好。
在任何情况下,对于网格操作,您需要更改循环:
for(size_t i = threadIdx.x+blockIdx.x*blockDim.x;
i<size*sizeof(T)/sizeof(int);
i+=blockDim.x*gridDim.x)