Search code examples
cudagpuequalitythrust

What is the canonical way to compare memory ranges in the CPU and in the GPU


I have to contiguous ranges (pointer + size), one in the GPU and one in the CPU and I want to compare if they are equal.

What the canonical way to compare these ranges for equality?

my_cpu_type cpu;  // cpu.data() returns double*
my_gpu_type gpu;  // gpu.data() returns thrust::cuda::pointer<double>

thrust::equal(cpu.data(), cpu.data() + cpu.size(), gpu.data());

gives illegal memory access. I also tried

thrust::equal(
   thrust::cuda::par // also thrust::host
   , cpu.data(), cpu.data() + cpu.size(), gpu.data()
);

Solution

  • You can't do it the way you are imagining in the general case with thrust. Thrust does not execute algorithms in a mixed backend. You must either use the device backend, in which case all data needs to be on the device (or accessible from device code, see below), or else the host backend in which case all data needs to be on the host.

    Therefore you will be forced to copy the data from one side to the other. The cost should be similar (copy host array to device, or device array to host) so we prefer to copy to the device, since the device comparison can be faster.

    If you have the luxury of having the host array be in a pinned buffer, then it will be possible to do something like what you are suggesting.

    For the general case, something like this should work:

    thrust::host_vector<double>   cpu(size);
    thrust::device_vector<double> gpu(size);
    
    thrust::device_vector<double> d_cpu = cpu;
    bool are_equal = thrust::equal(d_cpu.begin(), d_cpu.end(), gpu.begin());