Подтвердить что ты не робот

Игнорировать OpenMP на компьютере, у которого его нет

У меня есть программа на С++, использующая OpenMP, которая будет работать на нескольких машинах, которые могут иметь или не иметь OpenMP.

Как я могу сообщить своей программе, нет ли в машине OpenMP и игнорировать те #include <omp.h>, директивы OpenMP (например, #pragma omp parallel ...) и/или библиотечные функции (например, tid = omp_get_thread_num();)?

4b9b3361

Ответ 1

OpenMP - это среда выполнения компилятора, а не платформа.

т. Если вы скомпилируете свое приложение с помощью Visual Studio 2005 или выше, у вас всегда есть OpenMP, доступный по мере его поддержки. (и если у конечного пользователя не установлена ​​среда исполнения Visual Studio C, ваше приложение не будет работать вообще).

Итак, вам не нужно беспокоиться, если вы можете использовать его, он всегда будет рядом с такими функциями, как strcmp. Чтобы убедиться, что у них есть CRT, вы можете установить распространяемую визуальную студию.

изменить:

ok, но GCC 4.1 не сможет скомпилировать ваше приложение openMP, поэтому проблема не является целевой машиной, а целевым компилятором. Поскольку у всех компиляторов есть предопределенные макросы, дающие их версию, оберните ваши вызовы OpenMP блоками #ifdef. например, GCC использует 3 макроса для идентификации версии компилятора, __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__

Ответ 2

Компиляция OpenMP добавляет определение препроцессора "_OPENMP", поэтому вы можете сделать:

#if defined(_OPENMP)
   #pragma omp ...
#endif

В некоторых примерах см. http://bisqwit.iki.fi/story/howto/openmp/#Discussion и следующий код.

Ответ 3

Составители должны игнорировать директивы #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 файл и использовать это. Остальное будет работать.

Ответ 4

Как я могу сделать так, чтобы моя программа знала, что на машине нет OpenMP, и игнорирую эти директивы #include <omp.h>, OpenMP (например, #pragma omp parallel...) и/или библиотечные функции (например, tid = omp_get_thread_num();) 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
  • Clang 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.

И чтобы быть ясным, вам, вероятно, нужно собрать свою программу на каждой из этих машин. ABI x86_64 не гарантирует, что OpenMP доступен на машинах x86, x32 или x86_64. И я не читал, вы можете построить на одной машине, а затем запустить на другой машине.

Ответ 5

Есть еще один подход, который мне нравится, заимствованный из Bisqwit:

#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 и другие не поддерживают ее.