我正在尝试对某些文件实施和编码,其中一些包含SIMD调用。我已经在服务器上编译了此代码,该服务器与我的机器运行的操作系统基本相同,但我无法对其进行编译。
这是错误:
make
g++ main.cpp -march=native -o main -fopenmp
In file included from /usr/lib/gcc/x86_64-linux-gnu/7/include/immintrin.h:53:0,
from tensor.hpp:9,
from main.cpp:4:
/usr/lib/gcc/x86_64-linux-gnu/7/include/avx512vlintrin.h: In function ‘_ZN6TensorIdE8add_avx2ERKS0_._omp_fn.5’:
/usr/lib/gcc/x86_64-linux-gnu/7/include/avx512vlintrin.h:447:1: error: inlining failed in call to always_inline ‘__m256d _mm256_mask_add_pd(__m256d, __mmask8, __m256d, __m256d)’: target specific option mismatch
_mm256_mask_add_pd (__m256d __W, __mmask8 __U, __m256d __A,
^~~~~~~~~~~~~~~~~~
In file included from main.cpp:4:0:
tensor.hpp:228:33: note: called from here
res = _mm256_mask_add_pd(tmp, 0xFF, _mm256_mask_loadu_pd(tmp, 0xFF, &elements[i]), _mm256_mask_loadu_pd(tmp, 0xFF, &a.elements[i]));
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/lib/gcc/x86_64-linux-gnu/7/include/immintrin.h:53:0,
from tensor.hpp:9,
from main.cpp:4:
/usr/lib/gcc/x86_64-linux-gnu/7/include/avx512vlintrin.h:610:1: error: inlining failed in call to always_inline ‘__m256d _mm256_mask_loadu_pd(__m256d, __mmask8, const void*)’: target specific option mismatch
_mm256_mask_loadu_pd (__m256d __W, __mmask8 __U, void const *__P)
^~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:4:0:
tensor.hpp:228:33: note: called from here
res = _mm256_mask_add_pd(tmp, 0xFF, _mm256_mask_loadu_pd(tmp, 0xFF, &elements[i]), _mm256_mask_loadu_pd(tmp, 0xFF, &a.elements[i]));
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/lib/gcc/x86_64-linux-gnu/7/include/immintrin.h:53:0,
from tensor.hpp:9,
from main.cpp:4:
/usr/lib/gcc/x86_64-linux-gnu/7/include/avx512vlintrin.h:610:1: error: inlining failed in call to always_inline ‘__m256d _mm256_mask_loadu_pd(__m256d, __mmask8, const void*)’: target specific option mismatch
_mm256_mask_loadu_pd (__m256d __W, __mmask8 __U, void const *__P)
^~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:4:0:
tensor.hpp:228:33: note: called from here
res = _mm256_mask_add_pd(tmp, 0xFF, _mm256_mask_loadu_pd(tmp, 0xFF, &elements[i]), _mm256_mask_loadu_pd(tmp, 0xFF, &a.elements[i]));
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Makefile:7: recipe for target 'main' failed
make: *** [main] Error 1
谷歌搜索问题并没有真正帮助,因为所有答案都指出了一切,我已经做好/尝试过。
有人可以提供一些背景信息,以了解为什么它不起作用。
编辑:
int main(){
#ifdef __AVX512F___
auto tt = createTensor();
auto tt2 = createTensor();
auto res = tt.addAVX512(tt2);
#endif
}
//This is in tensor.hpp
#ifdef __AVX512F__
Tensor<T> Tensor::addAVX512(_param_){
res = _mm256_mask_add_pd(tmp, 0xFF, _mm256_mask_loadu_pd(tmp, 0xFF, &elements[i]), _mm256_mask_loadu_pd(tmp, 0xFF, &a.elements[i]));
}
#endif
这就是发生的事情的要点...我已将所有SIMD调用都封装在#ifdefs等中。
答案 0 :(得分:2)
GCC仅允许您将内部函数用于已启用编译器使用的指令集。例如有关AVX1内部函数的相关问题:inlining failed in call to always_inline '__m256d _mm256_broadcast_sd(const double*)'
这些是256位内部函数的_mask_
版,它们需要AVX512VL。
(关于-mavx
的问题我的评论是错误的,我没有注意到名称或参数中的_mask
,只是_mm256
。)
您可能正在服务器上的KNL(骑士登陆/至强皮)上进行编译,该服务器具有AVX512F但没有AVX512VL。因此-march=native
将设置-mavx512f
。 (与具有AVX512VL的Skylake-AVX512不同,Skylake-AVX512允许使用很酷的新AVX512内容,例如带有较窄矢量的掩码指令。)
并且您在tensor.hpp
中发现了一个错误,该错误仅在检查__AVX512F__
而不是__AVX512VL__
后才使用AVX512VL内部函数。 AVX512-任何内容表示512F,因此不需要同时检查两者。
#ifdef __AVX512F__ // should be __AVX512VL__
Tensor<T> Tensor::addAVX512(_param_){
res = _mm256_mask_add_pd(tmp, 0xFF, _mm256_mask_loadu_pd(tmp, 0xFF, &elements[i]), _mm256_mask_loadu_pd(tmp, 0xFF, &a.elements[i]));
}
#endif
这是没有意义的,如果要使用常量全一掩码,则不需要使用这些内在函数的掩码版本。像普通人一样使用_mm256_add_pd
,仅检查__AVX__
。或使用_mm512_add_pd
。
我最初以为这是来自TensorFlow,但是(根据您的评论)这没有任何意义。并不会那么糟糕。 使用完全真实的掩码将掩码合并为同一tmp
的3个副本是没有道理的;如果编译器无法将mask = all-ones优化到未屏蔽的负载中,那么引入错误依赖关系似乎是一种愚蠢的方法。
还有可怕的C ++风格:您有一个名为__m256d tmp
的变量作为全局成员或类成员?它甚至不是局部伪变量,它可能存在于编译器无法完全优化它的地方。