2016-10-05 4 views
0

저는 CUDA와 추진력에 대해 약간 새로운 사람입니다. 나는 thrust :: for_each 알고리즘이 counting_iterator와 함께 제공 될 때 작동하지 못하는 것 같습니다. 나는 순서로 채워져 호스트 벡터와이를 호출하는 경우, 그것은 잘 작동 이제cuda thrust :: for_each with thrust :: counting_iterator

struct print_Functor { 
    print_Functor(){} 
    __host__ __device__ 
    void operator()(int i) 
    { 
     printf("index %d\n", i); 
    } 
}; 

:

thrust::host_vector<int> h_vec(10); 
    thrust::sequence(h_vec.begin(),h_vec.end()); 
    thrust::for_each(h_vec.begin(),h_vec.end(), print_Functor()); 

을 그러나, 나는 추력이 작업을 수행하려고하면 여기 내 간단한 펑입니다 :: counting_iterator 그것은 실패

thrust::counting_iterator<int> first(0); 
    thrust::counting_iterator<int> last = first+10; 
    for(thrust::counting_iterator<int> it=first;it!=last;it++) 
     printf("Value %d\n", *it); 
    printf("Launching for_each\n"); 
    thrust::for_each(first,last,print_Functor()); 

내가 얻을 것은 for 루프가 제대로 실행하는, 그러나의 for_each는 오류 메시지와 함께 실패합니다

after cudaFuncGetAttributes: unspecified launch failure 

나는 반복자 형에게 템플릿 인수함으로써이 작업을 수행하려고 :

thrust::for_each<thrust::counting_iterator<int>>(first,last, print_Functor()); 

하지만 같은 오류가 발생합니다.

완벽을 기하기 위해, 저는 이것을 MATLAB mex 파일 (64 비트)에서 호출하고 있습니다.

저는 추력 반복기에서 작동하도록 다른 추력 알고리즘을 사용할 수있었습니다 (예 : thrust :: reduce가 올바른 결과를 제공함).

신입 사원으로 저는 정말로 어리석은 일을하고 있습니다.

의견을 보내 주셔서 감사합니다. 나는 지금까지 의견을 게시했다. 작업 한 예제 (Matlab 외부)는 올바르게 작동하고 출력물을 출력했지만,이 파일이 mex 파일로 만들어진 경우 여전히 작동하지 않았습니다. 출력물을 처음 생성하지 않고 두 번째로 이전과 동일한 오류 메시지를 생성했습니다 출력이 나오지 않을 때 재 컴파일로 고정).

그러나 DOS 에서조차도 thrust :: for_each에서 펑터를 실행하지 않는 것과 비슷한 문제가 있습니다.

#include <thrust/for_each.h> 
#include <thrust/iterator/counting_iterator.h> 

struct sum_Functor { 
    int *sum; 
    sum_Functor(int *s){sum = s;} 
    __host__ __device__ 
    void operator()(int i) 
    { 
     *sum+=i; 
     printf("In functor: i %d sum %d\n",i,*sum); 
    } 

}; 

int main(){ 

    thrust::counting_iterator<int> first(0); 
    thrust::counting_iterator<int> last = first+10; 
    int sum = 0; 
    sum_Functor sf(&sum); 
    printf("After constructor: value is %d\n", *(sf.sum)); 
    for(int i=0;i<5;i++){ 
     sf(i); 
    } 

    printf("Initiating for_each call - current value %d\n", (*(sf.sum))); 
    thrust::for_each(first,last,sf); 

    cudaDeviceSynchronize(); 
    printf("After for_each: value is %d\n",*(sf.sum)); 
} 

이 함께 DOS 프롬프트에서 컴파일된다 : 여기서 전체 일례이다

nvcc -o pf pf.cu 

생성되는 출력은 : 환언

After constructor: value is 0 
In functor: i 0 sum 0 
In functor: i 1 sum 1 
In functor: i 2 sum 3 
In functor: i 3 sum 6 
In functor: i 4 sum 10 
Initiating for_each call - current value 10 
After for_each: value is 10 

