Skip to content

Commit 56270c3

Browse files
author
mabsar
committed
[hexagon-mlir] Fixes for v73,v79 compilation.
Some changes necessary to get hexagon-mlir compile and run tests on different cpu targets. Signed-off-by: mabsar <mabsar@qti.qualcommm.com>
1 parent 7a39f69 commit 56270c3

9 files changed

Lines changed: 118 additions & 25 deletions

File tree

qcom_hexagon_backend/backend/hexagon_executor.py

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,26 @@
2222
)
2323
from triton.backends.qcom_hexagon_backend.hexagon_profiler import HexagonProfiler
2424

25+
26+
def _sdk_tool_version(q6_version: str) -> str:
27+
"""Return the SDK prebuilt tool version for the given Hexagon arch version.
28+
29+
v79+ devices require toolv88; older devices use toolv87.
30+
"""
31+
return "v88" if int(q6_version.lstrip("v")) >= 79 else "v87"
32+
33+
34+
def _qhmath_sdk_path(q6_version: str) -> tuple:
35+
"""Tool/arch version for qhmath_hvx prebuilt libs.
36+
37+
v79 qhmath_hvx in SDK <= 6.4.0.0 is missing fp16 _ahf symbols;
38+
fall back to v75 toolv87 libs until HSDK 6.6.0.
39+
"""
40+
if int(q6_version.lstrip("v")) >= 79:
41+
return ("v87", "75")
42+
return (_sdk_tool_version(q6_version), q6_version)
43+
44+
2545
# This file is part of a small subset of python files that uses some type-annotations
2646
# and it passes type-verification with mypy (a type checker).
2747
# To typecheck this set of files, do:
@@ -31,7 +51,7 @@
3151
class HexagonExecutor:
3252
def __init__(
3353
self,
34-
kernel_run_id,
54+
kernel_run_id: str,
3555
enable_lwp=False,
3656
enable_etm=False,
3757
compile_only=False,
@@ -50,6 +70,11 @@ def __init__(
5070
environment variables, tools paths, and Q6 version, set by
5171
calling the `get_config` method.
5272
"""
73+
if not compile_only:
74+
if (not isinstance(kernel_run_id, str)) or (len(kernel_run_id) == 0):
75+
raise ValueError(
76+
"kernel_run_id must be well-formed, non-empty string for execution via standalone launcher"
77+
)
5378
self.exec_mode = get_exec_mode() if not compile_only else "compile_only"
5479
self.device_path = f"/data/local/tmp/{kernel_run_id}"
5580
self.lib_path = f"{self.device_path}/lib"
@@ -229,9 +254,11 @@ def generate_shared_object(
229254
HEXAGON_SDK_ROOT=self.config.env_vars["HEXAGON_SDK_ROOT"],
230255
Q6_VERSION=self.config.Q6_VERSION,
231256
)
232-
QHL_LINK_DIR = """{HEXAGON_SDK_ROOT}/libs/qhl_hvx/prebuilt/hexagon_toolv87_v{Q6_VERSION}""".format(
257+
qhmath_tool_ver, qhmath_arch_ver = _qhmath_sdk_path(self.config.Q6_VERSION)
258+
QHL_LINK_DIR = "{HEXAGON_SDK_ROOT}/libs/qhl_hvx/prebuilt/hexagon_tool{TOOL_VERSION}_v{Q6_VERSION}".format(
233259
HEXAGON_SDK_ROOT=self.config.env_vars["HEXAGON_SDK_ROOT"],
234-
Q6_VERSION=self.config.Q6_VERSION,
260+
TOOL_VERSION=qhmath_tool_ver,
261+
Q6_VERSION=qhmath_arch_ver,
235262
)
236263

237264
if not (
@@ -248,9 +275,10 @@ def generate_shared_object(
248275
QHL_LINK_DIR,
249276
)
250277

251-
QHMATH_DIR = """{HEXAGON_SDK_ROOT}/libs/qhl/prebuilt/hexagon_toolv87_v{Q6_VERSION}""".format(
278+
QHMATH_DIR = "{HEXAGON_SDK_ROOT}/libs/qhl/prebuilt/hexagon_tool{TOOL_VERSION}_v{Q6_VERSION}".format(
252279
HEXAGON_SDK_ROOT=self.config.env_vars["HEXAGON_SDK_ROOT"],
253-
Q6_VERSION=self.config.Q6_VERSION,
280+
TOOL_VERSION=qhmath_tool_ver,
281+
Q6_VERSION=qhmath_arch_ver,
254282
)
255283
if os.path.exists(QHMATH_DIR) and os.path.exists(
256284
os.path.join(QHMATH_DIR, "libqhmath.a")
@@ -366,11 +394,10 @@ def run_kernel_on_device(
366394
)
367395
librun_main_on_hexagon_skel_path = os.path.join(
368396
self.config.env_vars["HEXAGON_SDK_ROOT"],
369-
"libs/run_main_on_hexagon/ship/hexagon_toolv87_v{}/librun_main_on_hexagon_skel.so".format(
370-
self.config.Q6_VERSION
397+
"libs/run_main_on_hexagon/ship/hexagon_tool{}_v{}/librun_main_on_hexagon_skel.so".format(
398+
_sdk_tool_version(self.config.Q6_VERSION), self.config.Q6_VERSION
371399
),
372400
)
373-
374401
libcpp_path = os.path.join(
375402
self.config.env_vars["HEXAGON_TOOLS"],
376403
"target/hexagon/lib/v{}/G0/pic/libc++.so.1".format(self.config.Q6_VERSION),
@@ -602,13 +629,11 @@ def run_kernel_on_device(
602629

603630
try:
604631
if self.enable_etm:
605-
if "mlir_ciface" in principal_lib_without_ext:
606-
kernel_name = "" # torch-mlir flow -> not just one kernel
607-
else:
608-
kernel_name = principal_lib_without_ext[3:] # remove lib prefix
609-
610632
hex_prof = HexagonProfiler(
611-
etm_local_dir, profiling_mode="etm", kernel_name=kernel_name
633+
etm_local_dir,
634+
profiling_mode="etm",
635+
device_lib_path=path_to_principal_lib_on_device,
636+
local_lib_filename=f"{principal_lib_without_ext}.so",
612637
)
613638
for command, should_run in commands:
614639
if not should_run:
@@ -724,16 +749,18 @@ def run_kernel_on_simulator(self, paths_to_shared_libs_local: list[str]):
724749
self.config.env_vars["HEXAGON_TOOLS"], SIM_Q6SS_PATH
725750
)
726751
),
727-
("{} -mv{} \
752+
(
753+
"{} -mv{} \
728754
--usefs={}/../Tools/target/hexagon/lib/v{}/G0/pic \
729755
--simulated_returnval \
730756
--cosim_file {} \
731757
--l2tcm_base 0xd800 \
732758
--rtos {} \
733759
{}/rtos/qurt/computev{}/sdksim_bin/runelf.pbn -- \
734-
{}/libs/run_main_on_hexagon/ship/hexagon_toolv87_v{}/run_main_on_hexagon_sim \
760+
{}/libs/run_main_on_hexagon/ship/hexagon_tool{}_v{}/run_main_on_hexagon_sim \
735761
stack_size=0x400000 -- \
736-
{}").format(
762+
{}"
763+
).format(
737764
self.config.HEX_TOOLS["hexagon-sim"],
738765
self.config.Q6_VERSION,
739766
self.config.env_vars["HEXAGON_TOOLS"],
@@ -743,6 +770,7 @@ def run_kernel_on_simulator(self, paths_to_shared_libs_local: list[str]):
743770
self.config.env_vars["HEXAGON_SDK_ROOT"],
744771
self.config.Q6_VERSION,
745772
self.config.env_vars["HEXAGON_SDK_ROOT"],
773+
_sdk_tool_version(self.config.Q6_VERSION),
746774
self.config.Q6_VERSION,
747775
path_to_principal_lib_local,
748776
),

qcom_hexagon_backend/backend/hexagon_options.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ class HexagonOptions:
1818
allow_fp8e4nv: bool = False
1919
allowed_dot_input_precisions: Tuple[str] = ("ieee",)
2020
arch_triple: str = "hexagon"
21-
arch_features: str = f'+hvxv{os.getenv("HEXAGON_ARCH_VERSION")},+hvx-length128b'
21+
arch_features: str = (
22+
f'+hvxv{os.getenv("HEXAGON_ARCH_VERSION")},+hvx-length128b'
23+
+ (",+hvx-ieee-fp" if int(os.getenv("HEXAGON_ARCH_VERSION", "0")) >= 79 else "")
24+
)
2225
device_type: str = "hexagon"
2326
vectorize: int = 1
2427
vector_length: int = 32

qcom_hexagon_backend/backend/hexagon_profiler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def write_config_lanai(self, addresses):
214214
"0x0",
215215
"0x0",
216216
],
217-
"ver": "v75",
217+
"ver": "v79",
218218
"target": "Hexagon",
219219
}
220220

qcom_hexagon_backend/bin/runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ set(HEXAGON_INCLUDES
4949
-I${HEXAGON_SDK_ROOT}/incs
5050
-I${HEXAGON_SDK_ROOT}/incs/stddef
5151
-I${HEXAGON_SDK_ROOT}/libs/qhl_hvx/inc
52+
-I${HEXAGON_SDK_ROOT}/libs/qhl_hvx/inc/internal
5253
-I${HEXKL_ROOT}/include
5354
-I${HEXAGON_SDK_ROOT}/rtos/qurt/computev${Q6_VERSION}/include/posix
5455
-I${HEXAGON_SDK_ROOT}/rtos/qurt/computev${Q6_VERSION}/include/qurt

qcom_hexagon_backend/bin/runtime/test/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,19 @@ set(DEVICE_PATH "/vendor/bin/${BENCHMARK}")
5353
set(Q6_VERSION "$ENV{HEXAGON_ARCH_VERSION}")
5454
set(DSP_STACK_SIZE "262144")
5555

56+
# v79+ devices require toolv88; older devices use toolv87.
57+
if(Q6_VERSION GREATER_EQUAL 79)
58+
set(HEXAGON_TOOL_VERSION "v88")
59+
else()
60+
set(HEXAGON_TOOL_VERSION "v87")
61+
endif()
62+
5663
# Generate the run_test.sh script to run the test
5764
# TODO: Add option to pass gtest args in commandline
5865
set(SHELL_SCRIPT_CONTENT "#!/bin/bash"
5966
"set -x"
6067
"adb -H \$ANDROID_HOST -s \$ANDROID_SERIAL push ${HEXAGON_SDK_ROOT}/libs/run_main_on_hexagon/ship/android_aarch64/run_main_on_hexagon ${DEVICE_PATH}/run_main_on_hexagon"
61-
"adb -H \$ANDROID_HOST -s \$ANDROID_SERIAL push ${HEXAGON_SDK_ROOT}/libs/run_main_on_hexagon/ship/hexagon_toolv87_v${Q6_VERSION}/librun_main_on_hexagon_skel.so /vendor/lib/rfsa/adsp/"
68+
"adb -H \$ANDROID_HOST -s \$ANDROID_SERIAL push ${HEXAGON_SDK_ROOT}/libs/run_main_on_hexagon/ship/hexagon_tool${HEXAGON_TOOL_VERSION}_v${Q6_VERSION}/librun_main_on_hexagon_skel.so /vendor/lib/rfsa/adsp/"
6269
"adb -H \$ANDROID_HOST -s \$ANDROID_SERIAL push ${TEST_PATH}/${BENCHMARK}.so ${DEVICE_PATH}"
6370
"adb -H \$ANDROID_HOST -s \$ANDROID_SERIAL shell 'cd ${DEVICE_PATH}\; touch /vendor/lib/rfsa/adsp/run_main_on_hexagon.farf\; ./run_main_on_hexagon 3 ${DEVICE_PATH}/${BENCHMARK}.so --gtest-args=\"\" stack_size=262144'"
6471
"adb -H \$ANDROID_HOST -s \$ANDROID_SERIAL pull ${DEVICE_PATH}/gtest_output.txt ."

qcom_hexagon_backend/lib/Target/HEX_LLVMIR/LLVMIRTranslation.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,25 @@ std::unique_ptr<llvm::Module> translateHexagonMlirLlvmToLLVMIR(
273273
return llvmIR;
274274
}
275275

276+
// Derive the Hexagon CPU name from arch_features string.
277+
// e.g., "+hvxv79,+hvx-length128b" -> "hexagonv79"
278+
static std::string deriveCpuFromFeatures(const std::string &features) {
279+
auto pos = features.find("+hvxv");
280+
if (pos != std::string::npos) {
281+
pos += 5; // skip "+hvxv"
282+
size_t end = pos;
283+
while (end < features.size() && std::isdigit((unsigned char)features[end]))
284+
end++;
285+
if (end > pos)
286+
return "hexagonv" + features.substr(pos, end - pos);
287+
}
288+
return "";
289+
}
290+
276291
static std::unique_ptr<llvm::TargetMachine>
277-
create_target_machine(const llvm::Triple &target_triple) {
292+
create_target_machine(const llvm::Triple &target_triple,
293+
const std::string &cpu = "",
294+
const std::string &features = "") {
278295

279296
// Hexagon target instance is needed to give a broader description of the
280297
// target platform
@@ -296,7 +313,7 @@ create_target_machine(const llvm::Triple &target_triple) {
296313
llvm::CodeGenOptLevel::Aggressive;
297314

298315
llvm::TargetMachine *targetMachine = target_instance->createTargetMachine(
299-
target_triple, "", "", target_options, reloc_model, code_model,
316+
target_triple, cpu, features, target_options, reloc_model, code_model,
300317
codegen_optlevel);
301318

302319
if (!targetMachine)
@@ -373,8 +390,23 @@ llvm_module_to_obj_string(std::unique_ptr<llvm::Module> &llvmModule) {
373390
initializeHexagonTarget();
374391

375392
auto target_triple = llvmModule->getTargetTriple();
393+
394+
// Extract target features from function attributes so the TargetMachine
395+
// is configured with the correct CPU (e.g. hexagonv79) and features
396+
// (e.g. +hvx-ieee-fp). Without this, the base TargetMachine defaults to
397+
// a generic Hexagon CPU and the LLVM backend rejects v79-specific
398+
// instructions even when they appear in the LLVM IR.
399+
std::string features;
400+
for (const auto &f : *llvmModule) {
401+
if (!f.isDeclaration() && f.hasFnAttribute("target-features")) {
402+
features = f.getFnAttribute("target-features").getValueAsString().str();
403+
break;
404+
}
405+
}
406+
std::string cpu = deriveCpuFromFeatures(features);
407+
376408
std::unique_ptr<llvm::TargetMachine> targetMachine =
377-
create_target_machine(target_triple);
409+
create_target_machine(target_triple, cpu, features);
378410

379411
// Set options for debugging
380412
setupCodegenDumpOptions();

scripts/build_hexagon_mlir.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@ export PATH="${HOST_TOOLCHAIN}/bin:${PATH}"
5151
export CC="${HOST_TOOLCHAIN}/bin/clang"
5252
export CXX="${HOST_TOOLCHAIN}/bin/clang++"
5353

54+
# Get libstdc++ from GCC 12 (Ubuntu 22.04) to satisfy GLIBCXX_3.4.30 requirement
55+
cd ${BASE_DIR}
56+
echo "Fetching libstdc++ (GCC 12)..."
57+
mkdir -p LIBSTDCXX
58+
cd LIBSTDCXX
59+
60+
if [[ ! -f libstdc++.so.6 ]]; then
61+
wget http://security.ubuntu.com/ubuntu/pool/main/g/gcc-12/libstdc++6_12.3.0-1ubuntu1~22.04.3_amd64.deb
62+
ar x libstdc++6_12.3.0-1ubuntu1~22.04.3_amd64.deb
63+
tar --use-compress-program=unzstd -xf data.tar.zst --strip-components=4 ./usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30
64+
ln -sf libstdc++.so.6.0.30 libstdc++.so.6
65+
else
66+
echo "libstdc++ already present. Skipping."
67+
fi
68+
export LD_PRELOAD="${BASE_DIR}/LIBSTDCXX/libstdc++.so.6:${LD_PRELOAD:-}"
69+
5470
# Get HEXAGON_SDK
5571
cd ${BASE_DIR}
5672
echo "extracting HEXAGON_SDK..."

scripts/build_triton.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ PYTHON_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.v
2828
# Triton shared path
2929
export TRITON_SHARED_OPT_PATH=$TRITON_ROOT/build/cmake.linux-x86_64-cpython-${PYTHON_VERSION}/third_party/triton_shared/tools/triton-shared-opt/triton-shared-opt
3030

31-
export HEXAGON_ARCH_VERSION=75
31+
export HEXAGON_ARCH_VERSION=79
3232
export TRITON_HOME=$HEXAGON_MLIR_ROOT
3333
export TRITON_PLUGIN_DIRS="$HEXAGON_MLIR_ROOT/triton_shared;$HEXAGON_MLIR_ROOT/qcom_hexagon_backend"
3434
export PATH=$TRITON_ROOT/build/cmake.linux-x86_64-cpython-${PYTHON_VERSION}/third_party/qcom_hexagon_backend/bin/:$TRITON_ROOT/build/cmake.linux-x86_64-cpython-${PYTHON_VERSION}/third_party/triton_shared/tools/triton-shared-opt:$PATH
@@ -39,6 +39,7 @@ TRITON_BUILD_WITH_CCACHE=true \
3939
LLVM_INCLUDE_DIRS="$LLVM_PROJECT_BUILD_DIR/include" \
4040
LLVM_LIBRARY_DIR="$LLVM_PROJECT_BUILD_DIR/lib" \
4141
LLVM_SYSPATH="$LLVM_PROJECT_BUILD_DIR" \
42+
TRITON_APPEND_CMAKE_ARGS="-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON" \
4243
pip install -e . --no-build-isolation --verbose
4344

4445
echo "🎉 Triton build completed successfully."

scripts/set_local_env.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ export HEXAGON_SDK_VERSION=6.4.0.2
2525
export HEXAGON_SDK_ROOT=${BASE_DIR}/HEXAGON_SDK/Hexagon_SDK/$HEXAGON_SDK_VERSION
2626
export HEXKL_ROOT=${BASE_DIR}/HEXKL_DIR/hexkl_addon
2727

28-
export HEXAGON_ARCH_VERSION=75
28+
export HEXAGON_ARCH_VERSION=79
2929
export TRITON_HOME=$HEXAGON_MLIR_ROOT
3030
export TRITON_PLUGIN_DIRS="$HEXAGON_MLIR_ROOT/triton_shared;$HEXAGON_MLIR_ROOT/qcom_hexagon_backend"
3131
export PATH=$TRITON_ROOT/build/cmake.linux-x86_64-cpython-${PYTHON_VERSION}/third_party/qcom_hexagon_backend/bin/:$TRITON_ROOT/build/cmake.linux-x86_64-cpython-${PYTHON_VERSION}/third_party/triton_shared/tools/triton-shared-opt:$PATH
3232
export PYTHONPATH=$TRITON_ROOT/python:${PYTHONPATH:-}
3333

34+
# Use locally downloaded libstdc++ (GCC 12) to satisfy GLIBCXX_3.4.30 requirement.
35+
# LD_PRELOAD is used instead of LD_LIBRARY_PATH because libtriton.so has an RPATH
36+
# pointing to miniconda's lib which would otherwise take precedence.
37+
export LD_PRELOAD="${BASE_DIR}/LIBSTDCXX/libstdc++.so.6:${LD_PRELOAD:-}"
38+
3439
set +euxo pipefail

0 commit comments

Comments
 (0)