Не работает cudaSetDevice, массив выдаёт не инициализированные значения

Рейтинг: -1Ответов: 1Опубликовано: 03.03.2025

недавно начал изучать 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;
}

Вроде должно работать