операции с пустым хост-массивом

Я хочу сделать несколько операций с тягой, но я не уверен, как именно.

Прямо сейчас я получаю массив, полный нулей (массив h_a)

У меня есть :

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>

#include <cuda.h>
#include <cuda_runtime_api.h>

#include <thrust/device_ptr.h>
#include <thrust/fill.h>
#include <thrust/transform.h>
#include <thrust/functional.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/copy.h>
#include <thrust/generate.h>


template <typename T>
struct square
{
    __host__ __device__
    T operator()( const T& x ) const
    {
        return x * x;
    }

};


int
main(
             int argc,
    const char * argv[] )
{
    const size_t NbOfPoints  = 256;

    int BlocksPerGridX    = 16;
    int BlocksPerGridY    = 16;

    int ThreadsPerBlockX  = 16;
    int ThreadsPerBlockY  = 16;

    // generate random data on the host
    thrust::host_vector<float> h_Kx ( NbOfPoints );
    thrust::generate( h_Kx.begin(), h_Kx.end(), rand );

    thrust::host_vector<float> h_Ky ( NbOfPoints );
    thrust::generate( h_Ky.begin(), h_Ky.end(), rand );

    // transfer to device
    thrust::device_vector<float> dev_Kx = h_Kx;
    thrust::device_vector<float> dev_Ky = h_Ky;

    // create arrays for holding the number of threads per block in each dimension
    int * X , * Y;
    cudaMalloc((void **) &X, ThreadsPerBlockX * BlocksPerGridX * sizeof(*X) );
    cudaMalloc((void **) &Y, ThreadsPerBlockY * BlocksPerGridY * sizeof(*Y) );

    // wrap raw pointer with a device_ptr
    thrust::device_ptr<int> dev_X ( X );
    thrust::device_ptr<int> dev_Y ( Y );

    // use device_ptr in Thrust algorithms
    thrust::fill( dev_X, dev_X + ( ThreadsPerBlockX * BlocksPerGridX ) , (int) 0 );
    thrust::fill( dev_Y, dev_Y + ( ThreadsPerBlockY * BlocksPerGridY ) , (int) 0 );

    // setup arguments
    square<float> square_op;

    // create various vectors
    thrust::device_vector<int> distX ( NbOfPoints );
    thrust::device_vector<int> distY ( NbOfPoints );
    thrust::device_vector<unsigned int> Tmp ( NbOfPoints );
    thrust::host_vector<unsigned int> h_a ( NbOfPoints );
    thrust::device_vector<unsigned int> distXSquared ( NbOfPoints );
    thrust::device_vector<unsigned int> distYSquared ( NbOfPoints );


    // compute distX = dev_Kx - dev_X and distY = dev_Ky - dev_Y
    thrust::transform( dev_Kx.begin(), dev_Kx.begin(), dev_X , distX.begin() , thrust::minus<float>() );
    thrust::transform( dev_Ky.begin(), dev_Ky.begin(), dev_Y , distY.begin() , thrust::minus<float>() );

    //square distances
    thrust::transform( distX.begin(), distX.end(), distXSquared.begin(), square_op );
    thrust::transform( distY.begin(), distY.end(), distYSquared.begin(), square_op );

    // compute Tmp =  distX + distY
    thrust::transform( distXSquared.begin() ,distXSquared.begin() , distYSquared.begin() , Tmp.begin() , thrust::plus<unsigned int>() );
    thrust::copy( Tmp.begin(), Tmp.end(), h_a.begin() );


    for ( int i = 0; i < 5; i ++ )
        printf("\n temp = %u",h_a[ i ] );


return 0;
}

ОБНОВИТЬ:

Помимо правок от Robert Crovella, вы должны отредактировать целые числа:

square<int> square_op;
thrust::transform( dev_Kx.begin(), dev_Kx.end(), dev_X , distX.begin() , thrust::minus<int>() );
thrust::transform( dev_Ky.begin(), dev_Ky.end(), dev_Y , distY.begin() , thrust::minus<int>() );

person George    schedule 09.12.2014    source источник
comment
И что такое точно эти различные ошибки?   -  person user703016    schedule 09.12.2014
comment
@Park Young-Bae:Я обновил..   -  person George    schedule 09.12.2014
comment
Насколько сложно было бы опубликовать пример, который кто-то мог бы скомпилировать и запустить для себя? Я в отчаянии, что даже после того, как вы задали 200 вопросов в Stack Overflow, вы так и не поняли, как это место работает.   -  person talonmies    schedule 09.12.2014
comment
Вы должны предоставить MCVE (почему этот код не работает?). Это то, что кто-то другой может скопировать, вставить, скомпилировать и запустить, ничего не добавляя и не изменяя, и видеть проблему.   -  person Robert Crovella    schedule 09.12.2014
comment
@talonmies: Хорошо, я обновил..   -  person George    schedule 09.12.2014
comment
@Robert Crovella: Хорошо, я обновил..   -  person George    schedule 09.12.2014
comment
Я не могу скомпилировать ваш код в том виде, в котором он опубликован. Я предполагаю, что это означает, что код, который вы используете, не является кодом, который вы опубликовали. Это не особенно хороший способ задать ТАК вопрос. Будет лучше, если вы на самом деле убедитесь, что опубликованный вами код создает проблему, которую вы описываете, как описано здесь.   -  person Robert Crovella    schedule 09.12.2014
comment
@Robert Crovella: я удалил проверку ошибок графического процессора. Теперь он должен нормально компилироваться!   -  person George    schedule 09.12.2014


Ответы (1)


У вас есть несколько примеров выполнения преобразований нулевой длины:

thrust::transform( dev_Kx.begin(), dev_Kx.begin(), dev_X , distX.begin() , thrust::minus<float>() );
thrust::transform( dev_Ky.begin(), dev_Ky.begin(), dev_Y , distY.begin() , thrust::minus<float>() );

и:

thrust::transform( distXSquared.begin() ,distXSquared.begin() , distYSquared.begin() , Tmp.begin() , thrust::plus<unsigned int>() );

Поскольку первые два параметра для каждого из приведенных выше преобразований одинаковы, проделанная работа равна нулю. Предположительно, вам нужны соответствующие итераторы .end() во второй позиции, а не .begin()

Когда я делаю эти изменения, я получаю ненулевые значения. Они довольно большие, но вы, похоже, возводите в квадрат большие значения, поэтому я не уверен, каково ваше намерение.

person Robert Crovella    schedule 09.12.2014
comment
:Здравствуйте, я просто хочу спросить. Если бы dev_X выше был вектором, я бы использовал dev_X.begin(). Тогда, когда мы используем 'begin()', это означает, что он возьмет весь вектор? С самого начала до конца? Спасибо! - person George; 10.12.2014
comment
вы можете прочитать std::vector. .begin() — это функция-член, являющаяся частью класса vector, которая возвращает итератор, указывающий на начало вектора (т. е. на первый элемент). Это не означает, что будет использоваться весь вектор. Если это все еще неясно, я предлагаю вам опубликовать новый вопрос. - person Robert Crovella; 10.12.2014
comment
: Хорошо, но в приведенной выше строке (преобразование) я хочу сделать вычитание 'dev_Kx - dev_X'. Как я могу гарантировать, что оно также проходит через все элементы dev_X? Поскольку в функции trasnform аргументов 5. - person George; 10.12.2014
comment
Я предлагаю вам опубликовать новый вопрос. - person Robert Crovella; 10.12.2014