Использование CUDA_VISIBLE_DEVICES с sge
Использование sge с комплексом ресурсов под названием "gpu.q", который позволяет управлять ресурсами устройств gpu (это все устройства nvidia). Однако в системах имеется несколько устройств GPU (в монопольном режиме), и если два задания распределены на одном узле, пользователь не может непрозрачно создать контекст для правильного GPU.
Кто-нибудь сталкивался с этой проблемой? Я думал о том, чтобы как-то управлять конкретными ресурсами GPU и отображать идентификаторы хоста и устройства. Что-то вроде
hostA -> gpu0:in_use
hostA -> gpu1:free
hostB -> gpu0:free
hostB -> gpu1:in_use
и т.д.... А затем по запросу ресурса выявляйте выделенные ресурсы gpu на каждом хосте через переменную CUDA_VISIBLE_DEVICES.
Это кажется довольно распространенной проблемой - она, должно быть, уже кем-то решена с преобладанием gpu в вычислительных кластерах.
2 ответа
Как я выяснил, сложным способом, вы не можете просто перечислить устройства и затем вызвать 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...
Примечание: если графические процессоры не находятся в эксклюзивном режиме, вам нужно каким-то образом управлять ими из вашей системы очередей. Описанный здесь метод позволил бы использовать расходный ресурс для мониторинга всех задач на узле, чтобы гарантировать, что они никогда не запрашивали больше графических процессоров, чем доступно на нем, а затем использовать исключительный режим для предотвращения коллизий.
Это действительно проблема, которая должна решаться на уровне кода. Если у вас есть устройства в эксклюзивном режиме, вы можете использовать API CUDA для перечисления всех графических процессоров, а затем пытаться выбирать их, пока не получите доступное. CUDA API возвращает ошибку, если вы пытаетесь выбрать устройство в эксклюзивном режиме, которое уже используется, и в этом случае вы просто переходите к следующему. Вам не нужно делать что-то необычное с расписанием.