我想知道如何在 Linux 远程计算机上检查 OpenMP 的版本?
我也不知道它安装在哪里。
OpenMP 的 C/C++ 规范似乎没有提供以编程方式执行此操作的直接方法。所以你必须检查你的编译器版本的文档。
gcc --version ## get compiler version
对于 GCC,这是一个很好的资源(未提及 GCC 的最新版本):http://gcc.gnu.org/wiki/openmp:
从 GCC 4.2 开始,编译器实现 OpenMP 标准 2.5 版本,从 4.4 开始,编译器实现 OpenMP 标准 3.0 版本。自 GCC 4.7 起支持 OpenMP 3.1。
经过一番努力,我得到了以下结果。它至少给出了 OpenMP 版本的指示——尽管它仍然需要您查找一些内容。
$ echo |cpp -fopenmp -dM |grep -i open
#define _OPENMP 200805
您可以前往此处 (http://www.openmp.org/specifications/) 查找提供的日期与实际 OpenMP 版本号之间的映射。
在支持预处理器的实现中,_OPENMP 宏名称被定义为具有十进制值 yyyymm,其中 yyyy 和 mm 是实现支持的 OpenMP API 版本的年份和月份名称。
这是一个简短的 C++11 程序,用于显示您的 OpenMP 版本;它还涵盖 2021 年 11 月发布的 5.2 版本。
#include <unordered_map>
#include <iostream>
#include <omp.h>
int main(int argc, char *argv[])
{
std::unordered_map<unsigned,std::string> map{
{199810,"1.0"},
{200203,"2.0"},
{200505,"2.5"},
{200805,"3.0"},
{201107,"3.1"},
{201307,"4.0"},
{201511,"4.5"},
{201811,"5.0"},
{202011,"5.1"},
{202111,"5.2"}
};
std::cout << "We have OpenMP " << map.at(_OPENMP) << ".\n";
return 0;
}
并编译它:
g++ -std=c++11 -fopenmp foobar.cpp
您需要使用
检查您的
gcc
版本
gcc --version
然后查看下面的(不完整)表格(其信息收集自这篇 Wiki 文章 和来自 OpenMP 官方网站的此网页):
| gcc version | OpenMP version | Languages | Offloading |
|-------------|----------------|-----------------|------------|
| 4.2.0 | 2.5 | C | |
| 4.4.0 | 3.0 | C | |
| 4.7.0 | 3.1 | C | |
| 4.9.0 | 4.0 | C, C++ | |
| 4.9.1 | 4.0 | C, C++, Fortran | |
| 5 | | | Yes |
| 6.1 | 4.5 | C, C++ | |
空白条目是因为我没有找到相应的信息。
首先设置环境变量OMP_DISPLAY_ENV: 在bash中:
export OMP_DISPLAY_ENV="TRUE"
或在类似 csh 的 shell 中:
setenv OMP_DISPLAY_ENV TRUE
然后编译并运行您的 OpenMP 程序:
./a.out
将会有其他信息,例如:
OPENMP DISPLAY ENVIRONMENT BEGIN
_OPENMP = '201511'
OMP_DYNAMIC = 'FALSE'
OMP_NESTED = 'FALSE'
OMP_NUM_THREADS = '8'
OMP_SCHEDULE = 'DYNAMIC'
OMP_PROC_BIND = 'FALSE'
OMP_PLACES = ''
OMP_STACKSIZE = '0'
OMP_WAIT_POLICY = 'PASSIVE'
OMP_THREAD_LIMIT = '4294967295'
OMP_MAX_ACTIVE_LEVELS = '2147483647'
OMP_CANCELLATION = 'FALSE'
OMP_DEFAULT_DEVICE = '0'
OMP_MAX_TASK_PRIORITY = '0'
OPENMP DISPLAY ENVIRONMENT END
其中 _OPENMP 有 8 位十进制值 yyyymm,其中 yyyy 和 mm 是实现支持的 OpenMP API 版本的年份和月份名称。
OpenMP 文档有了很大改进。您可以从this链接找到有关支持的OpenMP版本相应编译器的更多信息。
针对你的问题,如上所述,首先找到gcc编译器版本,然后参考上面的链接了解对应的OpenMP版本。
上面的链接还包含不同编译器中支持的 OpenMP 版本。
实际上,我认为你不能直接获取openmp的版本,但是编译器会使用一个预定义的宏
_OPENMP
来表示openmp的发布日期,并且你应该指定-fopenmp
选项来使用这个宏。
您可以先使用这样的 shell 命令获取 openmp 的发布日期
echo _OPENMP | gcc -fopenmp -E -x c - | tail -1
至于我的gcc,是
201511
然后您可以查看 openmp 发布历史记录(https://www.openmp.org/news/press-releases/)来获取版本。
201511
的意思是2015年11月,版本是openmp 4.5
.
发布历史如下:
Date Version
----------------------
Nov 2021 OpenMP 5.2
Nov 2020 OpenMP 5.1
Nov 2018 OpenMP 5.0
Nov 2015 OpenMP 4.5
Jul 2013 OpenMP 4.0
Jul 2011 OpenMP 3.1
May 2008 OpenMP 3.0
May 2005 OpenMP 2.5
Mar 2002 C/C++ 2.0
Nov 2000 Fortran 2.0
Nov 1999 Fortran 1.1
Oct 1998 C/C++ 1.0
Oct 1997 Fortran 1.0
您可以通过运行一个简单的 C 程序来检查它:
#include <stdio.h>
#include <omp.h>
int main() {
#ifdef _OPENMP
printf("OpenMP version: %d\n", _OPENMP);
#else
printf("No OpenMP support\n");
#endif
return 0;
}
然后使用
GCC
进行编译,或者像我一样,通过添加标志 mpicc
来使用
-fopenmp
进行编译
这是上面 user2023370 的答案的一个更安全的版本。为了简洁起见,省略了古老的 OpenMP 版本:
#include <map>
#include <fmt/format.h>
using namespace std;
...
fmt::print("OpenMP v{}\n", map<int, string>{{200805, "3.0"},{201107, "3.1"}, {201307, "4.0"}, {201511, "4.5"}, {201811, "5.0"}}[_OPENMP]);
如果遇到新版本号或损坏的版本号,与使用
at()
函数成员相反,此语句不会抛出异常。
版本号来自 https://github.com/jeffhammond/HPCInfo/blob/master/docs/Preprocessor-Macros.md。
如果您从 GNU 编译器集合中获取 OpenMP,上面评论者提供的链接会很有帮助:https://gcc.gnu.org/wiki/openmp。
但是,请注意,其中指出,虽然 GCC 12 和 13(至少)的功能完成度高达 5.1(我认为 GCC 13 为 5.2),但它们仍然返回
_OPENMP
预处理器值 201511
,对应于OpenMP 4.5。
换句话说,如果您使用另一位评论者列出的方法之一从该
_OPENMP
值获取版本,那么如果您从 GCC 获取 OpenMP,则可能不正确,并且您实际上可能拥有 5.0 的功能+.