Игнорировать OpenMP на машине, на которой его нет.

StackOverflow https://stackoverflow.com/questions/1300180

  •  18-09-2019
  •  | 
  •  

Вопрос

У меня есть программа на 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.И я не читал, что можно собрать на одной машине, а потом запустить на другой машине.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top