Fdtd3d: Вопросы по параллельным вычислениям

Созданный на 8 янв. 2020  ·  9Комментарии  ·  Источник: zer011b/fdtd3d

Привет Глеб,

Я Ченги. Спасибо за разработку этого великолепного проекта. Это действительно полезно для изучения FDTD и его параллелизма. Но я столкнулся с некоторыми проблемами при использовании вычислений MPI/GPU.

  1. Проблема в том, что когда я вызываю код fdtd3d с помощью следующей команды,
    ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    в котором я создал "vacuum3D_test.txt" на основе "vacuum3D.txt", вставив следующий код
--use-cuda
--cuda-buffer-size 1
--cuda-gpus 0
--num-cuda-threads-x 4
--num-cuda-threads-y 4
--num-cuda-threads-z 4

программа покажет только лог "Загрузка командной строки из файла ./Examples/vacuum3D_test.txt
"и продолжайте ждать, пока я не убью его. Мне просто интересно, есть ли какие-то конфигурации, которые я не установил правильно?
Кстати, это мои флаги cmake на случай, если вам это понадобится:
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVALUE_TYPE=f -DPRINT_MESSAGE=ON -DCUDA_ENABLED=ON -DCUDA_ARCH_SM_TYPE=sm_60 -DCXX11_ENABLED=ON -DPARALLEL_GRID=ON -DPARALLEL_GRID_DIMENSION=3

  1. Кроме того, когда я смоделировал "vacuum3D.txt" с помощью MPI, масштабируемость, обеспечиваемая fdtd3d, не очень идеальна. Например, размер сетки 40 на 40 на 40, что равно 64000. И у меня есть один чип, который имеет 18 ядер. Когда это происходит с 1 процессом, это будет стоить 67,74 секунды, а с включенными 8 процессорами - около 11,34 секунды. Ускорение составляет около 6. А когда я использую больше процессоров, например 18, сокращение времени тривиально, скажем, с 11,34 с до 9,6 с. Это разумно? Могу ли я спросить, существуют ли конфигурации моделирования, которые могут настроить производительность параллельных вычислений?

Если вам нужно больше деталей моделирования, пожалуйста, дайте мне знать. Большое Вам спасибо.

С огромной благодарностью и пожеланиями,
Чэнъи

Question

Все 9 Комментарий

  1. Я не думаю, что он застрял, он просто выполняет вычисления, которые намного медленнее даже в режиме RelWithDebInfo . Кроме того, полный лог печатается в конце выполнения в случае запуска Cuda.

Небольшой совет: быстрее (с точки зрения компиляции и выполнения) указать -DSOLVER_DIM_MODES , если вы точно знаете, какие режимы будете использовать. По умолчанию все моды компилируются в бинарники, что значительно увеличивает время компиляции в случае сборок Cuda. В вашем случае -DSOLVER_DIM_MODES=DIM3 будет достаточно.

  1. Здесь нужно помнить о нескольких вещах. Прежде всего, общее время выполнения каждого временного шага представляет собой сумму времени вычислений и общего времени. Когда сетка относительно небольшая, как в вашем случае, время совместного использования может быть значительным, и требуется тщательный выбор виртуальной топологии (fdtd3d показывает наилучшую виртуальную топологию для указанного размера сетки в своих выходных данных).

Однако в системах с разделяемой памятью операции вообще не требуются (кроме синхронизации потоков). Вот почему OpenMP здесь гораздо более применим, чем MPI, а программы, основанные на MPI, не покажут лучшего ускорения. К сожалению, OpenMP еще не поддерживается в fdtd3d.

Имея все это в виду, в fdtd3d еще есть что настроить.

  • По умолчанию между вычислительными узлами распределяется только ось Ox, но вы можете изменить это с помощью -DPARALLEL_BUFFER_DIMENSION=xyz , что разделит сетку на фрагменты во всех измерениях. Проверьте вывод fdtd3d, так как он рекомендует оптимальную виртуальную топологию.
  • Размер буфера можно установить с помощью --buffer-size B , а операция совместного использования будет выполняться только через каждые B шагов. В этом случае оптимальная виртуальная топология, которую рекомендует fdtd3d, не гарантируется. Но вы можете установить виртуальную топологию вручную с помощью --manual-topology --topology-sizex X --topology-sizey Y --topology-sizez Z .

Обратите внимание, что когда количество процессов не является делителем общего размера сетки, оптимальная виртуальная топология, рекомендованная fdtd3d, также не гарантируется.

Спасибо за этот своевременный ответ.

  1. Что касается вычислений на одном GPU, я переделал fdtd3d со следующими флагами.

cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVALUE_TYPE=f -DPRINT_MESSAGE=ON -DCUDA_ENABLED=ON -DCXX11_ENABLED=ON -DPARALLEL_GRID=ON -DPARALLEL_GRID_DIMENSION=3 -DSOLVER_DIM_MODES=DIM3 -DPARALLEL_BUFFER_DIMENSION=x

