Не удается открыть исходный файл mpi h

Обновлено: 21.11.2024

Я пытаюсь начать работу с OpenMPI на своей машине с Windows (сумасшедший/глупый, я знаю, когда-нибудь я соберусь с двойной загрузкой Linux), но столкнулся с несколькими проблемами.

Я могу заставить mpiexec нормально работать для выполнения заданий, т. е. примеров, которые поставляются с различными установками, но mpicc, похоже, не хочет работать.

В частности, основные библиотеки, используемые mpi.h, не найдены. Я получаю такие ошибки, как:

фатальная ошибка c1083: не удается открыть включаемый файл: 'stdio.h' нет такого файла или каталога.

У меня установлен MingW для gcc/g++, и они работают нормально. Мои пути к переменным среды следующие:

C:\OpenMPI\bin;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin;C:\MinGW \бин;

Единственная причина, по которой существует Visual Studio, - это cl.exe, который, по-видимому, необходим для MPI. Путь IDE указан для некоторых .dll.

Я делаю что-то глупое (кроме того, что использую Windows для написания кода) или упускаю что-то очевидное?

EDIT:
Я попытался включить
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
также в путь, и теперь он не может найти stddef .h, хотя он также находится в этой папке:\

Ответы и ответы

У меня есть несколько предложений.

Первый относится к порядку включения каталогов в Visual C++ IDE. Иногда, если они расположены в неправильном порядке, возникают странные ошибки, и в основном это связано с тем, что у вас разные спецификации включаемых файлов.

Второе относится к природе самих включаемых каталогов. Если они говорят так (прокрутите вниз, чтобы включить снимок экрана), то у вас будет больше каталогов для включения, чем тот, который вы упомянули выше.

Другое дело касается версий включаемых файлов и того, что поставляется с каждым компилятором (в данном случае с VC++ как частью Visual Studio Suite). В этом случае неправильные версии могут привести к большому количеству ошибок.

Спасибо за ответ. Просто чтобы уточнить ваше утверждение, вы имеете в виду порядок элементов Visual C++ в этой программе или в пути, который я указал?

На самом деле я не использую VC, я установил его только для файла cl.exe. Я пытаюсь запустить все из командной строки и использую другую IDE для самого программирования.

Я пытался выяснить, есть ли способ сделать все это без VC, но я еще не нашел его, возможно ли это?

Спасибо за ответ. Просто чтобы уточнить ваше утверждение, вы имеете в виду порядок элементов Visual C++ в этой программе или в пути, который я указал?

На самом деле я не использую VC, я установил его только для файла cl.exe. Я пытаюсь запустить все из командной строки и использую другую IDE для самого программирования.

Я пытался выяснить, есть ли способ сделать все это без VC, но я еще не нашел его, возможно ли это?

Вы можете использовать программу, которая преобразует список аргументов, предоставленный cl.exe, в список аргументов, используемый, скажем, компилятором GNU C (или C++, в зависимости от кода), а затем просто вызывает другой компилятор для скомпилировать код.

Что касается информации о пути, если вы передаете информацию о пути в cl.exe, то да, я имею в виду именно этот порядок, и порядок важен, особенно если вы используете разные репозитории кода с разными версиями или разные значения. Например, если вы когда-либо занимались программированием для Windows, вы, возможно, поняли, что когда вы включаете «windows.h», вы включаете множество определений всех видов, а включение вещей в неподходящее время даст вам массу компилятора. ошибки, связанные с переопределениями, и другие сообщения, которые заполняют окно ошибки за несколько секунд (или меньше).

Поэтому, если вы указываете путь, передайте его в cl.exe в правильном порядке и убедитесь, что список также полный.

Еще одна вещь: stddef.h на самом деле является синонимом заголовка приложения и не обязательно является стандартной библиотекой или заголовком SDK (может быть, но я знаю, что некоторые IDE настроили это так, чтобы поместить все стандартные определения приложений в один). место), поэтому вам также следует убедиться, что если у вас есть специальные включаемые файлы SDK, этот каталог упоминается перед всеми другими включаемыми каталогами.

