首先感谢大家的帮忙!不幸的是,到目前为止还没有找到解决办法。我正在更新描述以使问题更容易重现。
第 1 节:最小案例
首先发现
cmake
的问题,但可能不仅限于此,通过将以下最小可重现示例中的 cmake
更改为 make
或其他内容也可以重现问题。
#!/bin/bash
set -x
run() {
arg=$1
printf '%q\n' "$arg"
cmake "$arg" 1>/dev/null 2>&1
}
TEXT="local -DCMAKE_ARG=\"arg1;arg2\""
CMAKE_OPTS1=$(echo "$TEXT" | awk '/local/ {for (i=1; i<=NF; i++) {if ($i ~ /^-D/) {printf "%s ", $i}}}' | tr -d '";')
CMAKE_OPTS2=$(echo "$TEXT" | awk '/local/ {for (i=1; i<=NF; i++) {if ($i ~ /^-D/) {printf "%s ", $i}}}' )
CMAKE_OPTS3=("$(echo "$TEXT" | awk '/local/ {for (i=1; i<=NF; i++) {if ($i ~ /^-D/) {printf "%s ", $i}}}' )")
run $CMAKE_OPTS1
run $CMAKE_OPTS2
run "${CMAKE_OPTS3[@]}"
打印出来的结果是(减少到兴趣线)
-DCMAKE_ARG=arg1arg2
+ cmake -DCMAKE_ARG=arg1arg2
-DCMAKE_ARG=\"arg1\;arg2\"
+ cmake '-DCMAKE_ARG="arg1;arg2"'
-DCMAKE_ARG=\"arg1\;arg2\"\
+ cmake '-DCMAKE_ARG="arg1;arg2" '
不幸的是,
cmake '-DCMAKE_ARG="arg1;arg2"'
无法正常工作。
第二部分:原剧本
当然有很多修改以最小化脚本。因此,它涉及从 docker 和 GitHub 存储库中提取,都是公开的和开源的。
首先,从 Docker Hub 中拉取 docker(以确保必要的 clang env):
docker pull rocm/miopen:ci
然后在docker中,使用以下脚本:
#!/bin/bash
set -x
build_miopen_ck() {
echo "Building Composable Kernel"
ck_commit=$1
ck_cmake_opts=$2
if [ -z "$ck_commit" ]; then
echo "Composable Kernel entry was not found in requirements.txt"
return
fi
mkdir -p /tmp/composable_kernel && cd /tmp/composable_kernel || exit
wget -nv "https://www.github.com/ROCmSoftwarePlatform/composable_kernel/archive/${ck_commit}.tar.gz"
tar -xzf "${ck_commit}.tar.gz"
cd "composable_kernel-${ck_commit}" || exit
rm -rf build
mkdir -p build && cd build || exit
cmake -DBUILD_DEV=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_COMPILER="/opt/rocm/llvm/bin/clang++" \
-DCMAKE_C_COMPILER="/opt/rocm/llvm/bin/clang" \
-DCMAKE_PREFIX_PATH="$ROCM_PATH" \
"${ck_cmake_opts}" \
..
make -j"$(nproc)" install
echo "Finished building Composable Kernel"
}
TEXT="ROCmSoftwarePlatform/composable_kernel@5f28614222bd590bc31d98838bc019e9c3a7ad45 -DGPU_TARGETS=\"gfx900;gfx906;gfx908;gfx90a;gfx1030;gfx1100;gfx1101;gfx1102\""
CK_COMMIT=$(echo "$TEXT" | awk '/composable_kernel/ {split($1, s, "@"); print s[2]}')
CK_CMAKE_OPTS=$(echo "$TEXT" | awk '/composable_kernel/ {for (i=1; i<=NF; i++) {if ($i ~ /^-D/) {printf "%s ", $i}}}')
build_miopen_ck "$CK_COMMIT" "$CK_CMAKE_OPTS"
很快(可能是一段时间)构建将失败并出现以下错误:
clang-15: error: invalid target ID 'gfx900 --offload-arch=gfx906 --offload-arch=gfx908 --offload-arch=gfx90a --offload-arch=gfx1030 --offload-arch=gfx1100 --offload-arch=gfx1101 --offload-arch=gfx1102'; format is a processor name followed by an optional colon-delimited list of features followed by an enable/disable sign (e.g., 'gfx908:sramecc+:xnack-')
通过诊断日志,单引号看起来很可疑:
cmake -DBUILD_DEV=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=/opt/rocm/llvm/bin/clang++ -DCMAKE_C_COMPILER=/opt/rocm/llvm/bin/clang -DCMAKE_PREFIX_PATH= '-DGPU_TARGETS="gfx900;gfx906;gfx908;gfx90a;gfx1030;gfx1100;gfx1101;gfx1102" ' ..
如果我转到目录,然后重新运行 cmake
cmake -DBUILD_DEV=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=/opt/rocm/llvm/bin/clang++ -DCMAKE_C_COMPILER=/opt/rocm/llvm/bin/clang -DCMAKE_PREFIX_PATH= -DGPU_TARGETS="gfx900;gfx906;gfx908;gfx90a;gfx1030;gfx1100;gfx1101;gfx1102" ..
然后一切都按预期进行。
从上面的错误来看,应该和shell参数扩展有关:
'--offload-arch=gfx900' '--offload-arch=gfx906' ...
but instead, the single quotes are messing up the **secondary** parsing process, and it reads as if it is:
'--offload-arch=gfx900 --offload-arch=gfx906 ...'
与上面的最小示例相关,如果将包含特殊字符的变量作为参数传递给命令不会自动添加一对单引号,我们不应该有这个二次解析问题吗?
到目前为止的一些实验:
set -x
并不能解决此问题 :(解决方法:
到目前为止,一个 working 解决方法是在 -DGPU_TARGETS=
之后 grep 字符串,即代替
cmake "$arg"
我们可以进行以下工作 cmake -DGPU_TARGETS="${subset_arg}"
。但是,这是一种解决方法,原来的问题仍然存在。
您可能需要加倍反斜杠:
#!/bin/bash
set -x
run() {
arg="$1"
printf '%q\n' "$arg"
cmake "$arg" 1>/dev/null 2>&1
}
TEXT="local -DCMAKE_ARG=arg1;arg2"
CMAKE_OPTS="${TEXT#local }" # Remove [local ]
CMAKE_OPTS="${CMAKE_OPTS//;/\\\\;}" # Add \ doubled
run "$CMAKE_OPTS"
# If four backslashes (\\\\) don't work, try two (\\)