2014-12-10 5 views
1

here 다음과 같습니다.빼기를위한 적절한 추력 호출

dev_X가 벡터라고 가정합니다.

int * X = (int*) malloc(ThreadsPerBlockX * BlocksPerGridX * sizeof(*X)); 


for (int i = 0; i < ThreadsPerBlockX * BlocksPerGridX; i++) 
    X[ i ] = i; 

// create device vectors 
thrust::device_vector<int> dev_X (ThreadsPerBlockX * BlocksPerGridX); 

//copy to device 
thrust::copy(X , X + theThreadsPerBlockX * theBlocksPerGridX , dev_X.begin()); 

다음

는 뺄셈을하고있다 :

thrust::transform(dev_Kx.begin(), dev_Kx.end(), dev_X.begin() , distX.begin() , thrust::minus<float>()); 
dev_Kx - dev_X. 

나는 그것이 사용되는이 .END하는 .begin에서 이동하기 때문에 (전체 dev_Kx 벡터를 사용하려면()) 및 전체 dev_X 벡터.

위의 코드는 dev_X.begin()을 사용합니다.

dev_X 벡터 전체를 사용한다는 의미입니까? 처음부터 시작 하시겠습니까? 또는 다른 추가 인수를 사용하여 dev_X.end()을 가리켜 야합니까? 예를 들어,

또한 (위의 함수 호출에 난 그냥이 추가 인수를 사용할 수 없기 때문에) :

내가

thrust::transform(dev_Kx, dev_Kx + i , dev_X.begin() ,distX.begin() , thrust::minus<int>()); 

그런 다음 dev_Kx 내가 0에서 갈 것 사용하려면 및 dev_X.begin()? 그것은 같은 길이를 사용할 것인가? (0 ~ i?) 또는 dev_X 길이를 사용합니까?

+0

API가 있도록 설계되었습니다 ~ 만 하나의 * 전체 범위가 필요하며 (첫 번째 "피연산자"), 나머지는 동일한 길이 (또는 적어도 첫 번째 전체 범위를 커버하기에 충분한)로 가정됩니다. 그런데 처음으로'malloc'과 배열 초기화는 더 많은 관용적이고 에러가 발생하기 쉬운 C++을 작성하고자한다면'std :: vector'와'std :: iota' 호출로 대체 될 수 있습니다. –

+0

@Park Young-Bae : 그럼, 만약 내가 사용하고 싶다면 \t \t thrust :: transform (dev_Kx, dev_Kx + i, dev_X.begin(), distX.begin(), thrust :: minus ()); dev_Kx는 0에서 i와 dev_X.begin()으로 갈 것인가? 같은 길이로 될까요? (0 ~ i?) 아니면 dev_X의 길이를 사용합니까? – George

+0

'dev_Kx.end() - dev_Kx.begin()'과'dev_Kx + i - dev_Kx'의 마지막 예에서'0 '에서'i'까지의 길이를 사용합니다 '예. –

답변

7

많은 수의 thrust (및 표준 라이브러리) 함수는 범위를 첫 번째 매개 변수로 사용하고 다른 모든 반복기는 같은 크기의 컨테이너로 백업한다고 가정합니다. 범위는 시작을 나타내는 시퀀스를 나타내는 한 쌍의 반복자입니다. 예를 들어

는 : dev_X

thrust::copy(
    X.begin(), // begin input iterator 
    X.end(),  // end input iterator 
    dev_X.begin() // begin output iterator 
); 

이 복사 X의 전체 내용. dev_X.end()이 필요하지 않은 이유는 무엇입니까? thrust은 프로그래머가 dev_X의 크기를 적절하게 조정하여 이상이 입력 범위에있는 것보다 많은 요소 수인 이상을 포함 할 수 있도록 처리해야하기 때문입니다. 그 보장을 충족시키지 못하면 동작은 정의되지 않습니다.

당신이 할 때 : thrust가 보는 무엇

thrust::transform(
    dev_Kx.begin(), // begin input (1) iterator 
    dev_Kx.end(), // end input (1) iterator 
    dev_X.begin(), // begin input (2) iterator 
    distX.begin(), // output iterator 
    thrust::minus<float>() 
); 

dev_Kx.begin()에서 dev_Kx.end()의 입력 범위입니다. 명시 적 크기는 dev_Kx.end() - dev_Kx.begin()입니다. dev_X.end()distX.end()이 필요하지 않은 이유는 무엇입니까? 그들은 의 암시 적 크기가 dev_Kx.end() - dev_Kx.begin()이기 때문에.예를 들어, dev_Kx 10 개 요소가있는 경우, 다음 transform는 :

  • 수행

    • 은 (적어도 10 요소를 보유하고 있어야합니다) dev_Xdev_Kx
    • 사용 10 요소의 10 개 요소를 사용 빼기를 수행하고 distX에 10 개의 결과를 저장하면 이상을 적어도 개의 요소 10 개까지 포함 할 수 있어야합니다.

    어쩌면 구현을 보면 의심의 여지가 없습니다. 다음은 몇 가지 의사 코드입니다.

    void transform(InputIterator input1_begin, InputIterator input1_end, 
           InputIterator input2_begin, OutputIterator output, 
           BinaryFunction op) { 
        while (input1_begin != input1_end) { 
         *output++ = op(*input1_begin++, *input2_begin++); 
        } 
    } 
    

    하나의 엔드 반복자 만 필요합니다. 관련이없는 노트에


    , 다음

    int * X = (int*) malloc(ThreadsPerBlockX * BlocksPerGridX * sizeof(*X)); 
    for (int i = 0; i < ThreadsPerBlockX * BlocksPerGridX; i++) 
        X[ i ] = i; 
    

    더 관용적으로 다시 작성할 수 있습니다, 덜 오류가 발생하기 쉬운 C++ :

    std::vector<int> X(ThreadsPerBlockX * BlocksPerGridX); 
    std::iota(X.begin(), X.end(), 0); 
    
  • +0

    : 알았어, 이해 했어. 예를 들어 dev_Kx의 요소 10 개와 dev_X의 요소 10 개를 사용하는 방법이 있습니까? 예를 들어, 다음과 같이하고 싶습니다. dev_Kx [0] - dev_X [0], dev_Kx [0] - dev_X [ 1], dev_Kx [0] - dev_X [2] ... 그래서, dev_Kx에서 10 요소를 사용하십시오. 예를 들어 dev_X에서 100을 사용하십시오. – George

    +1

    'transform'으로는 그럴 수 없습니다. 10 개의 요소를 100 개로 조정하는 자체 반복자를 구현해야합니다. 또는 자체 변환 알고리즘을 구현하십시오. –

    +0

    : 네, 도와 줘서 고마워. – George