Linux 当COPT包含空格时,如何交叉编译docker build image上的tensorflow与bazel 背景信息

Linux 当COPT包含空格时,如何交叉编译docker build image上的tensorflow与bazel 背景信息,linux,docker,cross-compiling,bazel,tensorflow-serving,Linux,Docker,Cross Compiling,Bazel,Tensorflow Serving,我想在一些旧机器(目标系统)上运行tensorflow服务,这些机器不支持标准tensorflow构建中使用的现代cpu指令。我使用这些通过docker安装tf服务。然而,我遇到了错误Tensorflow服务非法指令核心转储,与此类似。建议的解决方案是使用docker构建映像在我的目标系统上编译二进制文件,如下所述 由于此部分与我的问题的复制相关,我将在此处复制相关命令: git clone https://github.com/tensorflow/serving cd serving doc

我想在一些旧机器(目标系统)上运行tensorflow服务,这些机器不支持标准tensorflow构建中使用的现代cpu指令。我使用这些通过docker安装tf服务。然而,我遇到了错误
Tensorflow服务非法指令核心转储
,与此类似。建议的解决方案是使用docker构建映像在我的目标系统上编译二进制文件,如下所述

由于此部分与我的问题的复制相关,我将在此处复制相关命令:

git clone https://github.com/tensorflow/serving
cd serving
docker build --pull -t $USER/tensorflow-serving-devel -f tensorflow_serving/tools/docker/Dockerfile.devel .

这将在我的慢速目标机器上的docker容器中编译带有标志
-march=native
的二进制文件,并正常工作


目标系统信息 然而,在我的旧机器上,编译需要花费很长时间,我想使用我的另一台功能更强大的pc交叉编译二进制文件。我使用本文中提供的命令查找目标系统所需的编译标志,以复制构建标志
-march=native
,这是在上述过程中隐式使用的默认标志

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )//g'
给了我以下旗帜:

-march=core2 -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 -mno-sse4a -mcx16 -msahf -mno-movbe -mno-aes -mno-sha -mno-pclmul -mno-popcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx -mno-avx2 -mno-sse4.2 -mno-sse4.1 -mno-lzcnt -mno-rtm -mno-hle -mno-rdrnd -mno-f16c -mno-fsgsbase -mno-rdseed -mno-prfchw -mno-adx -mfxsr -mno-xsave -mno-xsaveopt -mno-avx512f -mno-avx512er -mno-avx512cd -mno-avx512pf -mno-prefetchwt1 -mno-clflushopt -mno-xsavec -mno-xsaves -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512ifma -mno-avx512vbmi -mno-clwb -mno-mwaitx -mno-clzero -mno-pku --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=2048 -mtune=core2
请特别注意结尾处包含空格的以下标志:

 --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=2048
我可以通过build参数
TF\u service\u build\u OPTIONS
在docker构建过程中提供这些标志,如中所述

然后使用该字符串运行bazel构建,可以在

因此,我从上面获取所有标志,并将
--copt=
放在前面,并将结果字符串放在变量
TF\u service\u BUILD\u OPTIONS
中。这是我的全部命令,包括结尾处带有空格的COPT:

docker build --pull \
    --build-arg TF_SERVING_BUILD_OPTIONS="--copt=-mmmx --copt=-mno-3dnow --copt=-msse --copt=-msse2 --copt=-msse3 --copt=-mssse3 --copt=-mno-sse4a --copt=-mcx16 --copt=-msahf --copt=-mno-movbe --copt=-mno-aes --copt=-mno-sha --copt=-mno-pclmul --copt=-mno-popcnt --copt=-mno-abm --copt=-mno-lwp --copt=-mno-fma --copt=-mno-fma4 --copt=-mno-xop --copt=-mno-bmi --copt=-mno-bmi2 --copt=-mno-tbm --copt=-mno-avx --copt=-mno-avx2 --copt=-mno-sse4.2 --copt=-mno-sse4.1 --copt=-mno-lzcnt --copt=-mno-rtm --copt=-mno-hle --copt=-mno-rdrnd --copt=-mno-f16c --copt=-mno-fsgsbase --copt=-mno-rdseed --copt=-mno-prfchw --copt=-mno-adx --copt=-mfxsr --copt=-mno-xsave --copt=-mno-xsaveopt --copt=-mno-avx512f --copt=-mno-avx512er --copt=-mno-avx512cd --copt=-mno-avx512pf --copt=-mno-prefetchwt1 --copt=-mno-clflushopt --copt=-mno-xsavec --copt=-mno-xsaves --copt=-mno-avx512dq --copt=-mno-avx512bw --copt=-mno-avx512vl --copt=-mno-avx512ifma --copt=-mno-avx512vbmi --copt=-mno-clwb --copt=-mno-mwaitx --copt=-mno-clzero --copt=--param l1-cache-size=32 --copt=--param l1-cache-line-size=64 --copt=--param l2-cache-size=2048 --copt=-mtune=core2" \
    -t $USER/tensorflow/serving-devel \
    -f tensorflow_serving/tools/docker/Dockerfile.devel .
