在我的代码中,我在全局内存中有一个静态分配的数组(即使用__device__
分配),我想使用thrust::sort
排序,但这是无效的。本主题的所有示例都使用CUDA运行时分配的数组(使用cudaMalloc
)。有什么方法可以对静态分配的数组进行排序吗?
我猜这与静态无法从主机访问的静态分配内存有关。使用cudaMalloc
- 分配的数组,它工作正常。但是,我想避免使用这种类型的分配,因为静态分配允许更容易地从设备代码访问数据(不是吗?)。
#include <stdio.h>
#include <thrust/device_ptr.h>
#include <thrust/sort.h>
#define N 4
typedef struct element {
int key;
int value;
__host__ __device__ bool operator<(element e) const
{ return key > e.key; }
} element;
__device__ element array[N];
__global__ void init() {
for (int i = 0; i < N; ++i) {
array[N - i - 1].key = i;
}
}
__global__ void print_array() {
for (int i = 0; i < N; ++i) {
printf("%d ", array[i].key);
}
printf("\n");
}
int main(void) {
thrust::device_ptr<element> array_first(array);
init<<<1,1>>>();
printf("unsorted: ");
print_array<<<1, 1>>>();
cudaDeviceSynchronize();
thrust::sort(array_first, array_first + N);
printf("sorted: ");
print_array<<<1, 1>>>();
cudaDeviceSynchronize();
}
答案 0 :(得分:2)
使用declare class Meteor {
isClient: boolean;
}
从cudaGetSymbolAddress
函数中获取array
变量的地址:
__host__
这是完整的程序:
void* array_ptr = 0;
cudaGetSymbolAddress(&array_ptr, array);
thrust::device_ptr<element> array_first(reinterpret_cast<element*>(array_ptr));
这是我系统上的输出:
#include <stdio.h>
#include <thrust/device_ptr.h>
#include <thrust/sort.h>
#define N 4
typedef struct element {
int key;
int value;
__host__ __device__ bool operator<(element e) const
{ return key > e.key; }
} element;
__device__ element array[N];
__global__ void init() {
for (int i = 0; i < N; ++i) {
array[N - i - 1].key = i;
}
}
__global__ void print_array() {
for (int i = 0; i < N; ++i) {
printf("%d ", array[i].key);
}
printf("\n");
}
int main(void) {
cudaError_t error;
void* array_ptr = 0;
if(error = cudaGetSymbolAddress(&array_ptr, array))
{
throw thrust::system_error(error, thrust::cuda_category());
}
thrust::device_ptr<element> array_first(reinterpret_cast<element*>(array_ptr));
init<<<1,1>>>();
printf("unsorted: ");
print_array<<<1, 1>>>();
if(error = cudaDeviceSynchronize())
{
throw thrust::system_error(error, thrust::cuda_category());
}
thrust::sort(array_first, array_first + N);
if(error = cudaDeviceSynchronize())
{
throw thrust::system_error(error, thrust::cuda_category());
}
printf("sorted: ");
print_array<<<1, 1>>>();
if(error = cudaDeviceSynchronize())
{
throw thrust::system_error(error, thrust::cuda_category());
}
return 0;
}
排序的输出与未排序的输出相同,但我想这是有意的,因为数据的生成方式和$ nvcc test.cu -run
unsorted: 3 2 1 0
sorted: 3 2 1 0
的定义。
答案 1 :(得分:2)
此:
__device__ element array[N];
...
thrust::device_ptr<element> array_first(array);
是非法的。在 host 代码中,array
是主机地址,无法传递给设备代码。做这样的事情:
element* array_d;
cudaGetSymbolAddress((void **)&array_d, array);
thrust::device_ptr<element> array_first(array_d);
即。您需要使用cudaGetSymbolAddress在运行时从GPU上下文中读取地址,然后您可以在GPU代码中使用该调用的结果。