Копирование части набора данных в несколько графических процессоров 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 вопроса.
- это не выглядит правильным для меня:
Это:
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());
и аналогично для других случаев.
- это также не выглядит правильно:
Вот:
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());