chore: import upstream snapshot with attribution
Docker Image CI / build-ubuntu2004 (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:36:55 +08:00
commit c8a779b1bb
1887 changed files with 3245738 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
#
# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
set -e
PYTHON_MAJOR_VERSION=${PYTHON_MAJOR_VERSION:-3}
PYTHON_MINOR_VERSION=${PYTHON_MINOR_VERSION:-8}
TARGET=${TARGET_ARCHITECTURE:-x86_64}
ROOT_PATH=${TRT_OSSPATH:-/workspace/TensorRT}
EXT_PATH=${EXT_PATH:-/tmp/external}
WHEEL_OUTPUT_DIR=${ROOT_PATH}/python/build
mkdir -p ${WHEEL_OUTPUT_DIR}
pushd ${WHEEL_OUTPUT_DIR}
# Generate tensorrt.so
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DTARGET=${TARGET} \
-DPYTHON_MAJOR_VERSION=${PYTHON_MAJOR_VERSION} \
-DPYTHON_MINOR_VERSION=${PYTHON_MINOR_VERSION} \
-DEXT_PATH=${EXT_PATH} \
-DTENSORRT_ROOT=${ROOT_PATH} \
-DTENSORRT_MODULE=${TENSORRT_MODULE} \
-DTENSORRT_LIBPATH=${TRT_LIBPATH} \
-DTRT_ONNXPARSER_NAME=nvonnxparser
make -j12
# Generate wheel
TRT_MAJOR=$(awk '/^\#define TRT_MAJOR_ENTERPRISE/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_MINOR=$(awk '/^\#define TRT_MINOR_ENTERPRISE/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_PATCH=$(awk '/^\#define TRT_PATCH_ENTERPRISE/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_BUILD=$(awk '/^\#define TRT_BUILD_ENTERPRISE/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_VERSION=${TRT_MAJOR}.${TRT_MINOR}.${TRT_PATCH}.${TRT_BUILD}
TRT_MAJMINPATCH=${TRT_MAJOR}.${TRT_MINOR}.${TRT_PATCH}
PLUGIN_DISABLED_STR="0"
echo "Generating python ${PYTHON_MAJOR_VERSION}.${PYTHON_MINOR_VERSION} bindings for TensorRT ${TRT_VERSION}"
expand_vars_cp () {
test -f ${1} || (echo "ERROR: File: ${1} does not exist!" && exit 1); \
sed -e "s|\#\#TENSORRT_VERSION\#\#|${TRT_VERSION}|g" \
-e "s|\#\#TENSORRT_MAJMINPATCH\#\#|${TRT_MAJMINPATCH}|g" \
-e "s|\#\#TENSORRT_PYTHON_VERSION\#\#|${TRT_MAJMINPATCH}|g" \
-e "s|\#\#TENSORRT_MODULE\#\#|${TENSORRT_MODULE}|g" \
-e "s|##TENSORRT_PLUGIN_DISABLED##|${PLUGIN_DISABLED_STR}|g" \
${1} > ${2}
}
pushd ${ROOT_PATH}/python/packaging
for dir in $(find . -type d); do mkdir -p ${WHEEL_OUTPUT_DIR}/$dir; done
for file in $(find . -type f); do expand_vars_cp $file ${WHEEL_OUTPUT_DIR}/${file}; done
popd
# Copy required files and directories to build the bindings.
cp tensorrt/tensorrt.so bindings_wheel/tensorrt/tensorrt.so
mv tensorrt_build_backend bindings_wheel/
pushd ${WHEEL_OUTPUT_DIR}/bindings_wheel
python -m build --no-isolation --wheel --config-setting=wheel-type=binding --config-setting=python-tag=cp${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION} --config-setting=plat-name=linux_${TARGET}
popd
+261
View File
@@ -0,0 +1,261 @@
#!/usr/bin/env python3
#
# SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import argparse
import onnx
import logging
import os
import numpy as np
import onnx_graphsurgeon as gs
from onnx import helper, TensorProto, numpy_helper, version_converter
'''
This script is converting TE ONNX models (cast + CustomOp Q) and (CustomOp DQ + cast) pairs to Opset19 ONNX Q/DQ
usage:
python3 convert_te_onnx_to_trt_onnx.py --onnx_model_path <folder/file>
This script requires onnx 1.14 and above
'''
def find_node_by_tensor(graph, search_tensor, is_node_input, search_node_type=None):
for idx, node in enumerate(graph.node):
search_container = node.output
if is_node_input:
search_container = node.input
for node_tensor in search_container:
if search_node_type and node.op_type != search_node_type:
continue
if node_tensor == search_tensor:
return node, idx
return None, None
def redirect_quantize_input(graph, q_node):
assert(q_node.op_type == 'QuantizeLinear')
q_input = q_node.input[0]
cast_node, cast_node_idx = find_node_by_tensor(graph, q_input, False, 'Cast')
if cast_node:
q_node.input[0] = cast_node.input[0]
return [cast_node_idx]
return []
def redirect_dequantize_output(graph, dq_node):
assert(dq_node.op_type == 'DequantizeLinear')
dq_output = dq_node.output[0]
cast_node, cast_node_idx = find_node_by_tensor(graph, dq_output, True, 'Cast')
if cast_node:
dq_node.output[0] = cast_node.output[0]
return [cast_node_idx]
return []
def get_attr_numpy_tensor(attr):
assert(attr.type == onnx.AttributeProto.TENSOR)
return numpy_helper.to_array(attr.t)
def get_attr(node, search_attr_name):
for idx, attr in enumerate(node.attribute):
if attr.name == search_attr_name:
return attr, idx
return None, None
def cast_scale(graph, qdq_node, cast_to):
assert(cast_to in ['fp32', 'fp16'])
assert(qdq_node.op_type in ['QuantizeLinear', 'DequantizeLinear'])
constant_node_idx = None
scale_tensor = qdq_node.input[1]
constant_node, constant_node_idx = find_node_by_tensor(graph, scale_tensor, False, 'Constant')
scale_cast_to_dtype = None
onnx_cast_to_dtype = None
if cast_to == 'fp16':
scale_cast_to_dtype = np.dtype(np.float32)
onnx_cast_to_dtype = onnx.TensorProto.FLOAT16
elif cast_to == 'fp32':
scale_cast_to_dtype = np.dtype(np.float32)
onnx_cast_to_dtype = onnx.TensorProto.FLOAT
if constant_node:
scale_attr, _ = get_attr(constant_node, 'value')
assert(scale_attr)
numpy_scale = get_attr_numpy_tensor(scale_attr)
logging.info(type(numpy_scale.dtype))
logging.info(type(scale_cast_to_dtype))
if numpy_scale.dtype != scale_cast_to_dtype:
logging.debug(f'Change {qdq_node.name} scale from {numpy_scale.dtype} to {scale_cast_to_dtype}')
numpy_scale = numpy_scale.astype(scale_cast_to_dtype)
tensor_name = constant_node.name + '_casted'
create_constant_tensor(graph, tensor_name, onnx_cast_to_dtype, numpy_scale)
qdq_node.input[1] = tensor_name
else:
logging.warning(f'No constant node connected to {qdq_node} as scale')
if constant_node_idx:
return [constant_node_idx]
return []
def create_constant_tensor(graph, name, dtype, np_tensor):
tensor_value_info = helper.make_tensor_value_info(name, dtype, np_tensor.shape)
graph.input.append(tensor_value_info)
helper.make_tensor(name, data_type=dtype, dims=(), vals=[0])
tensor_initializer = helper.make_tensor(name, dtype, np_tensor.shape, np_tensor.flatten().tolist())
graph.initializer.append(tensor_initializer)
'''
Convert custom operators to opset19
'''
def custom_op_to_opset19(graph, node, use_int32_quantization, remove_cast_before_q, remove_cast_after_dq, change_qdq_scale_precision):
assert(node.op_type in ['TRT_FP8QuantizeLinear', 'TRT_FP8DequantizeLinear'])
is_dq = node.op_type == 'TRT_FP8DequantizeLinear'
logging.debug(f'Convert {node.name} to Opset19')
orig_node_name = node.name
new_node_name = orig_node_name + '_converted'
quant_to = TensorProto.FLOAT8E4M3FN
if use_int32_quantization:
quant_to = TensorProto.INT32
#add zero point to the node
tensor_name = new_node_name + '_zero_point'
create_constant_tensor(graph, tensor_name, quant_to, np.array([0]))
node.input.append(tensor_name)
node.domain = ""
node.op_type = "QuantizeLinear"
node_idxs_to_delete = []
if is_dq:
node.op_type = "DequantizeLinear"
if remove_cast_after_dq:
node_idxs_to_delete += redirect_dequantize_output(graph, node)
if change_qdq_scale_precision:
node_idxs_to_delete += cast_scale(graph, node, change_qdq_scale_precision)
else:
if remove_cast_before_q:
node_idxs_to_delete += redirect_quantize_input(graph, node)
if change_qdq_scale_precision:
node_idxs_to_delete += cast_scale(graph, node, change_qdq_scale_precision)
node.name = new_node_name
logging.debug(f'Convert Done\n')
return node_idxs_to_delete
def check_model(graph):
converted_qdq_ops = ['TRT_FP8QuantizeLinear', 'TRT_FP8DequantizeLinear']
passed_check = True
for node in graph.node:
if node.op_type in converted_qdq_ops:
logging.error(f'Node \"{node.name}\" of type {node.op_type} should have been removed')
passed_check = False
return passed_check
def update_quantize_node_type(model):
graph = gs.import_onnx(model)
for node in graph.nodes:
if node.op == "TRT_FP8QuantizeLinear":
for out in node.outputs:
out.dtype = TensorProto.FLOAT8E4M3FN
return gs.export_onnx(graph)
'''
Converts onnx files from TE to TRT
'''
def replace_customop_qdq_with_onnx_qdq(te_onnx_files, results_path, create_netron_compatible_model, remove_cast_before_q, remove_cast_after_dq, change_qdq_scale_precision):
# store mappings from original ONNX name to new ONNX name.
file_mappings = {}
for te_onnx_file in te_onnx_files:
logging.debug('Loading model')
model = onnx.load(te_onnx_file, load_external_data=False)
# update QuantizeLinear output dtype
model = update_quantize_node_type(model)
# change model opset to 19
model.opset_import[0].version = 19
graph = model.graph
logging.debug('Loading model finished')
converted_qdq_ops = ['TRT_FP8QuantizeLinear', 'TRT_FP8DequantizeLinear']
try:
node_idxs_to_delete = []
converted = False
for node in graph.node:
if node.op_type in converted_qdq_ops:
converted = True
node_idxs_to_delete += custom_op_to_opset19(graph, node, create_netron_compatible_model, remove_cast_before_q, remove_cast_after_dq, change_qdq_scale_precision)
if converted:
assert(check_model(graph))
node_idxs_to_delete = reversed(sorted(node_idxs_to_delete))
for node_idx in node_idxs_to_delete:
del(graph.node[node_idx])
suffix = '.opset19'
if create_netron_compatible_model:
suffix += '.netron'
suffix += '.onnx'
new_model_filename = os.path.join(results_path, os.path.splitext(os.path.split(te_onnx_file)[1])[0] + suffix)
onnx.save_model(model, new_model_filename)
logging.info(f'The converted model is saved at {new_model_filename}!')
file_mappings[te_onnx_file] = new_model_filename
else:
logging.info(f'No conversion was done with {te_onnx_file}!')
file_mappings[te_onnx_file] = te_onnx_file
except Exception as ex:
logging.error(f'Failed: {ex}')
file_mappings[te_onnx_file] = None
return file_mappings
if __name__ == "__main__":
logging.getLogger().setLevel(logging.INFO)
parser = argparse.ArgumentParser()
parser.add_argument('--onnx_model_path', required=True, help="Path of model or a folder of models. When using a folder, this script will convert all \'.onnx\' files")
parser.add_argument('--results_path', required=False, help="Path for generated models, when not set, the generated model(s) will be next ot the origianl model(s)")
parser.add_argument('--create_netron_compatible_model', action='store_true', required=False, help="When set, the script will use int32 quantization. "
"This enables the user to view the graph with Netron, until it adds support for opset19. The generated model isn't TRT compatible.")
parser.add_argument('--remove_casts', required=False, help="Controls whether to remove casts around q/dq nodes. "
"For example, when set to \'dq\', remove casts only after dq. Default is \'keep_all\'", choices=['q', 'dq', 'qdq', 'keep_all'], default='keep_all')
parser.add_argument('--change_qdq_scale_precision', required=False, help="When set controls q/dq nodes scales data type.", choices=['fp32', 'fp16'])
args = parser.parse_args()
results_path = args.results_path
if results_path and os.path.isdir(results_path) == False:
logging.error(f'\'--results_path\' set to \'{results_path}\', but the folder doesn\'t exist, exiting')
exit(-1)
if results_path is None:
results_path = args.onnx_model_path
if os.path.isfile(results_path):
results_path = os.path.split(results_path)[0]
remove_cast_after_dq = False
remove_cast_before_q = False
if args.remove_casts == 'q':
remove_cast_before_q = True
elif args.remove_casts == 'dq':
remove_cast_after_dq = True
elif args.remove_casts == 'qdq':
remove_cast_after_dq = True
remove_cast_before_q = True
onnx_files = []
if os.path.isdir(args.onnx_model_path):
logging.info(f"Got folder: {args.onnx_model_path}")
onnx_files = [os.path.join(args.onnx_model_path, filename) for filename in os.listdir(args.onnx_model_path) if filename.endswith('.onnx')==True and filename.endswith('.opset19.onnx')==False]
else:
logging.info(f"Got file: {args.onnx_model_path}")
onnx_files = [args.onnx_model_path]
replace_customop_qdq_with_onnx_qdq(onnx_files, results_path, args.create_netron_compatible_model, remove_cast_before_q, remove_cast_after_dq, args.change_qdq_scale_precision)
+175
View File
@@ -0,0 +1,175 @@
#!/usr/bin/env python3
#
# SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import argparse
import os
import re
# Configuration
copyright_year = "2020"
extensions_p = (".py", ".sh", ".cmake", "CMakeLists")
extensions_c = (".c", ".cpp", ".h", ".hpp", ".cu")
pattern_p = """#\s*
# Copyright \(c\) ([1-2][0-9]{3}),* NVIDIA CORPORATION.*
#\s*
# Licensed under the Apache License, Version 2.0 \(the "License"\);\s*
# you may not use this file except in compliance with the License.\s*
# You may obtain a copy of the License at\s*
#\s*
# http://www.apache.org/licenses/LICENSE-2.0\s*
#\s*
# Unless required by applicable law or agreed to in writing, software\s*
# distributed under the License is distributed on an "AS IS" BASIS,\s*
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\s*
# See the License for the specific language governing permissions and\s*
# limitations under the License.\s*
#
"""
header_p = """#
# Copyright (c) {year}, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
""".format(year=copyright_year)
pattern_c = """/\*\s*
\* Copyright \(c\) ([1-2][0-9]{3}),* NVIDIA CORPORATION.*
\*\s*
\* Licensed under the Apache License, Version 2.0 \(the "License"\);\s*
\* you may not use this file except in compliance with the License.\s*
\* You may obtain a copy of the License at\s*
\*\s*
\* http://www.apache.org/licenses/LICENSE-2.0\s*
\*\s*
\* Unless required by applicable law or agreed to in writing, software\s*
\* distributed under the License is distributed on an "AS IS" BASIS,\s*
\* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\s*
\* See the License for the specific language governing permissions and\s*
\* limitations under the License.\s*
\*/
"""
header_c = """/*
* Copyright (c) {year}, NVIDIA CORPORATION. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
""".format(year=copyright_year)
# Routines
def parse_args(parser):
"""
Parse commandline arguments.
"""
parser.add_argument('-d', '--dir', type=str, required=True, help='Root directory to start the scan')
parser.add_argument('-f','--force-update', action='store_true', help='Force the header writes for all files')
parser.add_argument('--dry-run', action='store_true', help='Just perform a dry-run')
parser.add_argument('--max-depth', type=int,default=100, help='Maximum depth to recurse while scanning files.')
return parser
def update(filename, args):
"""
Update copyright header for specified file
"""
if filename.endswith(extensions_p):
pattern = re.compile(pattern_p)
header = header_p
shebang = re.compile(r'^(\#\!.*\n)', re.MULTILINE)
elif filename.endswith(extensions_c):
pattern = re.compile(pattern_c)
header = header_c
shebang = None
else:
return
with open(filename, "r+") as f:
data = f.read()
match = pattern.search(data)
if match:
year = match.group(1)
if copyright_year == year:
if args.force_update:
print(filename,": FORCED")
new_data = pattern.sub(header, data, count=1)
else:
print(filename,": SKIP")
return
else:
print(filename,": UPDATE (",year,"->",copyright_year,")")
new_data = pattern.sub(header, data, count=1)
else:
match = shebang.search(data) if shebang else None
if match:
print(filename,": ADD ( after",match.group(1),")")
new_data = shebang.sub(match.group(1)+header, data, count=1)
else:
print(filename,": ADD ( top )")
new_data = header+data
if not args.dry_run:
with open(filename, "w") as f:
f.write(new_data)
def copyright_scan(directory, depth, args, exclude_dirs=[]):
"""
Update copyright for TensorRT sources
"""
if directory in exclude_dirs:
return
for f in os.listdir(directory):
filename = os.path.join(directory,f)
if os.path.isdir(filename) and (depth > 0):
copyright_scan(filename, depth-1, args, exclude_dirs)
elif filename.endswith(extensions_p + extensions_c):
update(filename, args)
def main():
parser = argparse.ArgumentParser(description='TensorRT copyright scan')
parser = parse_args(parser)
args, _ = parser.parse_known_args()
exclude_dirs = ["./third_party","./build","./parsers/onnx", "./include"]
copyright_scan(args.dir, args.max_depth, args, exclude_dirs)
if __name__ == '__main__':
main()
+69
View File
@@ -0,0 +1,69 @@
#!/bin/bash
#
# SPDX-FileCopyrightText: Copyright (c) 1993-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This short shell script will extract all the strong "text" symbols from the
# shared library and create a new "stub" shared library with the same symbols.
# The body of these functions will be empty and therefore have no dependencies.
# This scripts uses whatever CC is defined in the user's environment.
#
set -o pipefail
# check arguments
if [ $# -ne 2 ] ; then
echo "Usage: $(basename $0) IN_LIBFILE OUT_LIBFILE"
exit 1
fi
IN_LIBFILE="$1"
OUT_LIBFILE="$2"
# check compiler
if [ -z "${CC}" ] ; then
echo "Error: Environment variable 'CC' has not been defined"
exit 1
fi
SONAME=$(readelf -d "${IN_LIBFILE}" | grep '(SONAME)' | cut -d [ -f 2 | cut -d ] -f 1)
# Detect OS from /etc/os-release instead of lsb_release (which may not be installed).
if [ -f /etc/os-release ]; then
. /etc/os-release
OS="${ID}-${VERSION_ID}"
else
OS="unknown"
fi
if [ "$OS" = "ubuntu-22.04" ] ; then
EXTRA_NM_FLAG="--without-symbol-versions"
elif [ "$OS" = "ubuntu-24.04" ] ; then
EXTRA_NM_FLAG="--without-symbol-versions"
fi
# make stub library
# This uses the system nm in containers that compile with SCL, but the output is identical to the SCL output
if [ -z "${CC_ARGS}" ] ; then
nm -D "${IN_LIBFILE}" ${EXTRA_NM_FLAG} | \
awk '{if ($2 == "T") { print "void",$3,"() {}" }}' | \
${CC} -xc -Og -fPIC -shared -Wl,-soname=${SONAME} -Wl,--strip-all -o "${OUT_LIBFILE}" -
else
nm -D "${IN_LIBFILE}" ${EXTRA_NM_FLAG} | \
awk '{if ($2 == "T") { print "void",$3,"() {}" }}' | \
${CC} -xc -Og -fPIC -shared -Wl,-soname=${SONAME} -Wl,--strip-all -o "${OUT_LIBFILE}" "${CC_ARGS}" -
fi
exit $?