Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

cmake_minimum_required(VERSION 3.20)
project(tensorrt_model_connect VERSION 0.1.0 LANGUAGES CXX CUDA)
if(CMAKE_CROSSCOMPILING)
message(FATAL_ERROR "TensorRT Model Connect does not support cross compilation")
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -39,6 +42,8 @@ find_library(TRTMC_TRT_LIBRARY
REQUIRED
)

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/EdgeLLM.cmake")

option(TRTMC_ENABLE_BYOK "Enable the optional TVM-FFI BYOK bridge" ON)
set(TRTMC_HAS_TVM_FFI OFF)
if(TRTMC_ENABLE_BYOK)
Expand Down Expand Up @@ -245,6 +250,9 @@ option(TRTMC_BUILD_TESTS "Build tests" ON)
option(TRTMC_BUILD_EXAMPLES "Build examples" ON)
if(TRTMC_BUILD_TESTS)
enable_testing()
add_test(NAME test_edgellm_package_contract
COMMAND "${CMAKE_COMMAND}" "-DTEST_ROOT=${PROJECT_BINARY_DIR}/edgellm-package-contract"
-P "${PROJECT_SOURCE_DIR}/cmake/edgellm/tests/package_contract.cmake")
endif()

# A family owns its target, sources, dependencies, warnings, and installation.
Expand Down
94 changes: 94 additions & 0 deletions cmake/EdgeLLM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Optional native dependency provisioning. Model builds never acquire dependencies.
option(TRTMC_ENABLE_EDGELLM "Install the pinned native Edge-LLM SDK and builder" OFF)
if(NOT TRTMC_ENABLE_EDGELLM)
return()
endif()
if(CMAKE_CROSSCOMPILING)
message(FATAL_ERROR "Edge-LLM cross compilation is not supported")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/edgellm/CheckNative.cmake")
set(_edge_version "0.10.1")
set(_edge_revision "e8b29522938901f6df19ebeedd4b69bc8edbcd97")
set(_edge_root "${CMAKE_BINARY_DIR}/_deps/edgellm")
set(_edge_prefix "${_edge_root}/install")
find_package(EdgeLLM ${_edge_version} EXACT CONFIG QUIET)
if(EdgeLLM_FOUND AND NOT EdgeLLM_PREFIX STREQUAL _edge_prefix)
if(NOT EdgeLLM_REVISION STREQUAL _edge_revision)
message(FATAL_ERROR "EdgeLLM package does not match the pinned GitHub revision")
endif()
install(FILES "$<TARGET_FILE:EdgeLLM::Plugin>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT EdgeLLM)
return()
endif()

include(ExternalProject)
include(CMakePackageConfigHelpers)
find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter)
find_package(Threads REQUIRED)
set(TRTMC_EDGELLM_TRT_ROOT "$ENV{TRT_ROOT}" CACHE PATH "Native TensorRT SDK, including its Python wheel")
set(TRTMC_EDGELLM_CUDA_ARCHITECTURE "${CMAKE_CUDA_ARCHITECTURES}" CACHE STRING "One local GPU architecture for Edge-LLM")
set(TRTMC_EDGELLM_JOBS 2 CACHE STRING "Parallel Edge-LLM native and AOT compilation jobs")
set(TRTMC_EDGELLM_WHEELHOUSE "" CACHE PATH "Optional complete offline Python wheelhouse")
set(TRTMC_EDGELLM_GIT_MIRROR "" CACHE PATH "Optional local mirror of the pinned upstream Git repository")
if(NOT TRTMC_EDGELLM_CUDA_ARCHITECTURE MATCHES "^[0-9]+$")
message(FATAL_ERROR "Set TRTMC_EDGELLM_CUDA_ARCHITECTURE to one local GPU architecture, e.g. 80")
endif()
if(NOT EXISTS "${TRTMC_EDGELLM_TRT_ROOT}/include/NvInfer.h")
message(FATAL_ERROR "TRTMC_EDGELLM_TRT_ROOT must contain the native TensorRT SDK")
endif()
_edgellm_check_gpu("${TRTMC_EDGELLM_CUDA_ARCHITECTURE}")
_edgellm_trt_version("${TRTMC_EDGELLM_TRT_ROOT}/include" _edge_trt_version)
set(_edge_source "${_edge_root}/source")
set(_edge_build "${_edge_root}/build")
set(_edge_python "${_edge_prefix}/libexec/trtmc-edge-llm/bin/python")
set(_edge_repository "https://github.com/NVIDIA/TensorRT-Edge-LLM.git")
if(TRTMC_EDGELLM_GIT_MIRROR)
set(_edge_repository "${TRTMC_EDGELLM_GIT_MIRROR}")
endif()
set(_edge_template_dir "${CMAKE_CURRENT_LIST_DIR}/edgellm")
file(MAKE_DIRECTORY "${_edge_prefix}/lib/cmake/EdgeLLM" "${_edge_prefix}/include/edgellm/cpp"
"${_edge_prefix}/include/edgellm/3rdParty/nlohmannJson/include"
"${_edge_prefix}/include/edgellm/3rdParty/stb" "${_edge_prefix}/include/edgellm/3rdParty/miniaudio")
configure_file("${_edge_template_dir}/CheckNative.cmake" "${_edge_prefix}/lib/cmake/EdgeLLM/CheckNative.cmake" COPYONLY)
foreach(_script IN ITEMS Prepare Install)
configure_file("${_edge_template_dir}/${_script}.cmake.in" "${_edge_root}/${_script}.cmake" @ONLY)
endforeach()
configure_file("${_edge_template_dir}/EdgeLLMConfig.cmake.in"
"${_edge_prefix}/lib/cmake/EdgeLLM/EdgeLLMConfig.cmake" @ONLY)
write_basic_package_version_file("${_edge_prefix}/lib/cmake/EdgeLLM/EdgeLLMConfigVersion.cmake"
VERSION "${_edge_version}" COMPATIBILITY ExactVersion)
ExternalProject_Add(trtmc_edgellm_dependency
PREFIX "${_edge_root}/ep" SOURCE_DIR "${_edge_source}" BINARY_DIR "${_edge_build}"
GIT_REPOSITORY "${_edge_repository}" GIT_TAG "${_edge_revision}"
GIT_SUBMODULES_RECURSE TRUE UPDATE_DISCONNECTED TRUE
LIST_SEPARATOR |
CMAKE_COMMAND "${_edge_prefix}/libexec/trtmc-edge-llm/bin/cmake"
PATCH_COMMAND "${CMAKE_COMMAND}" -P "${_edge_root}/Prepare.cmake"
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON
"-DCMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}"
"-DCMAKE_CUDA_ARCHITECTURES=${TRTMC_EDGELLM_CUDA_ARCHITECTURE}"
"-DCUDA_DIR=${CUDAToolkit_LIBRARY_ROOT}" "-DCUDAToolkit_ROOT=${CUDAToolkit_LIBRARY_ROOT}"
"-DCUDA_CTK_VERSION=${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}"
"-DTRT_PACKAGE_DIR=${TRTMC_EDGELLM_TRT_ROOT}" "-DPython3_EXECUTABLE=${_edge_python}"
-DEDGELLM_WHEEL_PAYLOAD_DIR=unused -DENABLE_CUTE_DSL=fmha|gdn
"-DCUTE_DSL_ARTIFACT_TAG=sm_${TRTMC_EDGELLM_CUDA_ARCHITECTURE}"
BUILD_COMMAND "${CMAKE_COMMAND}" --build <BINARY_DIR> --target edgellmCore NvInfer_edgellm_plugin
--parallel "${TRTMC_EDGELLM_JOBS}"
INSTALL_COMMAND "${CMAKE_COMMAND}" -P "${_edge_root}/Install.cmake"
BUILD_BYPRODUCTS "${_edge_prefix}/lib/libedgellmCore.a"
"${_edge_prefix}/lib/libNvInfer_edgellm_plugin.so"
"${_edge_prefix}/lib/libcutedsl.a"
LOG_DOWNLOAD ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_OUTPUT_ON_FAILURE ON)
ExternalProject_Add_StepDependencies(trtmc_edgellm_dependency patch "${_edge_root}/Prepare.cmake")
ExternalProject_Add_StepDependencies(trtmc_edgellm_dependency install "${_edge_root}/Install.cmake")
# Generated package targets refer to declared future byproducts; their build dependency
# prevents consumers from compiling or linking until installation completes.
find_package(EdgeLLM ${_edge_version} EXACT CONFIG REQUIRED
PATHS "${_edge_prefix}/lib/cmake/EdgeLLM" NO_DEFAULT_PATH)
add_dependencies(EdgeLLM::Core trtmc_edgellm_dependency)
add_dependencies(EdgeLLM::Plugin trtmc_edgellm_dependency)
install(DIRECTORY "${_edge_prefix}/" DESTINATION . USE_SOURCE_PERMISSIONS COMPONENT EdgeLLM)
# Family DSOs may use lib64; their dynamically loaded plugin must remain adjacent.
install(FILES "$<TARGET_FILE:EdgeLLM::Plugin>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT EdgeLLM)
34 changes: 34 additions & 0 deletions cmake/edgellm/CheckNative.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Read the complete TensorRT SDK version using the compiler, including aliased macros.
# include_dir: native SDK include directory; output: caller variable receiving x.y.z.build.
function(_edgellm_trt_version include_dir output)
set(_version)
set(_probe "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/edgellm-version.cpp")
file(WRITE "${_probe}" "#include <NvInferVersion.h>\n")
foreach(_part IN ITEMS MAJOR MINOR PATCH BUILD)
file(APPEND "${_probe}" "TRTMC_EDGE_${_part}=NV_TENSORRT_${_part}\n")
endforeach()
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" -E -P -I "${include_dir}" "${_probe}"
OUTPUT_VARIABLE _expanded COMMAND_ERROR_IS_FATAL ANY)
foreach(_part IN ITEMS MAJOR MINOR PATCH BUILD)
if(NOT _expanded MATCHES "TRTMC_EDGE_${_part}=[ \t]*([0-9]+)")
message(FATAL_ERROR "Cannot determine TensorRT ${_part} from ${include_dir}")
endif()
list(APPEND _version "${CMAKE_MATCH_1}")
endforeach()
list(JOIN _version "." _version)
set(${output} "${_version}" PARENT_SCOPE)
endfunction()

