Home > Back-end >  How do I thrust::sort() or thrust::sort_by_key() with raw pointers
How do I thrust::sort() or thrust::sort_by_key() with raw pointers

Time:01-16

I want to sort an array using raw device pointers with thrust::sort() and thrust::sort_by_key() because it uses radix sort. The data is in a raw uint64_t device pointer, and I initialize with random elements for testing. I looked at the thrust library and saw some examples that simply passed in an array variable and the array variable plus the size to pass in the start and end of the array. When I call the sort method, it throws a runtime error saying that Exception thrown: read access violation. thrust::identity<unsigned __int64>::operator()(...) returned 0x701A00000. I am not sure what is causing this because I am new to using thrust to sort.

Here is some sample code to show how I am calling it:

uint64_t size = 1024ull;
uint64_t* data;
cudaMalloc((void**)&data, size * sizeof(uint64_t));
curandGenerator_t gen;
curandCreateGenerator(&gen, CURAND_RNG_QUASI_SOBOL64);
curandSetPseudoRandomGeneratorSeed(gen, 132748238ull);
curandGenerateLongLong(gen, data, size);
curandDestroyGenerator(gen);
thrust::sort(data, data   size);

CodePudding user response:

TLDR:

Call the sort function as follows:

thrust::sort(thrust::device, data, data size);

Detail:

If you pass a raw pointer to a thrust algorithm ( e.g. thrust::sort ), it cannot determine whether the pointer points to a memory location on the host or a device. By default, the algorithm's execution is dispatched to the host backend (CPU). It means, if the data pointer points to device memory, it will result in a crash as you are encountering.

This is where execution policies come in. The execution policies allow us to explicitly specify the backend to which the execution of the algorithm will be dispatched. If you are sure about the location of the allocated memory, you can specify the target backend explicitly ( as specified in the above example ).

Alternate Approach:

If you don't want to use execution policies, an alternate approach is to wrap the raw device pointer into a thrust::device_ptr object as follows:

auto dptr = thrust::device_ptr<uint64_t>(data); 
thrust::sort(dptr , dptr   size);

As stated in the thrust documentation:

Algorithms operating on device_ptr types will automatically be dispatched to the device system.

  • Related