Назад | Перейти на главную страницу

Использование CUDA_VISIBLE_DEVICES с sge

Использование sge с комплексом ресурсов под названием 'gpu.q', который позволяет управлять ресурсами устройств gpu (это все устройства nvidia). Однако в системах имеется несколько устройств с графическим процессором (в монопольном режиме), и если два задания размещены на одном узле, у пользователя нет возможности непрозрачно создать контекст на правильном графическом процессоре.

Кто-нибудь сталкивался с этой проблемой? Я думал как-то управлять конкретными ресурсами gpu и сопоставить идентификаторы хоста и устройства. Что-то вроде

hostA -> gpu0:in_use
hostA -> gpu1:free
hostB -> gpu0:free
hostB -> gpu1:in_use

и т. д. А затем при запросе ресурса показать выделенные ресурсы GPU на каждом хосте с помощью переменной CUDA_VISIBLE_DEVICES.

Это кажется довольно распространенной проблемой - она ​​должна была быть решена кем-то к настоящему времени с преобладанием графических процессоров в вычислительных кластерах.

Как я выяснил на собственном горьком опыте, нельзя просто перечислить устройства, а затем вызвать cudaSetDevice (). CudaSetDevice () всегда завершается успешно, если устройство присутствует и вы не создали контекст. Решение, которое я разработал здесь с некоторыми советами от NVidians, - это использовать nvidia-smi, чтобы установить режим вычислений на всех графических процессорах для эксклюзивной обработки, а затем отфильтровать устройства, которые не могут быть использованы для вашей задачи с помощью cudaSetValidDevices (), наконец, сделав вызов cudaFree (), чтобы заставить драйвер CUDA создать контекст на доступном устройстве.

Если вызов cudaFree завершился неудачно, доступных устройств нет:

// Let CUDA select any device from this list of device IDs filtered by your
// own criteria (not shown)
status                                      = cudaSetValidDevices(pGPUList, nGpus);
if (status != cudaSuccess)
{
    printf(("Error searching for compatible GPU\n");
    exit(-1);
}

// Trick driver into creating a context on an available and valid GPU
status                                      = cudaFree(0);
if (status != cudaSuccess)
{
    printf("Error selecting compatible GPU\n");
    exit(-1);
}

// Get device selected by driver
status                                      = cudaGetDevice(&device);
if (status != cudaSuccess)
{
    printf("Error fetching current GPU\n");
    exit(-1);
}

// Your amazing CUDA program goes here...

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

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