# Require the installed package GPU architecture to be present on this build host.
function(_edgellm_check_gpu architecture)
execute_process(COMMAND nvidia-smi --query-gpu=compute_cap --format=csv,noheader
OUTPUT_VARIABLE _sms RESULT_VARIABLE _result OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE "." "" _sms "${_sms}")
string(REPLACE "\n" ";" _sms "${_sms}")
if(NOT _result EQUAL 0 OR NOT architecture IN_LIST _sms)
message(FATAL_ERROR "EdgeLLM requires a local GPU with architecture ${architecture}")
endif()
endfunction()
40 changes: 40 additions & 0 deletions cmake/edgellm/EdgeLLMConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
include(CMakeFindDependencyMacro)
find_dependency(CUDAToolkit)
find_dependency(Threads)
find_dependency(nlohmann_json 3.12.0 EXACT)
include("${CMAKE_CURRENT_LIST_DIR}/CheckNative.cmake")
get_filename_component(EdgeLLM_PREFIX "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE)
set(EdgeLLM_VERSION "@_edge_version@")
set(EdgeLLM_REVISION "@_edge_revision@")
set(EdgeLLM_CUDA_VERSION "@CUDAToolkit_VERSION@")
set(EdgeLLM_TENSORRT_VERSION "@_edge_trt_version@")
set(EdgeLLM_ARCH "@CMAKE_SYSTEM_PROCESSOR@")
set(EdgeLLM_CUDA_ARCHITECTURE "@TRTMC_EDGELLM_CUDA_ARCHITECTURE@")
if(CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSTEM_PROCESSOR STREQUAL EdgeLLM_ARCH)
message(FATAL_ERROR "EdgeLLM is a native-only package for ${EdgeLLM_ARCH}")
endif()
if(NOT CUDAToolkit_VERSION_MAJOR EQUAL @CUDAToolkit_VERSION_MAJOR@ OR
NOT CUDAToolkit_VERSION_MINOR EQUAL @CUDAToolkit_VERSION_MINOR@)
message(FATAL_ERROR "EdgeLLM requires the CUDA SDK it was built with: ${EdgeLLM_CUDA_VERSION}")
endif()
set(EdgeLLM_PYTHON_EXECUTABLE "${EdgeLLM_PREFIX}/libexec/trtmc-edge-llm/bin/python")
set(EdgeLLM_BUILDER_LAUNCHER "${EdgeLLM_PREFIX}/bin/edgellm-builder")
find_path(EdgeLLM_TRT_INCLUDE_DIR NvInfer.h HINTS "$ENV{TRT_ROOT}" "@TRTMC_EDGELLM_TRT_ROOT@" PATH_SUFFIXES include REQUIRED)
find_library(EdgeLLM_TRT_LIBRARY nvinfer HINTS "$ENV{TRT_ROOT}" "@TRTMC_EDGELLM_TRT_ROOT@" PATH_SUFFIXES lib lib64 REQUIRED)
find_library(EdgeLLM_PARSER_LIBRARY nvonnxparser HINTS "$ENV{TRT_ROOT}" "@TRTMC_EDGELLM_TRT_ROOT@" PATH_SUFFIXES lib lib64 REQUIRED)
_edgellm_trt_version("${EdgeLLM_TRT_INCLUDE_DIR}" _edge_current_trt)
if(NOT _edge_current_trt STREQUAL EdgeLLM_TENSORRT_VERSION)
message(FATAL_ERROR "EdgeLLM requires TensorRT ${EdgeLLM_TENSORRT_VERSION}; found ${_edge_current_trt}")
endif()
_edgellm_check_gpu("${EdgeLLM_CUDA_ARCHITECTURE}")
if(NOT TARGET EdgeLLM::Core)
add_library(EdgeLLM::Core STATIC IMPORTED)
set_target_properties(EdgeLLM::Core PROPERTIES
IMPORTED_LOCATION "${EdgeLLM_PREFIX}/lib/libedgellmCore.a"
INTERFACE_INCLUDE_DIRECTORIES "${EdgeLLM_PREFIX}/include;${EdgeLLM_PREFIX}/include/edgellm/cpp;${EdgeLLM_PREFIX}/include/edgellm/3rdParty/nlohmannJson/include;${EdgeLLM_PREFIX}/include/edgellm/3rdParty/stb;${EdgeLLM_PREFIX}/include/edgellm/3rdParty/miniaudio;${EdgeLLM_TRT_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${EdgeLLM_PREFIX}/lib/libcutedsl.a;${EdgeLLM_TRT_LIBRARY};${EdgeLLM_PARSER_LIBRARY};CUDA::cudart;CUDA::cuda_driver;Threads::Threads;${CMAKE_DL_LIBS}")
add_library(EdgeLLM::Plugin SHARED IMPORTED)
set_target_properties(EdgeLLM::Plugin PROPERTIES IMPORTED_LOCATION "${EdgeLLM_PREFIX}/lib/libNvInfer_edgellm_plugin.so")
endif()
22 changes: 22 additions & 0 deletions cmake/edgellm/Install.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
file(INSTALL "@_edge_build@/cpp/libedgellmCore.a" DESTINATION "@_edge_prefix@/lib")
file(INSTALL "@_edge_build@/libNvInfer_edgellm_plugin.so" DESTINATION "@_edge_prefix@/lib" FOLLOW_SYMLINK_CHAIN)
file(INSTALL "@_edge_source@/cpp/kernels/cuteDSLArtifact/@CMAKE_SYSTEM_PROCESSOR@/sm_@TRTMC_EDGELLM_CUDA_ARCHITECTURE@/libcutedsl_@CMAKE_SYSTEM_PROCESSOR@.a"
DESTINATION "@_edge_prefix@/lib" RENAME libcutedsl.a)
file(INSTALL "@_edge_source@/cpp" DESTINATION "@_edge_prefix@/include/edgellm" FILES_MATCHING PATTERN "*.h" PATTERN "*.cuh")
foreach(_third_party IN ITEMS nlohmannJson stb miniaudio)
file(INSTALL "@_edge_source@/3rdParty/${_third_party}" DESTINATION "@_edge_prefix@/include/edgellm/3rdParty"
FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp")
endforeach()
file(MAKE_DIRECTORY "@_edge_prefix@/bin" "@_edge_prefix@/share/trtmc")
file(WRITE "@_edge_prefix@/bin/edgellm-builder" [=[#!/bin/sh
set -eu
prefix=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
exec "$prefix/libexec/trtmc-edge-llm/bin/python" -I -c 'from experimental.builder.cli import main; main()' "$@"
]=])
file(CHMOD "@_edge_prefix@/bin/edgellm-builder" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
execute_process(COMMAND "@_edge_python@" -I -c "import tensorrt; print(tensorrt.__version__)"
OUTPUT_VARIABLE _trt_version OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)
# Paths are relative to the installation prefix, preserving relocatability.
file(WRITE "@_edge_prefix@/share/trtmc/edge-llm.json" "{\n \"schema_version\": 1,\n \"version\": \"@_edge_version@\",\n \"revision\": \"@_edge_revision@\",\n \"arch\": \"@CMAKE_SYSTEM_PROCESSOR@\",\n \"architectures\": [@TRTMC_EDGELLM_CUDA_ARCHITECTURE@],\n \"cuda_version\": \"@CUDAToolkit_VERSION_MAJOR@.@CUDAToolkit_VERSION_MINOR@\",\n \"tensorrt_version\": \"${_trt_version}\",\n \"python\": \"libexec/trtmc-edge-llm/bin/python\",\n \"builder\": \"bin/edgellm-builder\",\n \"plugin\": \"lib/libNvInfer_edgellm_plugin.so\"\n}\n")
36 changes: 36 additions & 0 deletions cmake/edgellm/Prepare.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Executed only by the explicit CMake dependency build, never by model dispatch.
function(run)
execute_process(COMMAND ${ARGV} COMMAND_ERROR_IS_FATAL ANY)
endfunction()
execute_process(COMMAND "@Python3_EXECUTABLE@" -I -c "import ensurepip"
RESULT_VARIABLE _has_ensurepip OUTPUT_QUIET ERROR_QUIET)
if(_has_ensurepip EQUAL 0)
run("@Python3_EXECUTABLE@" -I -m venv --copies "@_edge_prefix@/libexec/trtmc-edge-llm")
else()
# Debian minimal Python may omit ensurepip; use an already installed bootstrapper.
run("@Python3_EXECUTABLE@" -I -m virtualenv --copies --no-download --no-periodic-update
"@_edge_prefix@/libexec/trtmc-edge-llm")
endif()
set(_pip_options --isolated install --no-user)
if(NOT "@TRTMC_EDGELLM_WHEELHOUSE@" STREQUAL "")
list(APPEND _pip_options --no-index --find-links "@TRTMC_EDGELLM_WHEELHOUSE@")
endif()
file(GLOB _trt_wheels "@TRTMC_EDGELLM_TRT_ROOT@/python/tensorrt-*-cp@Python3_VERSION_MAJOR@@Python3_VERSION_MINOR@-none-linux_@CMAKE_SYSTEM_PROCESSOR@.whl")
list(LENGTH _trt_wheels _wheel_count)
if(NOT _wheel_count EQUAL 1)
message(FATAL_ERROR "Expected exactly one TensorRT SDK wheel matching the native Python ABI")
endif()
run("@_edge_python@" -I -m pip ${_pip_options} --report "@_edge_prefix@/pip-report.json"
${_trt_wheels} numpy==2.2.6 transformers==5.14.1 jinja2==3.1.6
scikit-build-core==0.11.6 wheel==0.45.1 cmake==3.31.10 ninja==1.13.0
"cuda-python>=@CUDAToolkit_VERSION_MAJOR@.@CUDAToolkit_VERSION_MINOR@,<@CUDAToolkit_VERSION_MAJOR@.@CUDAToolkit_VERSION_MINOR@.999"
"nvidia-cutlass-dsl[cu@CUDAToolkit_VERSION_MAJOR@]==4.7.0" "cupy-cuda@CUDAToolkit_VERSION_MAJOR@x==13.6.0")
run("@_edge_python@" -I -m pip ${_pip_options} --no-deps --no-build-isolation "@_edge_source@")
run("@_edge_python@" -I -m pip --isolated check)
run("@_edge_python@" -I -c "print(__import__('tensorrt').__version__)")
set(ENV{PATH} "@CUDAToolkit_BIN_DIR@:$ENV{PATH}")
run("@_edge_python@" -I "@_edge_source@/kernelSrcs/build_cutedsl.py"
--gpu_arch "sm_@TRTMC_EDGELLM_CUDA_ARCHITECTURE@" --arch "@CMAKE_SYSTEM_PROCESSOR@"
--kernels fmha,gdn --cuda-version "@CUDAToolkit_VERSION_MAJOR@.@CUDAToolkit_VERSION_MINOR@" --jobs "@TRTMC_EDGELLM_JOBS@")
56 changes: 56 additions & 0 deletions cmake/edgellm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Pinned native Edge-LLM package

Edge-LLM is optional. The default `TRTMC_ENABLE_EDGELLM=OFF` neither downloads
nor builds it. Enable it once while installing Model Connect; ordinary model
builds only use the installed package and never fetch or install dependencies.
Cross compilation is rejected. Configure and build on the inference GPU host.

```bash
cmake -S . -B build \
-DTRTMC_ENABLE_EDGELLM=ON \
-DTRTMC_EDGELLM_CUDA_ARCHITECTURE=80 \
-DTRTMC_EDGELLM_TRT_ROOT="$TRT_ROOT" \
-DCUDAToolkit_ROOT="$CUDA_ROOT" \
-DCMAKE_CUDA_COMPILER="$CUDA_ROOT/bin/nvcc" \
-DCMAKE_INSTALL_PREFIX="$PWD/install"
cmake --build build --parallel 8
cmake --install build
export CMAKE_PREFIX_PATH="$PWD/install${CMAKE_PREFIX_PATH:+:$CMAKE_PREFIX_PATH}"
```

The regular project dependencies remain required, including nlohmann_json
**3.12.0** when Edge is enabled (its C++ ABI must match upstream). The Python
interpreter needs `ensurepip` or an already installed `virtualenv` bootstrapper.
The native CUDA SDK must include NVCC, NVRTC, cuRAND headers and driver link
libraries; the TensorRT SDK must contain its matching CPython wheel.

The provider first uses `find_package(EdgeLLM 0.10.1 EXACT CONFIG)`. If absent,
CMake `ExternalProject` clones the public NVIDIA TensorRT-Edge-LLM repository at
`e8b29522938901f6df19ebeedd4b69bc8edbcd97` (v0.10.1), initializes the pinned
submodules, builds the native core/plugin and FMHA/GDN CuTe archives, and installs
an isolated direct-builder Python environment. It does not install the exporter
or modify the caller Python environment. Downloads happen only during this
explicit dependency build. `TRTMC_EDGELLM_WHEELHOUSE` selects a complete offline
Python wheelhouse; `TRTMC_EDGELLM_GIT_MIRROR` optionally supplies a local Git
mirror, still checked out at the immutable upstream commit.

Upstream 0.10.1 does not export a CMake SDK package, so these compact templates
supply that installation boundary. `EdgeLLM::Core` exposes the installed static
core, headers, CuTe archive and native dependencies. Consumers requiring CUDA
device linking enable separable compilation and device-symbol resolution.
`EdgeLLM::Plugin` identifies the plugin DSO; adapters load it, rather than linking
it twice. `EdgeLLM_PYTHON_EXECUTABLE` and `EdgeLLM_BUILDER_LAUNCHER` expose the
isolated upstream `experimental.builder.cli.main` API.

`share/trtmc/edge-llm.json` records the pin, native architecture, CUDA/TensorRT
versions and prefix-relative Python/plugin paths. The manifest is written only
after successful installation. Build-tree package files live under
`build/_deps/edgellm/install`; `cmake --install` copies the package into the final
prefix. Package discovery rejects mismatched native CPU/GPU and SDK versions.
Model support and routing policies belong exclusively to the model families.

GPU-independent package contract tests:

```bash
cmake -P cmake/edgellm/tests/package_contract.cmake
```
Loading
Loading