Usando CUDA_VISIBLE_DEVICES com sge

1

Usando sge com complexo de recursos chamado 'gpu.q' que permite o gerenciamento de recursos de dispositivos gpu (todos esses dispositivos nvidia). No entanto, nos sistemas existem vários dispositivos GPU (no modo exclusivo) e se duas tarefas são alocadas no mesmo nó, não há como o usuário criar um contexto na GPU correta.

Alguém se deparou com esse problema? Eu estava pensando em, de alguma forma, gerenciar recursos específicos do gpu e mapear os ids do host e do dispositivo. Algo como

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

etc ... E depois, mediante solicitação de recurso, revelar recursos gpu alocados em cada host através da variável CUDA_VISIBLE_DEVICES.

Este parece ser um problema bastante comum - deve ter sido resolvido por alguém até agora com a prevalência de GPUs em clusters de computação.

    
por Marm0t 05.04.2012 / 14:42

2 respostas

1

Como descobri da maneira mais difícil, você não pode simplesmente enumerar dispositivos e, em seguida, chamar cudaSetDevice (). CudaSetDevice () sempre terá êxito se o dispositivo estiver presente e você não tiver criado um contexto. A solução que eu trabalhei aqui com algumas dicas de NVidians é usar nvidia-smi para definir o modo de computação em todas as GPUs para processar exclusivo e, em seguida, filtrar dispositivos que não podem ser usados para sua tarefa com cudaSetValidDevices (), finalmente fazendo uma chamada para cudaFree () para forçar o driver CUDA a criar um contexto em um dispositivo disponível.

Se a chamada para cudaFree falhar, não há dispositivos disponíveis:

// 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...

Nota: se as GPUs não estiverem no modo exclusivo, você precisará gerenciá-las explicitamente de seu sistema de enfileiramento de alguma forma. O método descrito aqui permitiria o uso de um recurso consumível para monitorar todas as tarefas em um nó para garantir que elas nunca solicitassem mais GPUs do que as disponíveis nele e, em seguida, explorasse o modo exclusivo para evitar colisões.

    
por 01.05.2012 / 15:24
0

Este é realmente um problema que deve ser resolvido no nível do código. Se você tiver dispositivos no modo exclusivo, poderá usar a API CUDA para enumerar todas as GPUs e, em seguida, tentar selecioná-las até obter uma que esteja disponível. A API do CUDA retornará um erro se você tentar selecionar um dispositivo no modo exclusivo que já está em uso e, nesse caso, apenas passará para o próximo. Você não deveria precisar fazer nada extravagante com o agendamento.

    
por 05.04.2012 / 20:12