问题 然而,bazel抱怨如下,这可能是由于
--param
一级缓存大小=32
之间的空间,这是为bazel构建调用提供的C编译器的一个选项

ERROR: Skipping 'l1-cache-line-size=64': couldn't determine target from filename 'l1-cache-line-size=64'
ERROR: couldn't determine target from filename 'l1-cache-line-size=64'
INFO: Elapsed time: 20.233s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded)
The command '/bin/sh -c bazel build --color=yes --curses=yes     ${TF_SERVING_BAZEL_OPTIONS}     --verbose_failures     --output_filter=DONT_MATCH_ANYTHING     ${TF_SERVING_BUILD_OPTIONS}     tensorflow_serving/model_servers:tensorflow_model_server &&     cp bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server     /usr/local/bin/' returned a non-zero code: 1
我试过的
  • 我尝试在最后的标志中转义空格字符:
  • 但是bazel仍然抱怨与上面相同的错误消息

  • 我尝试将命令括在双引号或单引号中:
  • 也会出现与之前相同的错误

  • 我尝试对copts使用内部双引号,并用外部单引号将
    TF\u-service\u-BUILD\u选项
    包装起来,但错误相同

  • 我尝试用
    \x22
    从COPT中转义双引号。一个与以前类似的错误出现了。这一次表明目标格式不正确
    错误:跳过“一级缓存大小=32\x22”:目标模式错误…

  • 我尝试用
    \40
    转义空格字符:

  • 这次bazel没有抱怨,因为copt的参数是一个没有正规空格的字符串。但是,参数被错误地传递给gcc,因为我得到以下错误:

    ERROR: /root/.cache/bazel/_bazel_root/e53bbb0b0da4e26d24b415310219b953/external/grpc/BUILD:692:1: C++ compilation of rule '@grpc//:grpc_base_c' failed (Exit 1): gcc failed: error executing command 
      (cd /root/.cache/bazel/_bazel_root/e53bbb0b0da4e26d24b415310219b953/execroot/tf_serving && \
      exec env - \
        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
        PWD=/proc/self/cwd \
        PYTHON_BIN_PATH=/usr/bin/python \
      /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -g0 -O2 '-D_FORTIFY_SOURCE=1' -DNDEBUG -ffunction-sections -fdata-sections '-std=c++0x' -MD -MF bazel-out/k8-opt/bin/external/grpc/_objs/grpc_base_c/endpoint_pair_uv.d '-frandom-seed=bazel-out/k8-opt/bin/external/grpc/_objs/grpc_base_c/endpoint_pair_uv.o' '-DGRPC_ARES=0' -iquote external/grpc -iquote bazel-out/k8-opt/genfiles/external/grpc -iquote bazel-out/k8-opt/bin/external/grpc -iquote external/zlib_archive -iquote bazel-out/k8-opt/genfiles/external/zlib_archive -iquote bazel-out/k8-opt/bin/external/zlib_archive -isystem external/grpc/include -isystem bazel-out/k8-opt/genfiles/external/grpc/include -isystem bazel-out/k8-opt/bin/external/grpc/include -isystem external/zlib_archive -isystem bazel-out/k8-opt/genfiles/external/zlib_archive -isystem bazel-out/k8-opt/bin/external/zlib_archive -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 -mno-sse4a -mcx16 -msahf -mno-movbe -mno-aes -mno-sha -mno-pclmul -mno-popcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx -mno-avx2 -mno-sse4.2 -mno-sse4.1 -mno-lzcnt -mno-rtm -mno-hle -mno-rdrnd -mno-f16c -mno-fsgsbase -mno-rdseed -mno-prfchw -mno-adx -mfxsr -mno-xsave -mno-xsaveopt -mno-avx512f -mno-avx512er -mno-avx512cd -mno-avx512pf -mno-prefetchwt1 -mno-clflushopt -mno-xsavec -mno-xsaves -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512ifma -mno-avx512vbmi -mno-clwb -mno-mwaitx -mno-clzero '--param\40l1-cache-size=32' '--param\40l1-cache-line-size=64' '--param\40l2-cache-size=2048' '-mtune=core2' '-std=c++14' '-D_GLIBCXX_USE_CXX11_ABI=0' -fno-canonical-system-headers -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c external/grpc/src/core/lib/iomgr/endpoint_pair_uv.cc -o bazel-out/k8-opt/bin/external/grpc/_objs/grpc_base_c/endpoint_pair_uv.o)
    Execution platform: @bazel_tools//platforms:host_platform
    gcc: error: unrecognized command line option '--param\40l1-cache-size=32'
    gcc: error: unrecognized command line option '--param\40l1-cache-line-size=64'
    gcc: error: unrecognized command line option '--param\40l2-cache-size=2048'
    Target //tensorflow_serving/model_servers:tensorflow_model_server failed to build
    
    这似乎与以下几点有关

  • 我尝试了在没有包含空格的标志的情况下进行编译,这一结果强化了错误是由bazel错误处理的空格引起的假设 我怎样才能解决这个问题

    我想在一些旧机器(目标系统)上运行tensorflow服务,这些机器不支持标准tensorflow构建中使用的现代cpu指令。我使用这些说明通过docker安装tf服务。然而,我遇到了错误Tensorflow服务非法指令核心转储类似于github上的这个错误

    Bazel和TensorFlow在其构建标志中默认使用
    -march=native
    ,如果我回忆正确的话

    您应该省略该标志,或指定更合适的标志,如
    -march=sse4.2

    您的转储显示
    -mno-sse4.1
    。我相信这意味着你可以使用下面的方法来完成它

    -msse2 -msse3 -mssse3
    
    x86_64将SSE2作为核心指令集的一部分,因此它意味着MMX和SSE

    我认为您不应该使用
    -march=core2
    -mtune=core2
    ,因为core2意味着您拥有SSE4.1(早期的iCore CPU)或SSE4.2(后来的iCore CPU)

    从GCC手册页上看,我觉得这很可疑/错误:

    core2

    具有64位扩展、MMX、SSE、SSE2、SSE3和SSSE3指令集支持的Intel Core2 CPU

    我相当肯定Core2比SSSE3更有能力。我保留了几台Core2机器用于测试,它们有SSE4.1和SSE4.2。(我相信其中一个有CRC指令,即)

    我可能对GCC选项页的看法是错误的,但对我来说它看起来很可疑


    Tensorflow服务非法指令内核转储

    什么是非法指令


    gcc-####-E--march=native 2>&1|sed-r'/cc1/!Ds/(“”|(^.*-//g'

    这只是另一种观点,但我发现类似的东西更有用。从Skylake机器:


    $gcc-march=native-dM-E-感谢您的快速响应。我一回到家就会尝试其他编译标志。core2机器有一个
    Intel®Pentium®Prozessor SU4100
    ,代码名为
    Penryn-3M
    ,应该支持SSSE4.1(请参阅wiki)但是,快速运行建议的命令会显示与Core2机器相同的内容,除了行
    \define\u SSE4\u 1\u 1
    。关于缺少文件名的消息可能是bazel中的一个错误?因为
    --copt=--param x=y
    被错误解释,bazel认为
    x=y
    是编译的目标,而
    --copt=--param
    是唯一的选项。转义该选项无助于作为基线,您可以尝试
    -march=x86-64
    (注意虚线,而不是下划线)。这是一台仅限SSE2的机器。如果非法指令仍然出现,则可能是工具链中的错误。感谢您的帮助!我接受了您的回答,因为它非常有助于确定正确的标志。我可以交叉编译tensorflow服务于该标志<
    TF_SERVING_BUILD_OPTIONS="--copt=-mmmx ... --copt=--param\40l1-cache-size=32 --copt=--param\40l1-cache-line-size=64 --copt=--param\40l2-cache-size=2048 --copt=-mtune=core2 "
    
    ERROR: /root/.cache/bazel/_bazel_root/e53bbb0b0da4e26d24b415310219b953/external/grpc/BUILD:692:1: C++ compilation of rule '@grpc//:grpc_base_c' failed (Exit 1): gcc failed: error executing command 
      (cd /root/.cache/bazel/_bazel_root/e53bbb0b0da4e26d24b415310219b953/execroot/tf_serving && \
      exec env - \
        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
        PWD=/proc/self/cwd \
        PYTHON_BIN_PATH=/usr/bin/python \
      /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -g0 -O2 '-D_FORTIFY_SOURCE=1' -DNDEBUG -ffunction-sections -fdata-sections '-std=c++0x' -MD -MF bazel-out/k8-opt/bin/external/grpc/_objs/grpc_base_c/endpoint_pair_uv.d '-frandom-seed=bazel-out/k8-opt/bin/external/grpc/_objs/grpc_base_c/endpoint_pair_uv.o' '-DGRPC_ARES=0' -iquote external/grpc -iquote bazel-out/k8-opt/genfiles/external/grpc -iquote bazel-out/k8-opt/bin/external/grpc -iquote external/zlib_archive -iquote bazel-out/k8-opt/genfiles/external/zlib_archive -iquote bazel-out/k8-opt/bin/external/zlib_archive -isystem external/grpc/include -isystem bazel-out/k8-opt/genfiles/external/grpc/include -isystem bazel-out/k8-opt/bin/external/grpc/include -isystem external/zlib_archive -isystem bazel-out/k8-opt/genfiles/external/zlib_archive -isystem bazel-out/k8-opt/bin/external/zlib_archive -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 -mno-sse4a -mcx16 -msahf -mno-movbe -mno-aes -mno-sha -mno-pclmul -mno-popcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx -mno-avx2 -mno-sse4.2 -mno-sse4.1 -mno-lzcnt -mno-rtm -mno-hle -mno-rdrnd -mno-f16c -mno-fsgsbase -mno-rdseed -mno-prfchw -mno-adx -mfxsr -mno-xsave -mno-xsaveopt -mno-avx512f -mno-avx512er -mno-avx512cd -mno-avx512pf -mno-prefetchwt1 -mno-clflushopt -mno-xsavec -mno-xsaves -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512ifma -mno-avx512vbmi -mno-clwb -mno-mwaitx -mno-clzero '--param\40l1-cache-size=32' '--param\40l1-cache-line-size=64' '--param\40l2-cache-size=2048' '-mtune=core2' '-std=c++14' '-D_GLIBCXX_USE_CXX11_ABI=0' -fno-canonical-system-headers -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c external/grpc/src/core/lib/iomgr/endpoint_pair_uv.cc -o bazel-out/k8-opt/bin/external/grpc/_objs/grpc_base_c/endpoint_pair_uv.o)
    Execution platform: @bazel_tools//platforms:host_platform
    gcc: error: unrecognized command line option '--param\40l1-cache-size=32'
    gcc: error: unrecognized command line option '--param\40l1-cache-line-size=64'
    gcc: error: unrecognized command line option '--param\40l2-cache-size=2048'
    Target //tensorflow_serving/model_servers:tensorflow_model_server failed to build
    
    -march=core2 -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 -mno-sse4a -mcx16 -msahf
    -mno-movbe -mno-aes -mno-sha -mno-pclmul -mno-popcnt -mno-abm -mno-lwp -mno-fma
    -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx -mno-avx2 -mno-sse4.2
    -mno-sse4.1 -mno-lzcnt -mno-rtm -mno-hle -mno-rdrnd -mno-f16c -mno-fsgsbase
    -mno-rdseed -mno-prfchw -mno-adx -mfxsr -mno-xsave -mno-xsaveopt -mno-avx512f
    -mno-avx512er -mno-avx512cd -mno-avx512pf -mno-prefetchwt1 -mno-clflushopt -mno-xsavec
    -mno-xsaves -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512ifma -mno-avx512vbmi
    -mno-clwb -mno-mwaitx -mno-clzero -mno-pku --param l1-cache-size=32
    --param l1-cache-line-size=64 --param l2-cache-size=2048 -mtune=core2
    
    -msse2 -msse3 -mssse3
    
    ERROR: Skipping 'l1-cache-line-size=64': couldn't determine target from filename 'l1-cache-line-size=64'
    ERROR: couldn't determine target from filename 'l1-cache-line-size=64'