无法使用 frama-c 分析 openmp 代码
cant analysis openmp code with frama-c
我是 frama-c 的新手。我尝试 运行 使用 openmp 指令对以下 c 代码进行值分析插件:
static void kernel_2mm(int ni, int nj, int nk, int nl, float alpha,
float beta, float *tmp, float *A, float *B, float *C, float *D) {
int i, j, k;
/* D := alpha*A*B*C + beta*D */
#pragma omp parallel for collapse(2)
for (i = 0; i < ni; i++)
for (j = 0; j < nj; j++) {
tmp[i * nj + j] = 0.0;
for (k = 0; k < nk; ++k)
tmp[i * nj + j] += alpha * A[i * nk + k] * B[k * nj + j];
}
#pragma omp parallel for collapse(2)
for (i = 0; i < ni; i++)
for (j = 0; j < nl; j++) {
D[i * nl + j] *= beta;
for (k = 0; k < nj; ++k)
D[i * nl + j] += tmp[i * nj + k] * C[k * nl + j];
}
}
但是我得到了以下错误:
rouki@rouki-VirtualBox:~/Téléchargements/frama-c$ frama-c -val 2mm_mp.c
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i
(no preprocessing)
[kernel] Parsing 2mm_mp.c (with preprocessing)
[kernel] syntax error at 2mm_mp.c:78:
76 int i, j, k;
77 /* D := alpha*A*B*C + beta*D */
78 #pragma omp parallel for collapse(2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
79 for (i = 0; i < ni; i++)
80 for (j = 0; j < nj; j++) {
[kernel] Frama-C aborted: invalid user input.
当我尝试将 -fopenmp
标志添加到预处理器选项时:
frama-c -machdep gcc_x86_64 -val -cpp-command 'gcc -fopenmp -C -E -I. ' 2mm_mp.c
我收到另一条错误消息:
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i
(no preprocessing)
[kernel] warning: your preprocessor is not known to handle option `-nostdinc'.
If pre-processing fails because of it, please add
-no-cpp-frama-c-compliant option to Frama-C's command-line.
If you do not want to see this warning again, explicitly use option
-cpp-frama-c-compliant.
[kernel] warning: your preprocessor is not known to handle option `-dD'.
If pre-processing fails because of it, please add -no-cpp-frama-c-compliant
option to Frama-C's command-line.
If you do not want to see this warning again, explicitly use option
-cpp-frama-c-compliant.
[kernel] Parsing 2mm_mp.c (with preprocessing)
[kernel] warning: trying to preprocess annotation with an
unknown preprocessor.
[kernel] syntax error at 2mm_mp.c:78:
76 int i, j, k;
77 /* D := alpha*A*B*C + beta*D */
78 #pragma omp parallel for collapse(2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
79 for (i = 0; i < ni; i++)
80 for (j = 0; j < nj; j++) {
[kernel] Frama-C aborted: invalid user input.
如何让frama-c可以解析openmp的代码?
有没有办法强制 frama-c 使用 gcc 以外的其他编译器(例如:clang、pgcc)?
我用的是frama-c Phosphorus-20170501版本,gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5).
第一个问题的答案(如何使 Frama-C 可以用 openmp 分析代码?)
Frama-C 当前不支持 OpenMP pragma(直到并包括 Frama-C 16 Sulfur)。
Frama-C 尝试解析它遇到的 pragma,在某些情况下它会忽略它们,但在其他情况下(如您遇到的那个)它会尝试解析它们并失败。这样的编译指示不是 C 标准的一部分,构成 implementation-defined 的编译器扩展。 Frama-C 视具体情况支持某些编译指示,例如 #pragma pack()
。
另请注意,如果您可以使用 -cpp-extra-args
,则不再推荐使用 -cpp-command
。在您的情况下,使用它意味着使用 -cpp-extra-args="-fopenmp"
。并不是说它在这里会有多大帮助,因为无论如何都不支持这些 pragma,但它应该避免你提到的额外警告。
恐怕目前最好的解决方案是手动注释掉这些编译指示,然后再次尝试解析源代码。
第二个问题的答案(有没有办法强制frama-c使用gcc以外的其他编译器(例如:clang、pgcc)?)
是的,像您一样使用 -cpp-command
确实是这样做的方法。但是在这里很好地理解 C 编译链是有帮助的。特别是,处理某些 architecture-specific 问题(例如自定义标准库 headers 和 non-standard 功能)的一种经常推荐的方法是使用编译器生成预处理代码(例如,gcc -E <inputs> -o file.i
), 然后将该文件提供给 Frama-C.
请注意,特别是在 OpenMP 的情况下,GCC 使用的编译指示不会通过预处理删除(这是合乎逻辑的,因为它在 after 预处理期间使用这些编译指示编译本身),所以它对你的情况没有帮助。但它确实有帮助,例如,当使用 MSVC-specific 代码时,其中包含来自 Microsoft SDK 的几个标准库 headers,这些标准库与来自 GNU libc 的标准库不兼容。
最后,请记住 Frama-C 使用 gcc(或其他编译器)仅用于预处理源代码;编译链的其余部分未使用。因此,从 GCC 和 Clang 切换到 Clang 并不会经常改变结果,因为两者在预处理方面都实现了非常相似的特性。同样,通常可以专门使用 -cpp-extra-args
而不是 -cpp-command
,这主要是在 -cpp-extra-args
尚不存在时推荐的。
我是 frama-c 的新手。我尝试 运行 使用 openmp 指令对以下 c 代码进行值分析插件:
static void kernel_2mm(int ni, int nj, int nk, int nl, float alpha,
float beta, float *tmp, float *A, float *B, float *C, float *D) {
int i, j, k;
/* D := alpha*A*B*C + beta*D */
#pragma omp parallel for collapse(2)
for (i = 0; i < ni; i++)
for (j = 0; j < nj; j++) {
tmp[i * nj + j] = 0.0;
for (k = 0; k < nk; ++k)
tmp[i * nj + j] += alpha * A[i * nk + k] * B[k * nj + j];
}
#pragma omp parallel for collapse(2)
for (i = 0; i < ni; i++)
for (j = 0; j < nl; j++) {
D[i * nl + j] *= beta;
for (k = 0; k < nj; ++k)
D[i * nl + j] += tmp[i * nj + k] * C[k * nl + j];
}
}
但是我得到了以下错误:
rouki@rouki-VirtualBox:~/Téléchargements/frama-c$ frama-c -val 2mm_mp.c
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i
(no preprocessing)
[kernel] Parsing 2mm_mp.c (with preprocessing)
[kernel] syntax error at 2mm_mp.c:78:
76 int i, j, k;
77 /* D := alpha*A*B*C + beta*D */
78 #pragma omp parallel for collapse(2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
79 for (i = 0; i < ni; i++)
80 for (j = 0; j < nj; j++) {
[kernel] Frama-C aborted: invalid user input.
当我尝试将 -fopenmp
标志添加到预处理器选项时:
frama-c -machdep gcc_x86_64 -val -cpp-command 'gcc -fopenmp -C -E -I. ' 2mm_mp.c
我收到另一条错误消息:
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i
(no preprocessing)
[kernel] warning: your preprocessor is not known to handle option `-nostdinc'.
If pre-processing fails because of it, please add
-no-cpp-frama-c-compliant option to Frama-C's command-line.
If you do not want to see this warning again, explicitly use option
-cpp-frama-c-compliant.
[kernel] warning: your preprocessor is not known to handle option `-dD'.
If pre-processing fails because of it, please add -no-cpp-frama-c-compliant
option to Frama-C's command-line.
If you do not want to see this warning again, explicitly use option
-cpp-frama-c-compliant.
[kernel] Parsing 2mm_mp.c (with preprocessing)
[kernel] warning: trying to preprocess annotation with an
unknown preprocessor.
[kernel] syntax error at 2mm_mp.c:78:
76 int i, j, k;
77 /* D := alpha*A*B*C + beta*D */
78 #pragma omp parallel for collapse(2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
79 for (i = 0; i < ni; i++)
80 for (j = 0; j < nj; j++) {
[kernel] Frama-C aborted: invalid user input.
如何让frama-c可以解析openmp的代码?
有没有办法强制 frama-c 使用 gcc 以外的其他编译器(例如:clang、pgcc)?
我用的是frama-c Phosphorus-20170501版本,gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5).
第一个问题的答案(如何使 Frama-C 可以用 openmp 分析代码?)
Frama-C 当前不支持 OpenMP pragma(直到并包括 Frama-C 16 Sulfur)。
Frama-C 尝试解析它遇到的 pragma,在某些情况下它会忽略它们,但在其他情况下(如您遇到的那个)它会尝试解析它们并失败。这样的编译指示不是 C 标准的一部分,构成 implementation-defined 的编译器扩展。 Frama-C 视具体情况支持某些编译指示,例如 #pragma pack()
。
另请注意,如果您可以使用 -cpp-extra-args
,则不再推荐使用 -cpp-command
。在您的情况下,使用它意味着使用 -cpp-extra-args="-fopenmp"
。并不是说它在这里会有多大帮助,因为无论如何都不支持这些 pragma,但它应该避免你提到的额外警告。
恐怕目前最好的解决方案是手动注释掉这些编译指示,然后再次尝试解析源代码。
第二个问题的答案(有没有办法强制frama-c使用gcc以外的其他编译器(例如:clang、pgcc)?)
是的,像您一样使用 -cpp-command
确实是这样做的方法。但是在这里很好地理解 C 编译链是有帮助的。特别是,处理某些 architecture-specific 问题(例如自定义标准库 headers 和 non-standard 功能)的一种经常推荐的方法是使用编译器生成预处理代码(例如,gcc -E <inputs> -o file.i
), 然后将该文件提供给 Frama-C.
请注意,特别是在 OpenMP 的情况下,GCC 使用的编译指示不会通过预处理删除(这是合乎逻辑的,因为它在 after 预处理期间使用这些编译指示编译本身),所以它对你的情况没有帮助。但它确实有帮助,例如,当使用 MSVC-specific 代码时,其中包含来自 Microsoft SDK 的几个标准库 headers,这些标准库与来自 GNU libc 的标准库不兼容。
最后,请记住 Frama-C 使用 gcc(或其他编译器)仅用于预处理源代码;编译链的其余部分未使用。因此,从 GCC 和 Clang 切换到 Clang 并不会经常改变结果,因为两者在预处理方面都实现了非常相似的特性。同样,通常可以专门使用 -cpp-extra-args
而不是 -cpp-command
,这主要是在 -cpp-extra-args
尚不存在时推荐的。