Не работает cudaSetDevice, массив выдаёт не инициализированные значения
недавно начал изучать cuda c, узнал про функцию cudaSetDevice и решил протестировать её
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
#include <stdio.h>
const int choses = 1;
__global__ void func(int* a,const int choses = 0)
{
a[blockIdx.x + choses] = 1;
}
int main()
{
int* a;
int* a_cpu = new int[2];
cudaMalloc((void**)&a, 2 * sizeof(int));
while (true)
{
cudaSetDevice(0);
func <<<1, 1 >>> (a);
cudaSetDevice(1);
func <<<1, 1 >>> (a, choses);
cudaMemcpy(a_cpu, a, 2 * sizeof(int), cudaMemcpyDeviceToHost);
std::cout << a_cpu[0] << " ";
std::cout << a_cpu[1] << "\n";
}
}
Программа берет массив из 2 чисел и вечно суммирует, причём каждый элемент суммирует своя видеокарта после копирует данные в переменную CPU, но программа почему то выдаёт что элементы массива не инициализрованы
P.S без cudaSetDevice() всё работает как надо.
Ответы (1 шт):
Синхронизация покинула чат. После запуска ядра (func) на одном устройстве, ты сразу переключаетесь на другое устройство и запускаете ядро там, так как операции на GPU выполняются асинхронно.
После запуска ядра на каждом устройстве вызывается cudaDeviceSynchronize, чтобы дождаться завершения выполнения:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
const int choses = 1;
__global__ void func(int* a, const int offset = 0)
{
a[blockIdx.x + offset] = 1;
}
int main()
{
int* a_dev0; // Память на устройстве 0
int* a_dev1; // Память на устройстве 1
int* a_cpu = new int[2]; // Память на хосте
// Выделяем память на каждом устройстве
cudaSetDevice(0);
cudaMalloc((void**)&a_dev0, 2 * sizeof(int));
cudaSetDevice(1);
cudaMalloc((void**)&a_dev1, 2 * sizeof(int));
while (true)
{
cudaSetDevice(0);
func<<<1, 1>>>(a_dev0);
cudaDeviceSynchronize(); // Синхронизируем устройство 0
cudaSetDevice(1);
func<<<1, 1>>>(a_dev1, choses);
cudaDeviceSynchronize(); // Синхронизируем устройство 1
// Копируем данные с устройств на хост
cudaSetDevice(0);
cudaMemcpy(&a_cpu[0], a_dev0, sizeof(int), cudaMemcpyDeviceToHost);
cudaSetDevice(1);
cudaMemcpy(&a_cpu[1], a_dev1, sizeof(int), cudaMemcpyDeviceToHost);
// Выводим результат
std::cout << a_cpu[0] << " " << a_cpu[1] << "\n";
}
// Освобождаем память
cudaSetDevice(0);
cudaFree(a_dev0);
cudaSetDevice(1);
cudaFree(a_dev1);
delete[] a_cpu;
return 0;
}
Вроде должно работать