펑의 과부하 연산자() for 루프에서 올바르게 호출되지만 thrust :: for_each 알고리즘에서는 호출하지 않습니다. 카운팅 반복자를 사용할 때 for_each가 펑터를 실행하게하는 유일한 방법은 멤버 변수를 생략하는 것입니다.

당신은 당신의 코드가 실행 싶은 말 귀하의 의견에

+2

어떤 플랫폼을 사용하고 계십니까? 리눅스? 창문? 맥? 어떤 CUDA 버전? 어떤 버전을 밀어? 어느 컴파일러? 제발 항상 [mcve] –

+0

[여기] (http://pastebin.com/ebvNdf4v) 게시 된 (Linux가 아닌 - MATLAB) 예를 들어 무엇을 기반으로 게시 할 수 있습니다. 그것은 나를 위해 올바르게 작동하는 것 같습니다. matlab mex에서 인쇄 할 물건을 얻는 것이 까다로울 수 있습니다. –

+0

@ m.s - CUDA 7.5 툴킷을 사용하여 Windows 7 Professional 64 비트를 사용 중입니다. 추력 버전을 얻는 방법을 모르십니까? CUDA 7.5와 함께 제공됩니다. –

답변

1

을 (... 난 내 C + +를 매우 녹슨 사용하여 순수 matlab에의 년 후에 그를 추가해야합니다, 그래서 분명 뭔가가 될 수있다) 호스트 측.

오류 코드 "지정되지 않은 발사 실패", 그리고 펑은 호스트 날 추력 장치에서 실행하고 싶은 생각하게장치로 정의됩니다 사실.

실행 정책을 추가하여 코드가 실행되는 위치를 확인할 수 있습니까?

교체 :

thrust::for_each(first,last,sf); 

thrust::for_each(thrust::host, first,last,sf); 

로 GPU에서 실행 할 수 있으려면, 당신의 결과는 다시 호스트로 복사 (cudaMalloc를 통해) 장치 메모리에 할당해야합니다.


#include <thrust/host_vector.h> 
#include <thrust/sequence.h> 
#include <thrust/for_each.h> 
#include <thrust/iterator/counting_iterator.h> 
#include <thrust/execution_policy.h> 

struct sum_Functor { 
    int *sum; 
    sum_Functor(int *s){sum=s;} 
    __host__ __device__ 
    void operator()(int i) 
    { 
     atomicAdd(sum, 1); 
    } 
}; 

int main(int argc, char**argv){ 


    thrust::counting_iterator<int> first(0); 
    thrust::counting_iterator<int> last = first+atoi(argv[1]); 
    int *d_sum; 
    int h_sum = 0; 

    cudaMalloc(&d_sum,sizeof(int)); 
    cudaMemcpy(d_sum,&h_sum,sizeof(int),cudaMemcpyHostToDevice); 

    thrust::for_each(thrust::device,first,last,sum_Functor(d_sum)); 

    cudaDeviceSynchronize(); 
    cudaMemcpy(&h_sum,d_sum,sizeof(int),cudaMemcpyDeviceToHost); 
    printf("sum = %d\n", *h_sum); 
    cudaFree(d_sum); 

} 

코드 업데이트 : 당신은 원자 작업을 사용합니다 장치에 올바른 결과를합니다.

+0

감사합니다. 예, 이제 thrust :: host 인수를 추가 할 때 올바른 출력을 제공합니다. 물론 현실에서는 코드를 장치에서 실행하고 싶지만 문제를 설명하기 위해 코드를 단순화했습니다! 내가 단순화에서 너무 멀리 나가는 것처럼 보입니다. 이제 장치 메모리를 할당하여 시도해보십시오. –

+0

코드를 업데이트했는데 하나의 int에 대한 malloc이 너무 맘에 들지만 가장 중요한 것은 int에 대한 AtomicOperation을 잊어 버린 것입니다. – X3liF

+0

안녕하세요, 감사합니다. @ X3liF - AtomicOperations는 내가 교환에서 배웠던 새로운 것입니다. CUDA를 처음 접한 사람들은 아직 알아야 할 부분이 있습니다. 모든 도움에 감사드립니다. –

관련 문제