Я работаю над библиотекой, которая выполняет динамическое распределение рабочей нагрузки c для решения дифференциального уравнения с использованием CUDA и MPI. У меня есть несколько узлов, каждый из которых имеет графический процессор NVIDIA. Конечно, у каждого узла также есть несколько процессов. Уравнение принимает определенное количество входных данных (6 в этом примере) и создает решение, которое представляется в виде массива в глобальной памяти на графическом процессоре.
Моя текущая стратегия состоит в том, чтобы выделить буфер входных данных на root процесс на каждом узле :
if (node_info.is_node_root_process)
{
cudaMalloc(&gpu_input_buffer.u_buffer, totalsize);
cudaMalloc(&gpu_input_buffer.v_buffer, totalsize);
}
Затем я хочу, чтобы каждый процесс по отдельности вызывал cudaMemcpy
, чтобы скопировать входные данные в глобальную память графического процессора, каждый в другое место в этом входном буфере. Таким образом, входной буфер является непрерывным в памяти, и возможно достичь слияния памяти.
Я понимаю, что вызов cudaMemcpy
из нескольких процессов (или потоков), что вызовы будут выполняться последовательно на устройство. Это нормально.
Я хочу поделиться адресом, который, например, gpu_input_buffer.u_buffer
указывает на каждый процесс. Таким образом, каждый процесс имеет смещение process_gpu_io_offset
, так что данные, относящиеся к этому процессу, просто gpu_input_buffer.u_buffer + process_gpu_io_offset
до gpu_input_buffer.u_buffer + process_gpu_io_offset + number_of_points - 1
.
Я прочитал, что разделять значения указателя через MPI запрещено, поскольку виртуальный используется адресация, но поскольку все данные графического процессора находятся в одном пространстве памяти, а gpu_input_buffer.u_buffer является указателем устройства, я думаю, что это нормально.
Это надежный способ реализовать то, что я хочу?
РЕДАКТИРОВАТЬ: На основе документации CUDA:
Любой указатель памяти устройства или дескриптор события, созданный потоком хоста, может напрямую ссылаться на любой другой поток в том же процессе. Однако он недопустим вне этого процесса и поэтому не может напрямую ссылаться на потоки, принадлежащие другому процессу.
Это означает, что мой оригинальный подход недопустим. Как уже указывалось, для этой цели в CUDA API есть дескрипторы памяти IP C, но я не могу найти никакой информации о том, как поделиться этим с помощью MPI. Документация для cudaIpcMemHandle_t просто:
CUDA IP C дескриптор памяти
, которая не дает никакой информации в поддержку того, что мне нужно делать. Можно создать производный тип MPI и сообщить об этом, но для этого необходимо, чтобы я знал членов cudaIpcMemHandle_t, чего я не знаю.