Получите помощь в создании, анализе, оптимизации и масштабировании приложений для высокопроизводительных вычислений (HPC).

Успех! Подписка добавлена.

Успех! Подписка удалена.

К сожалению, вы должны подтвердить, чтобы завершить это действие. Пожалуйста, нажмите на ссылку подтверждения в вашем электронном письме. Вы можете отправить повторно через свой профиль.

  • Сообщества Intel
  • Форумы разработчиков программного обеспечения
  • Инструменты и SDK
  • Инструментарий Intel® oneAPI HPC
  • катастрофическая ошибка: невозможно открыть исходный файл "mpi.h"

катастрофическая ошибка: невозможно открыть исходный файл "mpi.h"

  • Отметить как новое
  • Добавить в закладки
  • Подписаться
  • Отключить звук
  • Отправить сообщение другу

У нас есть кластер SGI altix под управлением SUSE SLES 11 sp 2.

Я пытаюсь скомпилировать программу "LAMMPS" и получаю сообщение об ошибке: "катастрофическая ошибка: невозможно открыть исходный файл "mpi.h"" для многих файлов.

Есть предложения, как действовать?

  • Отметить как новое
  • Добавить в закладки
  • Подписаться
  • Отключить звук
  • Отправить сообщение другу

Если вы используете оболочки mpi, такие как mpiicc для Intel C, mpicpc для Intel C++, mpiifort для Fortran, для вас устанавливается путь включения mpi.h. Если нет, вы должны указать его в командной строке или в Makefile, но предпочтительнее использовать метод оболочки MPI.

  • Отметить как новое
  • Добавить в закладки
  • Подписаться
  • Отключить звук
  • Отправить сообщение другу

Не могли бы вы написать пример строк "mpi" в Makefile?

  • Отметить как новое
  • Добавить в закладки
  • Подписаться
  • Отключить звук
  • Отправить сообщение другу

Это делается в обычном стиле Linux. Параметр Include path добавляется в строку параметров компилятора, например,

(предположим, вы собираете для 64-разрядного режима/режим Intel64).

но правильный Makefile позволит вам установить mpiifort, mpiicpc, mpiicc в качестве инструментов компилятора, поэтому вам не нужно менять параметры -I.

Некоторые клиенты предпочитают удалять mpif90, mpif77, mpicc, mpiCC из установки Intel MPI и задавать их как символические ссылки, чтобы им не нужно было задавать имя инструментов компилятора при изменении MPI. Это будет работать только в том случае, если вы правильно настроили свою систему, чтобы не возникало конфликтов при установке MPI, которые обычно возникают при установке MPI, поставляемого с дистрибутивом Linux.

Введение в программирование MPI

должен быть первым оператором программы

<УЛ> Это должен быть первый оператор функции MPI в программе.

    Рассмотрим следующую программу Hello World в MPI:

    Процессы в MPI разделены на группы коммуникаторов

<УЛ> список/группа процессов MPI, которые могут взаимодействовать друг с другом

    В MPI определена наиболее часто используемая группа коммуникаторов, которой дается символическое имя MPI_COMM_WORLD

.

    <УЛ> Группа коммуникатора MPI_COMM_WORLD состоит из ВСЕХ процессов MPI, которые использует программа

    Вот ряд очень часто используемых функций MPI

Имя функции Использование MPI_Init(int *argc, char*argv []) Инициализировать систему MPI - должен быть первым оператором в программе MPI MPI_Finalize() Завершает Система MPI MPI_Comm_size(MPI_Comm comm , int * size ) Определяет размер группы, связанной с коммуникатором comm

Размер возвращается в виде целочисленной переменной size MPI_Comm_rank(MPI_Comm comm, int * rank) Определяет ранг вызывающего процесса в коммуникаторе comm

Сообщение хранится в ячейке памяти buff и состоит из элементов count типа datatype

Сообщение будет помечено тегом значения тега

