thrust::min_element 从位置读取时发生访问冲突

thrust::min_element Access violation while reading from location

我想使用 gpu 找到数组的最小值,因此我想使用 thrust::min_element 我的数据在设备中,这就是为什么我必须使用 thrust::device 但我有一个"Access violation while reading from location 0x0000000701240000" 并正在考虑 tuple.inl 函数:

inline __host__ __device__
  cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
        T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )

但是如果我使用 thrust::host 它会起作用!!!这是我的代码。如果有什么不对请告诉我。

#include <thrust/extrema.h>
#include <thrust/execution_policy.h>
#include <time.h>
int main()
{
    int nx=200;
    int ny=200;
    float cpt=0;
    clock_t start,end;
    double time;
    float *in,*d_in;
    float moy,*d_moy;
    in=(float*)malloc(nx*ny*sizeof(float));
    moy=0.0f;
    cudaMalloc((void**)&d_in,nx*ny*sizeof(float));
    cudaMalloc((void**)&d_moy,sizeof(float));
    for(int i=0;i<nx*ny;i++){in[i]=i+0.07;cpt+=in[i];}
    cudaMemcpy(d_in,in,nx*ny*sizeof(float),cudaMemcpyHostToDevice);
     start=clock(); 
     //float result= thrust::reduce(thrust::device, d_in, d_in + nx*ny);
     float *result=thrust::min_element(thrust::device, d_in , d_in+ nx*ny);
     end=clock();
     time=((double)(end-start))/CLOCKS_PER_SEC;
     printf("result= %f and correct result is %f time= %lf  \n",*result,in[0],time);
     system("pause");
}

这是 thrust::min_element 的错误。使用原始指针时程序崩溃。此错误仅存在于 CUDA7.5 Thrust1.8.2 或更早版本中。

您可以改用 thrust::device_vectorthrust::device_ptr。这是使用推力的更好方法。

#include <iostream>
#include <thrust/sequence.h>
#include <thrust/extrema.h>
#include <thrust/device_vector.h>
#include <thrust/execution_policy.h>

int main() {
  int n = 1000;
  thrust::device_vector<float> in(n);
  thrust::sequence(in.begin(), in.end(), 123);

  std::cerr << "by iterator:" << std::endl;
  thrust::device_vector<float>::iterator it_result =
      thrust::min_element(in.begin(), in.end());
  std::cerr << *it_result << std::endl;

  std::cerr << "by device_ptr:" << std::endl;
  thrust::device_ptr<float> ptr_in = in.data();
  thrust::device_ptr<float> ptr_result =
      thrust::min_element(ptr_in, ptr_in + in.size());
  std::cerr << *ptr_result << std::endl;

  std::cerr << "by pointer:" << std::endl;
  float* raw_in = thrust::raw_pointer_cast(in.data());
  std::cerr << "before min_element" << std::endl;
  float* result = thrust::min_element(thrust::device, raw_in, raw_in + in.size());
  std::cerr << "after min_element" << std::endl;
  std::cerr << in[result - raw_in] << std::endl;

  return 0;
}

结果表明 thrust::min_element 使用原始指针崩溃。

$ nvcc -o test test.cu && ./test
by iterator:
123
by device_ptr:
123
by pointer:
before min_element
Segmentation fault (core dumped)

另一方面,如果这个bug不存在,那么你原来的代码还是有问题的。正如@talonmies 所说,result 是设备指针。您需要将它指向的数据从设备复制到主机,然后才能打印出来。