Копирование части набора данных в несколько графических процессоров CUDA с использованием Thrust

Я хочу разделить набор данных между несколькими графическими процессорами, причем каждый графический процессор получает только подмножество данных для кода CUDA с использованием Thrust. Прикрепленный ниже код, который компилируется; однако, thrust выдает следующую ошибку во время выполнения: "прерывание вызывается после создания экземпляра thrust::system::system_error" what(): неверный аргумент прерван "

Как мне сделать копию только части диапазона и отметить весь диапазон?

// find number of GPU's
int GPU_N, i;
cudaGetDeviceCount(&GPU_N);

//Subdividing input data across GPUs
//Get data sizes for each GPU
for (i = 0; i < GPU_N; i++)
{
    number_gpu[i] = Np / GPU_N;
}

//Take into account "odd" data sizes
for (i = 0; i < Np % GPU_N; i++)
{
    number_gpu[i]++;
}

for(i = 0; i < GPU_N; i++){
    cudaSetDevice(i);

thrust::device_vector<ARRAYTYPE> dev_pos(3*number_gpu[i]);
thrust::device_vector<ARRAYTYPE> dev_vel(3*number_gpu[i]);
thrust::device_vector<ARRAYTYPE> dev_accel(3*number_gpu[i]);
thrust::device_vector<ARRAYTYPE> dev_time(number_gpu[i]);

thrust::copy_n(pPos.begin()+3*number_gpu[i], 3*number_gpu[i+1], dev_pos.begin());
thrust::copy_n(pVel.begin()+3*number_gpu[i], 3*number_gpu[i+1], dev_vel.begin());
thrust::copy_n(pAccel.begin()+3*number_gpu[i], 3*number_gpu[i+1], dev_accel.begin());
thrust::copy_n(pTime.begin()+number_gpu[i], 3*number_gpu[i+1], dev_time.begin());

Спасибо!

2 ответа

Вы должны предоставить MCVE, а не частичный фрагмент. SO ожидает, что для таких вопросов ("почему этот код не работает?").

Однако я вижу как минимум 2 вопроса.

  1. это не выглядит правильным для меня:

Это:

thrust::device_vector<ARRAYTYPE> dev_pos(3*number_gpu[i]);

говорит "выделено на устройстве, память в векторе dev_pos за 3*number_gpu[i] элементы размера ARRAYTYPE"

Это:

thrust::copy_n(pPos.begin()+3*number_gpu[i], 3*number_gpu[i+1], dev_pos.begin());

говорит "копия 3*number_gpu[i+1] элементы, начинающиеся с nPos.begin()+3*number_gpu[i] в dev_pos,

Мы видели это dev_pos выделил хранилище для 3*number_gpu[i] элементы. Вы сейчас хотите скопировать 3*number_gpu[i+1] элементы в него. Это не выглядит правильным, и, кроме того, если 3*number_gpu[i+1] > 3*number_gpu[i] это будет проблемой.

Второй параметр thrust::copy_n количество элементов для копирования. Вы можете просмотреть документацию по thrust:: copy_n.

Чтобы это исправить, вам, вероятно, просто нужно изменить второй параметр:

thrust::copy_n(pPos.begin()+3*number_gpu[i], 3*number_gpu[i], dev_pos.begin());

и аналогично для других случаев.

  1. это также не выглядит правильно:

Вот:

thrust::device_vector<ARRAYTYPE> dev_time(number_gpu[i]);

Вы выделили место для number_gpu[i] элементы.

Вот:

thrust::copy_n(pTime.begin()+number_gpu[i], 3*number_gpu[i+1], dev_time.begin());

вы пытаетесь скопировать 3*number_gpu[i+1] элементы в него. Это, вероятно, слишком велико и выглядит как ошибка копирования-вставки.

Опять же, чтобы исправить, вам, вероятно, просто нужно изменить второй параметр:

thrust::copy_n(pTime.begin()+number_gpu[i], number_gpu[i], dev_time.begin());

Если это не решит проблему, вам нужно будет предоставить MCVE. Это полный, но короткий код, демонстрирующий проблему. Это должно быть что-то, что кто-то другой может копировать, вставлять, компилировать и запускать, без необходимости что-либо добавлять или изменять, и видеть проблему.

Спасибо за помощь, теперь я вижу, что я сделал не так. Вот рабочая версия кода.

//Subdividing input data across GPUs
int number_gpu=Np / GPU_N;
int data_offset_gpu[GPU_N+1];
data_offset_gpu[0]=0;

//Get data sizes for each GPU
for (i = 0; i < GPU_N; i++)
{
    data_offset_gpu[i+1] = data_offset_gpu[i] + number_gpu;
}

//Take into account "odd" data sizes
    //number_gpu[1]+= Np % GPU_N;

std::cout << "CUDA-capable device count: " << GPU_N << std::endl;
std::cout << "Starting addresses for GPU memory blocks:" << std::endl;
for (i=0; i< GPU_N+1; i++){
     std::cout << data_offset_gpu[i] << std::endl;
}


for(i = 0; i < GPU_N; i++){

    cudaSetDevice(i);

    int Nblocks=(number_gpu +(THREADS_PER_BLOCK-1))/THREADS_PER_BLOCK;

thrust::device_vector<ARRAYTYPE> dev_pos(3*number_gpu);
thrust::device_vector<ARRAYTYPE> dev_vel(3*number_gpu);
thrust::device_vector<ARRAYTYPE> dev_accel(3*number_gpu);
thrust::device_vector<ARRAYTYPE> dev_time(number_gpu);

std::cout << "Preparing to copy data to GPU: " << i << std::endl;
thrust::copy(&(pPos[3*data_offset_gpu[i]]),&(pPos[3*data_offset_gpu[i+1]]), dev_pos.begin());
thrust::copy(&(pVel[3*data_offset_gpu[i]]),&(pVel[3*data_offset_gpu[i+1]]), dev_vel.begin());
thrust::copy(&(pAccel[3*data_offset_gpu[i]]), &(pAccel[3*data_offset_gpu[i+1]]), dev_accel.begin());
thrust::copy(&(pTime[data_offset_gpu[i]]), &(pTime[data_offset_gpu[i+1]]), dev_time.begin());
Другие вопросы по тегам