и это работало на моей рабочей станции. (Кстати, на моей рабочей станции четыре Tesla P100, из которых арка должна быть SM_60)

  1. Когда я хочу включить вычисления с несколькими GPU с помощью
    mpiexec --mca btl ^openib -n 2 ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    и команды CUDA
--use-cuda
--cuda-buffer-size 2
--buffer-size 2
--cuda-gpus 0,1
--num-cuda-threads-x 4
--num-cuda-threads-y 4
--num-cuda-threads-z 4

ошибка возникает, как показано:

Calculating time step 0...
Calculating time step 1...
Fatal error: an illegal memory access was encountered at /home/t00540502/fdtd3d/Source/Scheme/InternalScheme.inc.h:912
*** FAILED - ABORTING
-------------------------------------------------------
Primary job  terminated normally, but 1 process returned
a non-zero exit code.. Per user-direction, the job has been aborted.

Кажется, первый шаг был в порядке, но что-то не так с вызовом функции InternalSchemeKernelHelpers::calculateFieldStepIterationKernel на втором шаге. Мне интересно, должны ли быть какие-то ошибки, которые я сделал при использовании MPI + CUDA. Не могли бы вы научить меня, как это правильно называть?
Большое спасибо.

Лучший

Может что-то не так с аркой sm_60, я не проверял. Арка по умолчанию — sm_20, так что она должна работать на ваших картах. Однако иногда я видел illegal memory access , когда cuda arch не соответствовал вычислительным возможностям графического процессора.

Вычисления с несколькими GPU имеют ограниченную применимость. Если все данные помещаются в память одного GPU, то гораздо быстрее будет выполнять вычисления на этом единственном GPU на одном вычислительном узле (поскольку не будет промежуточного обмена данными между CPU/GPU и между разными вычислительными узлами).

Но когда сетки очень большие и не могут быть размещены в памяти одного вычислительного узла, нет другого выбора, кроме как использовать несколько вычислительных узлов, каждый из которых может иметь GPU. В этом случае совместное использование данных CPU-GPU и CPU-CPU будет выполняться каждые B шагов, по умолчанию B=1 . Это намного медленнее, чем простое вычисление всех временных шагов на одном графическом процессоре.

Вычисления с несколькими GPU еще не полностью поддерживаются в fdtd3d, потому что в настоящее время fdtd3d полагается на пользователя, чтобы убедиться, что все данные помещаются туда, где они должны помещаться (так же, как и в режиме только CPU). Так что с такими ограничениями должно работать.

@solotcy Была ошибка с неустановленной аркой (см. № 140). Пожалуйста, уточните этот PR у sm_60.

Illegal memory access относится к доступу к глобальной переменной cudaSolverSettings, которая находится в памяти устройства (см. INTERNAL_SCHEME_BASE<Type, TCoord, layout_type>::calculateFieldStepIteration ):

if (SOLVER_SETTINGS.getDoUseTFSF ())

На 2-х из 3-х GPU с одинаковыми вычислительными возможностями sm_35, на которых я тестировал fdtd3d, все работает нормально (все GPU разные модели). Однако в одном случае cudaSolverSettings по какой-то причине становится NULL при входе в метод getDoUseTFSF (т.е. этот ptr равен NULL). Я не смог понять, почему это происходит, но из того, что я обнаружил, это может произойти из-за неисправности устройства.

Похоже, вы смогли успешно запустить fdtd3d по крайней мере на одном из ваших 4 графических процессоров. Попробуйте режим только GPU на каждом GPU отдельно. Поскольку все ваши 4 графических процессора абсолютно одинаковы, в поведении fdtd3d не должно быть никакой разницы. Если есть разница, то более вероятной причиной является неисправность устройства.

Большое спасибо за ответы.

Я проверил PR #140 и пересобрал fdtd3d с добавленным флагом -DCUDA_ARCH_SM_TYPE=sm_60. К сожалению, такая же проблема бывает.

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

Estimated current size: 1437644553 byte.
Setup blocks:
blockCount:
Coord (X : 1.000000, Y : 1.000000, Z : 1.000000).
blockSize:
Coord (X : 200.000000, Y : 200.000000, Z : 200.000000).
Calculating time step 0...
Calculating time step 1...
Fatal error: an illegal memory access was encountered at ~/fdtd3d/Source/Scheme/InternalScheme.inc.h:912

И все становится немного странно, поскольку это работало только на первом графическом процессоре. Для трех других все это не удалось и имело ту же информацию об ошибке.

Спасибо за ваши тесты! Я смог, наконец, выяснить основную причину этой проблемы. PR #141 решает проблему. Теперь fdtd3d должен работать на всех ваших графических процессорах. Режим Multi-gpu теперь тоже работает.

Спасибо за ваши ответы и измененный код. Я смог запустить программу на своей рабочей станции с любым количеством графических процессоров. Затем я могу проверить масштабируемость как на процессорах, так и на графических процессорах.
Это очень круто, спасибо!!!

Не стесняйтесь снова открывать эту тему, если у вас есть дополнительные вопросы.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги