Краткое руководство по интеграции Open MPI 4.1.2 с CLion 2021.3.2, работающим на Apple M1
TL;DR
- Настройка сборки баз данных
- Замените «команду» по умолчанию выводом
mpicc -showme
- Настройте пользовательские цели сборки, установив Программу в качестве местоположения clang, Аргументы в качестве аргументов из
mpicc -showme
, местоположение файла, который будет скомпилирован, а также местоположение исполняемого файла и Рабочий каталог. как местоположение clang. - Настройте индивидуальную конфигурацию запуска/отладки, установив Исполняемый файл как
mpirun
и Аргументы программы как количество процессоров и расположение исполняемого файла (вывод компилятора).
Идти параллельно
Предположим, что когда-нибудь вам надоест последовательное программирование и вы решите попробовать что-то более параллельное.
У вас нет никакого представления о библиотеках или фреймворках для параллельного программирования, но у вас есть хороший опыт программирования на C. Погуглив, вы довольно быстро доберетесь до MPI (интерфейс передачи сообщений).
Короче говоря, MPI — это стандарт соединения вещей в параллельных архитектурах.
Существуют две основные реализации этого стандарта: Open MPI и MPICH. Так как я просто хотел поиграть, я случайным образом выбрал Open MPI.
Поскольку я уже установил CLion 2021.3.2
на свой MacBook M1 (macOS Monterey 12.0), я решил интегрировать Open MPI с CLion. Я установил Open MPI 4.1.2
. используя настой по инструкции отсюда.
Неправильный путь
На первый взгляд ничего не могло пойти не так. Погуглив несколько туториалов о том, как объединить Open MPI и CLion, я нашел два хороших ресурса.
В обоих учебниках указано, что для использования Open MPI с CLion
все, что вам нужно сделать, это включить find_package(MPI REQUIRED)
в файл CMakeLists.txt
. Проблема:
Моей первой мыслью было указать путь, куда был установлен Open MPI, поэтому я использую find_package(MPI REQUIRED PATHS /opt/homebrew/Cellar/open-mpi/4.1.2)
. К сожалению, это тоже не сработало:
Проведя дополнительное исследование, я обнаружил, что проблема связана с версией CMake.
В более новых версиях CMake, таких как 3.11, есть эта проблема, а в более старых версиях, таких как 3.5, - нет. Подробнее об этом можно прочитать здесь.
Решение
Прежде всего, вот мой пример кода, который я хочу скомпилировать и запустить в CLion:
Это приветственное приложение для Open MPI, представленное в этом очень хорошем руководстве. Для компиляции кода используем mpicc
:
mpicc main.c -o main.o
Для запуска исполняемого файла мы используем mpirun
. Аргумент -np 4
указывает количество процессоров, на которых вышеуказанный код будет выполняться параллельно:
mpirun -np 4 main.o
Обе команды (mpicc
и mpirun
) стали доступны, когда мы установили Open MPI с помощью brew.
Все, что я хотел сделать в CLion, — связать кнопку сборки с командой mpicc
, а кнопку запуска с командой mpirun
. Решение заключалось в использовании двух замечательных функций CLion: базы данных компиляции и настраиваемые цели сборки.
Как только вы включите базы данных компиляции, вы получите файл JSON с именем compiled_commands.json
. В этом JSON вы найдете элемент с именем command
. Это команда, которая будет выполняться при компиляции main.c
. Первой идеей было заменить команду по умолчанию на mpicc
:
Проблема в том, что CLion по умолчанию не распознает mpicc
как компилятор, поэтому будет отображаться следующая ошибка:
Cannot determine compiler type by executable file: ‘/opt/homebrew/bin/mpicc
Проведя еще одно дополнительное исследование, я обнаружил, что mpicc
на самом деле является оболочкой системного компилятора. В моем случае mpicc
будет использовать компилятор clang. Чтобы узнать, что скрывается за mpicc
, вы можете выполнить следующую команду:
mpicc -showme
Вот мой вывод:
clang - I/opt/homebrew/Cellar/open-mpi/4.1.2/include -L/opt/homebrew/Cellar/open-mpi/4.1.2/lib - L/opt/homebrew/libevent/lib -lmpi
При указании «команды» из файлаcompile_commands.json вам нужно заменить mpicc на вывод mpicc -showme
. Вот моя «команда»:
Для компиляции main.c
используйте кнопку Recompile ‘main.c’
в разделе Build:
Хотя компиляция прошла успешно, исполняемый файл не создается, поскольку CLion автоматически добавляет флаг -fsyntax-only
к команде компиляции, указанной в файле JSON.
Чтобы сгенерировать исполняемый файл, вам нужно создать цель пользовательской сборки. Следуя инструкции от CLion, мы попадаем на следующую форму, которую нам нужно заполнить:
«Программа» описывает программу, которая будет запущена, когда мы нажмем кнопку сборки. В нашем случае мы хотим запустить компилятор clang, поэтому «Программа» должна быть:
/usr/bin/clang
«Аргументы» относятся к аргументам, переданным в «Программу». В нашем случае «Аргументы» состоят из аргументов компилятора clang, показанных командой mpicc -showme
, файла, который будет скомпилирован, и выходного файла. Для меня «Аргументы» это:
Рабочий каталог — это местонахождение «Программы», поэтому в нашем случае:
/usr/bin
С этими настройками, когда мы нажмем кнопку сборки, будет создан исполняемый файл с именем main.o
. Чтобы запустить этот исполняемый файл, мы должны настроить конфигурацию пользовательский запуск/отладка. Что нам в основном нужно сделать, так это заполнить следующую форму:
«Исполняемый файл» относится к программе, которая будет запущена, когда мы нажмем кнопку запуска. В нашем случае это mpirun
:
/opt/homebrew/bin/mpirun
«Аргументы программы» относятся к аргументам «Исполняемого файла». В нашем случае у нас есть два аргумента: количество процессоров и расположение исполняемого файла (вывод mpicc
):
-np 4 /Users/mihailplesa/Documents/Doctorat/Experiments/MPI2/main.o
Теперь, когда мы нажимаем кнопку запуска, мы можем увидеть вывод примера кода сверху:
/opt/homebrew/bin/mpirun -np 4 /Users/mihailplesa/Documents/Doctorat/Experiments/MPI2/main.o Hello world! I'm process 2 out of 4 processes Hello world! I'm process 0 out of 4 processes Hello world! I'm process 3 out of 4 processes Hello world! I'm process 1 out of 4 processes Process finished with exit code 0
Заключительные замечания
Хотя это решение проблемы интеграции Open MPI с CLion на Apple M1, мне кажется, что это не самое элегантное решение. Если вы знаете другие способы, дайте мне знать в комментариях.
Ресурсы
- https://www.jetbrains.com/help/clion/compilation-database.html
- https://www.jetbrains.com/help/clion/custom-build-targets.html
- https://www.open-mpi.org
- https://www.mpich.org
- https://en.wikipedia.org/wiki/Message_Passing_Interface
- https://formulae.brew.sh/formula/open-mpi
- https://www.onooks.com/how-to-import-openmp-and-mpi-to-a-large-clion-cmake-project/
- https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000001110-Configure-CMakeList-properly-to-work-with-OpenMPI-c-
- https://cmake.org/cmake/help/latest/command/find_package.html
- https://stackoverflow.com/questions/49816206/cmake-find-package-specify-path
- https://github.com/Intel-HLS/GenomicsDB/issues/187
- http://condor.cc.ku.edu/~grobe/docs/intro-MPI-C.shtml