Сообщение ДОЛЖНО БЫТЬ получено от источника процесса в группе связи comm И сообщение ДОЛЖНО БЫТЬ помечено тегом значения тега

Полученное сообщение будет сохранено в буфере памяти, в котором будет место для хранения элементов счетчика типа данных

При выходе из функции статус выхода сохраняется в status .

Информация о полученном сообщении возвращается в переменной состояния, например,

<УЛ>
  • Тег полученного сообщения — status.MPI_TAG и
  • Ранг процесса отправки (сообщения) — status.MPI_SOURCE .
  • В большинстве случаев вы знаете структуру полученных данных и можете игнорировать значение статуса. Если вы передадите NULL в качестве параметра состояния, MPI не вернет значение состояния.

    Параллельные программы позволяют пользователям в полной мере использовать многоузловую структуру суперкомпьютерных кластеров. Интерфейс передачи сообщений (MPI) — это стандарт, позволяющий нескольким различным процессорам в кластере взаимодействовать друг с другом. В этом руководстве мы будем использовать компилятор Intel C++, GCC, IntelMPI и OpenMPI для создания многопроцессорной программы «hello world» на C++. В этом руководстве предполагается, что пользователь имеет опыт работы как с терминалом Linux, так и с C++.

    Ресурсы:

    Настройка и «Hello, World»¶

    Начните с входа в кластер и использования ssh для входа в узел компиляции. Это можно сделать с помощью команды:

    Далее мы должны загрузить MPI в нашу среду. Начните с загрузки выбранного вами компилятора C++ и соответствующей библиотеки MPI. Используйте следующие команды при использовании компилятора GNU C++:

    Компилятор GNU C++

    Или используйте следующие команды, если вы предпочитаете использовать компилятор Intel C++:

    Компилятор Intel C++

    Это должно подготовить вашу среду со всеми необходимыми инструментами для компиляции и запуска вашего кода MPI. Давайте теперь начнем создавать наш файл C++. В этом руководстве мы назовем наш файл кода: hello_world_mpi.cpp

    Откройте hello_world_mpi.cpp и начните с включения стандартной библиотеки C и библиотеки MPI , а также с создания основной функции кода C++:

    Теперь давайте настроим несколько директив MPI для распараллеливания нашего кода. В этом руководстве «Hello World» мы будем использовать следующие четыре директивы:

    Эта функция инициализирует среду MPI. Он принимает адреса аргументов командной строки C++ argc и argv.

    Эта функция возвращает общий размер среды через количество процессов. Функция принимает среду MPI и адрес памяти целочисленной переменной.

    Эта функция возвращает идентификатор процесса процессора, вызвавшего функцию. Функция принимает среду MPI и адрес памяти целочисленной переменной.

    Этих четырех директив должно быть достаточно, чтобы запустить наш параллельный «hello world». Мы начнем с создания двух переменных, process_Rank и size_Of_Cluster, для хранения идентификатора каждого из параллельных процессов и количества процессов, работающих в кластере, соответственно. Мы также реализуем функцию MPI_Init, которая инициализирует коммуникатор mpi:

    Давайте теперь получим некоторую информацию о нашем кластере процессоров и распечатаем ее для пользователя. Мы будем использовать функции MPI_Comm_size() и MPI_Comm_rank() для получения количества процессов и ранга процесса соответственно:

    Наконец, давайте закроем среду, используя MPI_Finalize():

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

    OpenMPI

    Интел МПИ

    Это создаст исполняемый файл, который мы можем передать Summit в качестве задания. Для выполнения скомпилированного кода MPI необходимо использовать специальную команду:

    Флаг -np указывает количество процессоров, которые должны быть задействованы при выполнении программы.

    В своем сценарии задания загрузите тот же компилятор и варианты OpenMPI, которые вы использовали выше для компиляции программы, и запустите задание с помощью slurm для выполнения приложения. Ваш сценарий задания должен выглядеть примерно так:

    OpenMPI

    Интел МПИ

    Важно отметить, что в Summit на узел приходится 24 ядра. Для приложений, которым требуется более 24 процессов, вам потребуется запросить несколько узлов в вашем задании. Наш выходной файл должен выглядеть примерно так:

    Барьеры и синхронизация MPI¶

    Как и многие другие утилиты параллельного программирования, синхронизация является важным инструментом для обеспечения безопасности потоков и обеспечения обработки определенных участков кода в определенных точках. MPI_Barrier — это блокировка процесса, которая удерживает каждый процесс на определенной строке кода до тех пор, пока все процессы не достигнут этой строки кода. MPI_Barrier можно вызывать как таковой:

    Чтобы справиться с барьерами, давайте изменим нашу программу «Hello World», чтобы она выводила каждый процесс в порядке идентификатора потока. Начиная с нашего кода «Hello World» из предыдущего раздела, начните с вложения нашего оператора печати в цикл:

    Далее давайте реализуем в цикле условный оператор, который будет печатать только тогда, когда итерация цикла соответствует рангу процесса.

    Наконец, реализуйте барьерную функцию в цикле. Это обеспечит синхронизацию всех процессов при прохождении цикла.

    Компиляция и запуск этого кода приведет к следующему результату:

    Передача сообщений¶

    Передача сообщений — это основная утилита в интерфейсе приложения MPI, позволяющая процессам взаимодействовать друг с другом. В этом руководстве мы изучим основы передачи сообщений между двумя процессами.

    Передача сообщений в MPI обрабатывается соответствующими функциями и их аргументами:

    Аргументы следующие:

    Давайте реализуем передачу сообщений на примере:

    Пример¶

    Мы создадим двухпроцессный процесс, который будет передавать число 42 от одного процесса к другому. Мы будем использовать нашу программу «Hello World» в качестве отправной точки для этой программы. Начнем с создания переменной для хранения некоторой информации.

    Теперь создайте условия if и else if, которые определяют соответствующий процесс для вызова функций MPI_Send() и MPI_Recv(). В этом примере мы хотим, чтобы процесс 1 отправил сообщение, содержащее целое число 42, процессу 2.

    Наконец мы должны вызвать MPI_Send() и MPI_Recv(). Мы будем передавать в функции следующие параметры:

    Давайте реализуем эти функции в нашем коде:

    Компиляция и запуск нашего кода с двумя процессами приведет к следующему результату:

    Групповые операторы: разбросать и собрать¶

    Групповые операторы очень полезны для MPI.Они позволяют распределять массивы данных от корневого процесса ко всем другим доступным процессам, или данные от всех процессов могут быть собраны в одном процессе. Эти операторы могут устранить необходимость в большом количестве стандартного кода с помощью двух функций:

    MPI_Scatter:

    MPI_Gather:

    Чтобы лучше понять эти функции, давайте продолжим и создадим программу, которая будет использовать функцию рассеяния. Обратите внимание, что функция сбора (не показанная в примере) работает аналогично и, по сути, является обратной функцией функции разброса. Дополнительные примеры использования функции сбора можно найти в руководствах по MPI, перечисленных в качестве ресурсов в начале этого документа.

    Пример¶

    Мы создадим программу, которая разбрасывает по одному элементу массива данных каждому процессу. В частности, этот код будет распределять четыре элемента массива по четырем различным процессам. Мы начнем с базовой функции C++ main вместе с переменными для хранения ранга процесса и количества процессов.

    Теперь давайте настроим среду MPI, используя MPI_Init, MPI_Comm_size, MPI_Comm_rank и

    Далее создадим массив с именем distro_Array для хранения четырех чисел. Мы также создадим переменную с именем разбросанные_данные, в которую мы будем распределять данные.

    Теперь мы начнем использовать групповые операторы. Мы будем использовать оператор разброса для распределения distro_Array по разбросанным_данным. Давайте взглянем на параметры, которые мы будем использовать в этой функции:

    Давайте посмотрим, как это реализовано в коде. Мы также напишем оператор печати после вызова разброса:

    Выполнение этого кода выведет четыре числа в массиве дистрибутива в виде четырех отдельных чисел, каждое из которых получено от разных процессоров (обратите внимание, что порядок рангов не обязательно последовательный):

    Вы хотите запускать mpi в среде, настроенной таким образом, чтобы вам не нужно было вводить пароль для каждой машины, на которой будут выполняться процессы mpi. Для этого в нашей системе вам необходимо: (1) иметь открытый ключ rsa в файле с именем ~/.ssh/authorized_keys2; и (2) обычно запускайте ssh-agent и ssh-add в терминале, с которого вы будете запускать mpirun (часто при запуске с машины, на которой вы удаленно вошли в систему ).

      одноразовая настройка: если вы никогда этого не делали, сначала создайте ключ rsa и скопируйте открытый ключ в файл autorized_keys2.

    • В терминале сначала выполните следующее перед запуском mpirun:
    • Вы можете проверить, работает ли это, подключившись по ssh к тестовому компьютеру (вам не нужно будет вводить свой пароль или фразу-пароль, если вы правильно настроили его. Например, если вы используете морковь, вы можете подключиться по ssh к масло:
    • Вот некоторая информация о ssh-agent (вам не нужно запускать пример parallel-ssh или пример добавления tmux, просто попробуйте подключиться к машине по ssh после запуска ssh-agent и ssh-add): ssh без пароля

    мпирун

    mpirun используется для запуска приложений mpi. Он принимает аргументы командной строки, которые определяют количество порождаемых процессов, набор машин, на которых должны запускаться процессы приложения (или вы можете указать файл хоста, содержащий имена машин), и команду для запуска. Например:

    Использование хост-файла

    Часто mpirun запускается с аргументом командной строки hostfile, в котором указан набор хостов, на которых должны запускаться процессы MPI. Как правило, все процессы MPI запускают один и тот же исполняемый файл. Однако это не требуется. Некоторые программы могут быть написаны в стиле «босс-рабочий», где один процесс действует как босс, распределяя работу и координируя результаты других процессов, рабочих, выполняющих параллельные задачи. Другие программы могут иметь отдельные типы задач, которые выполняют подмножества процессов. В этих случаях у программиста могут быть отдельные исполняемые файлы для каждого типа процессов. Чтобы запускать такие MPI-программы, вам нужно указать, какие процессы могут запускаться для каждого исполняемого файла, используя несколько параметров командной строки -np, по одному на каждый исполняемый файл.

    Создание хост-файлов

    Хост-файлы состоят из машин, по одной в строке. Списки без полного доменного имени (например, loon против loon.cs.swarthmore.edu) предполагают, что хосты находятся в том же домене, что и тот, на котором работает mpirun. Хост-файлы могут дополнительно указывать количество слотов на машину. Слот — это единица распределения на хосте, которая указывает количество процессов MPI, которые могут быть запущены на хосте. Если слот не указан, то MPI использует количество ядер на хосте, чтобы определить количество процессов, которые он может создать. Добавляя slots=X в hostfiles, вы можете изменить то, как mpirun распределяет процессы по хостам. Номер слота может быть любым положительным числом; оно не ограничено фактическим количеством ядер на машине, но производительность может быть ограничена. Вот пример двух hostfiles: Если у robin 4 ядра, то:

    узнать информацию о наших машинах

    Когда вы запускаете приложения MPI, вы можете захотеть создать больше процессов mpi на машинах с большим количеством процессоров. Для этого вы можете использовать предложение «slots=n» в hostfile. Чтобы узнать системную информацию о данном компьютере: Кроме того, на следующей странице страниц справки CS приведена сводная информация о компьютерах в нашей системе: Информация о лабораторном компьютере CS

    В /usr/swat/local/db находятся файлы, в которых перечислены все имена хостов для машин в разных лабораториях. Вы можете использовать их для создания файлов хоста MPI. Например: затем отредактируйте hostfile, чтобы удалить все хосты, которые вы не хотите включать.

    использование autoMPIgen для создания хост-файлов

    В нашей системе вы можете запустить autoMPIgen, чтобы автоматически генерировать файлы хостов MPI из хороших машин, определенных различными способами в нашей системе.

    Запустите autoMPIgen -h, чтобы просмотреть аргументы командной строки для дополнительных параметров конфигурации.

    Дополнительную информацию об autoMPIgen (и smarterSSH) можно найти на странице PeerMon

    Для отладки программ MPI можно использовать как gdb, так и valgrind. Помните, что вы должны компилировать с флагом -g, чтобы убедиться, что компилятор включает отладочную информацию в исполняемый файл mpi. В противном случае вы не получите номера строк исходного кода, связанные, например, с вашим исполняемым файлом.

    Как правило, при отладке параллельных программ отладка выполняется с наименьшим возможным числом процессов (2, если возможно).

    Чтобы использовать valgrind, выполните следующую команду: В этом примере будут запущены два процесса MPI, выполняющие mpiprog в valgrind. Это означает, что оба процесса будут выводить ошибки valgrind на терминал.

    Чтобы использовать gdb, сначала создайте файл хоста, который включает только машину, на которой вы вошли в систему (gdb в MPI создаст окна xterm, которые в противном случае должны были бы быть перенаправлены Xforward с удаленной машины). Затем выполните команду, подобную следующей: Поскольку это порождает два окна терминала, каждое из которых запускает сеанс gdb для одного из двух процессов MPI в этом запуске. В каждом сеансе gdb вы можете установить точки останова, выбрать команду запуска для запуска каждого запуска, а затем использовать другие команды gdb для проверки состояния выполнения процессов MPI.

    Если ваши настройки xterm с подсветкой выходного шрифта gdb плохо читаются, вы можете изменить настройки xterm по умолчанию в файле .Xdefaults, а затем сбросить их на свои изменения, запустив xrdb - объединить ~/.Xdefaults. Например:

    Вот несколько ссылок на мое руководство по gdb и руководство по valgrind. Кроме того, глава 3 книги «Погружение в системы» содержит более подробную версию большей части этого содержания.

    Иногда mpirun дает сбой, потому что хост в hostfile недоступен. В этом случае убедитесь, что хост доступен, а если нет, удалите хост из файла хоста и повторите попытку. Полезно использовать скрипт для проверки этого, вот пример скрипта checkup.sh для проверки работоспособности хостов в файле хостов: Скрипт checkup.sh может выглядеть следующим образом: Затем запустите файл хоста, чтобы проверить, доступны ли хосты Обычно вам не нужно этого делать, но если все узлы в файле хоста доступны, но у вас возникли проблемы с повторным запуском mpirun, вы можете попробовать запустить orte-clean для очистки всех процессов и файлов, оставшихся от предыдущего запуска, которые могут мешать последующим запускам.

    При запуске в нашей системе вы можете увидеть следующее предупреждение: Вы можете игнорировать это, так как это mpirun ищет сетевые карты infiniband и не находит их в нашей системе (и вместо этого использует Ethernet). Вы также можете избавиться от этих предупреждений при запуске mpirun, установив для параметра MCA btl_base_warn_component_unused значение 0: один из способов сделать это — в командной строке mpirun. Другой способ — добавить переменную среды оболочки с этим параметром. и запустите mpirun без этой опции командной строки: наконец, вы можете добавить эту переменную среды в свой файл .bashrc, и она всегда будет добавляться к вашим переменным bash env, а затем вы можете просто запустить без этого предупреждения. Добавьте это в свой файл ~/.bashrc: как только вы установите это в своем .bashrc, в любой новой оболочке bash вы можете запустить mpirun и больше не видеть это предупреждение: в более старой оболочке, предшествует вашему изменению, вы можете запустить source ~/.bashrc, чтобы обновить его переменные среды из нового .bashrc, чтобы получить это.

    Дополнительную информацию о настройках MCA см. в разделе часто задаваемых вопросов MPI, ссылка на который приведена здесь: Ссылки на справочные материалы и учебные пособия по MPI

    Читайте также: