Игнорировать OpenMP на машине, на которой его нет.
Вопрос
У меня есть программа на C++, использующая OpenMP, которая будет работать на нескольких машинах, на которых может быть установлен или не установлен OpenMP.
Как я могу сообщить своей программе, что на машине нет OpenMP, и игнорировать эти #include <omp.h>
, директивы OpenMP (например, #pragma omp parallel ...
) и/или библиотечные функции (например, tid = omp_get_thread_num();
) ?
Решение
OpenMP — это среда выполнения компилятора, а не платформа.
то есть.Если вы компилируете свое приложение с помощью Visual Studio 2005 или более поздней версии, у вас всегда будет доступен OpenMP, поскольку среда выполнения поддерживает его.(и если у конечного пользователя не установлена среда выполнения Visual Studio C, ваше приложение вообще не будет работать).
Так что вам не о чем беспокоиться: если вы сможете его использовать, он всегда будет там, как и такие функции, как strcmp.Чтобы убедиться, что у них есть CRT, вы можете установить распространяемый пакет Visual Studio.
редактировать:
ОК, но GCC 4.1 не сможет скомпилировать ваше приложение openMP, поэтому проблема не в целевой машине, а в целевом компиляторе.Поскольку все компиляторы имеют предопределенные макросы, указывающие свою версию, оберните вызовы OpenMP блоками #ifdef.например, GCC использует 3 макроса для определения версии компилятора, __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__
Другие советы
Компиляция OpenMP добавляет определение препроцессора «_OPENMP», поэтому вы можете:
#if defined(_OPENMP)
#pragma omp ...
#endif
Некоторые примеры см. http://bisqwit.iki.fi/story/howto/openmp/#Discussion и следующий за ним код.
Компиляторы должны игнорировать #pragma
директивы, которые они не понимают;в этом вся суть синтаксиса.И функции, определенные в openmp.h
имеют простое и четко определенное значение в непараллельной системе — в частности, заголовочный файл проверит, определяет ли компилятор ENABLE_OPENMP
и, если он не включен, предоставьте правильные резервные варианты.
Итак, все, что вам нужно, это копия openmp.h
для ссылки.Вот один: http://cms.mcc.uiuc.edu/qmcdev/docs/html/OpenMP_8h-source.html .
Однако соответствующая часть кода такова:
#if defined(ENABLE_OPENMP)
#include <omp.h>
#else
typedef int omp_int_t;
inline omp_int_t omp_get_thread_num() { return 0;}
inline omp_int_t omp_get_max_threads() { return 1;}
#endif
В худшем случае вы можете просто взять эти три строки и поместить их в пустышку. openmp.h
файл и используйте его.Остальное будет просто работать.
Есть еще один подход, который мне нравится, позаимствованный у Бисквит:
#if defined(_OPENMP)
#include <omp.h>
extern const bool parallelism_enabled = true;
#else
extern const bool parallelism_enabled = false;
#endif
Затем запустите параллельную программу OpenMP для таких циклов:
#pragma omp parallel for if(parallelism_enabled)
Примечание:есть веские причины за то, что не использовал pragma
, что нестандартно, поэтому Google и другие его не поддерживают.
Как я могу сообщить своей программе, что на машине нет OpenMP, и игнорировать эти
#include <omp.h>
, директивы OpenMP (например,#pragma omp parallel ...
) и/или библиотечные функции (например,tid = omp_get_thread_num();
) ?
Вот поздний ответ, но мы только что получили отчет об ошибке из-за использования #pragma omp simd
на компиляторах Microsoft.
В соответствии с Спецификация OpenMP, раздел 2.2:
Условная компиляция
В реализациях, которые поддерживают препроцессор, имя макроса _openmp определяется как десятичное значение yyyymm, где yyyy и mm являются годом, а онт обозначения версии API OpenMP, которую поддерживает реализация.
Похоже, что современные компиляторы Microsoft поддерживают OpenMP только где-то между 2000 и 2005 годами.Я могу сказать только «где-то между», потому что OpenMP 2.0 был выпущен в 2000 году, а OpenMP 2.5 — в 2005 году.Но Microsoft рекламирует версию 2002 года.
Вот некоторые _OPENMP
цифры...
- Visual Studio 2012 — OpenMP 200203
- Visual Studio 2017 — OpenMP 200203
- IBM XLC 13.01 — OpenMP 201107
- Кланг 7.0 — OpenMP 201107
- GCC 4.8 — OpenMP 201107
- GCC 8.2 — OpenMP 201511
Итак, если вы хотите использовать, скажите #pragma omp simd
охранять петлю и #pragma omp simd
доступен в OpenMP 4.0, то:
#if _OPENMP >= 201307
#pragma omp simd
for (size_t i = 0; i < 16; ++i)
data[i] += x[i];
#else
for (size_t i = 0; i < 16; ++i)
data[i] += x[i];
#endif
который будет работать на нескольких машинах, на которых может быть установлен или не установлен OpenMP.
И чтобы внести ясность: вам, вероятно, придется собрать свою программу на каждой из этих машин.А x86_64 АБИ не гарантирует, что OpenMP доступен на компьютерах x86, x32 или x86_64.И я не читал, что можно собрать на одной машине, а потом запустить на другой машине.