2016-06-21 8 views
0

gpuを使用して配列の最小値を検索したいと思いますthrust :: min_elementを使用したいデータがデバイスに格納されていますので、 :「場所0x0000000701240000からの読み込み中にアクセス違反」とtuple.inl機能に取っていますデバイスが、私は持っている:thrust :: min_element場所からの読み取り中にアクセス違反が発生しました

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

が、私は推力::ホストを使用している場合、それは動作します!これは私のコードです。何かが間違っている場合は教えてください。

#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"); 
} 
+1

'result'は' min_element'呼び出しの後に有効なホストポインタではありません。このためにデバイスから 'result'で値ポインタをコピーする必要があります – talonmies

+0

あなたの答えはThnxですが、結果が有効なポインタではないことを理解できませんでしたか?これはドキュメントの例であり、私がthrust :: min_elementを呼び出すと問題になります。 –

+0

'thrust :: device'実行ポリシーを使用しています。これは、結果を含むすべてのポインタがデバイスポインタであることを意味します – talonmies

答えて

1

thrust::min_elementのバグです。生ポインタが使用されると、プログラムがクラッシュしました。このバグは、CUDA7.5 Thrust1.8.2以前のバージョンにのみ存在します。

代わりにthrust::device_vectorまたはthrust::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) 

一方、このバグが存在しない場合、元のコードにはまだ問題があります。 @ talonmiesが言ったように、resultはデバイスポインタです。あなたがそれを印刷する前に、それが指すデータをデバイスからホストにコピーする必要があります。

+0

Thnxあなたの答えのためにたくさん私はデバイスポインタを使用して、私は同じ問題を抱えている結果をcpyしようとしました。確かに私はCUDA7.5を使用しています。私はあなたのコードを試して、私は次のエラーがあります:エラーC2027:定義されていない型の使用 '推力::詳細:: STATIC_ASSERTION_FAILURE ' \t reduce.inl。私はいくつかのバグがあるバージョンです。 –

+0

代わりに 'thrust :: device_ptr'を使うことができます。 http://docs.nvidia.com/cuda/thrust/#iterators-and-static-dispatching – kangshiyin

+0

はい、私はそれを行います。 Thnx多くのエリックとあなたの助けのための他のすべて! –

関連する問題