chore: import upstream snapshot with attribution
Docker Image CI / build-ubuntu2004 (push) Waiting to run
Docker Image CI / build-ubuntu2004 (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
|
||||
|
||||
# Note: This subdirectory is added multiple times, once for each binding library target.
|
||||
|
||||
# Indirectly call the current ADD_SOURCES_FUNCTION to populate target sources on the bindings lib that currently being setup.
|
||||
cmake_language(CALL ${ADD_SOURCES_FUNCTION}
|
||||
pyTensorRT.cpp
|
||||
utils.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(infer ${SUBDIR_BINARY_DIR_PREFIX}/src/infer)
|
||||
add_subdirectory(parsers ${SUBDIR_BINARY_DIR_PREFIX}/src/parsers)
|
||||
@@ -0,0 +1,30 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025-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.
|
||||
|
||||
# Note: This subdirectory is added multiple times, once for each binding library target.
|
||||
|
||||
# Indirectly call the current ADD_SOURCES_FUNCTION to populate target sources on the bindings lib that currently being setup.
|
||||
cmake_language(CALL ${ADD_SOURCES_FUNCTION}
|
||||
pyCore.cpp
|
||||
pyPlugin.cpp
|
||||
pyFoundationalTypes.cpp
|
||||
)
|
||||
|
||||
# These sources are omitted from the lean/dispatch runtime bindings.
|
||||
if(${TRT_PYTHON_IS_FULL_BINDINGS})
|
||||
cmake_language(CALL ${ADD_SOURCES_FUNCTION}
|
||||
pyGraph.cpp
|
||||
)
|
||||
endif()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2025 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 contains the fundamental types, i.e. Dims, Weights, dtype
|
||||
#include "ForwardDeclarations.h"
|
||||
#include "utils.h"
|
||||
#include <pybind11/numpy.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
#include "infer/pyFoundationalTypesDoc.h"
|
||||
#include <cuda_runtime_api.h>
|
||||
|
||||
namespace tensorrt
|
||||
{
|
||||
using namespace nvinfer1;
|
||||
|
||||
namespace lambdas
|
||||
{
|
||||
// For Weights
|
||||
static const auto weights_datatype_constructor = [](DataType const& type) { return new Weights{type, nullptr, 0}; };
|
||||
|
||||
static const auto weights_pointer_constructor = [](DataType const& type, size_t const ptr, int64_t count) {
|
||||
return new Weights{type, reinterpret_cast<void*>(ptr), count};
|
||||
};
|
||||
|
||||
static const auto weights_numpy_constructor = [](py::array& arr) {
|
||||
arr = py::array::ensure(arr);
|
||||
// In order to construct a weights object, we must have a contiguous C-style array.
|
||||
PY_ASSERT_VALUE_ERROR(
|
||||
arr, "Could not convert NumPy array to Weights. Is it using a data type supported by TensorRT?");
|
||||
PY_ASSERT_VALUE_ERROR((arr.flags() & py::array::c_style),
|
||||
"Could not convert non-contiguous NumPy array to Weights. Please use numpy.ascontiguousarray() to fix this.");
|
||||
return new Weights{utils::type(arr.dtype()), arr.data(), arr.size()};
|
||||
};
|
||||
|
||||
// Helper to compare dims with any kind of Python Iterable.
|
||||
template <typename DimsType, typename PyIterable>
|
||||
bool dimsEqual(DimsType const& self, PyIterable& other)
|
||||
{
|
||||
if (static_cast<int64_t>(other.size()) != self.nbDims)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool eq = true;
|
||||
std::vector<int64_t> o = other.template cast<std::vector<int64_t>>();
|
||||
for (int32_t i = 0; i < self.nbDims; ++i)
|
||||
{
|
||||
eq = eq && (self.d[i] == o[i]);
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
|
||||
// For base Dims class
|
||||
static const auto dims_vector_constructor = [](std::vector<int64_t> const& in) {
|
||||
// This is required, because otherwise MAX_DIMS will not be resolved at compile time.
|
||||
int32_t const maxDims{static_cast<int32_t>(Dims::MAX_DIMS)};
|
||||
PY_ASSERT_VALUE_ERROR(in.size() <= maxDims,
|
||||
"Input length " + std::to_string(in.size()) + ". Max expected length is " + std::to_string(maxDims));
|
||||
|
||||
// Create the Dims object.
|
||||
Dims* self = new Dims{};
|
||||
self->nbDims = in.size();
|
||||
for (int32_t i = 0; static_cast<size_t>(i) < in.size(); ++i)
|
||||
self->d[i] = in[i];
|
||||
return self;
|
||||
};
|
||||
|
||||
static const auto dims_to_str = [](Dims const& self) {
|
||||
if (self.nbDims == 0)
|
||||
return std::string("()");
|
||||
// Length 1 should followed by trailing comma, for tuple-like behavior.
|
||||
if (self.nbDims == 1)
|
||||
return "(" + std::to_string(self.d[0]) + ",)";
|
||||
// Non-zero lengths
|
||||
std::string temp = "(";
|
||||
for (int32_t i = 0; i < self.nbDims - 1; ++i)
|
||||
temp += std::to_string(self.d[i]) + ", ";
|
||||
temp += std::to_string(self.d[self.nbDims - 1]) + ")";
|
||||
return temp;
|
||||
};
|
||||
|
||||
static const auto dims_len = [](Dims const& self) { return self.nbDims; };
|
||||
|
||||
// TODO: Add slicing support?
|
||||
static const auto dims_getter = [](Dims const& self, int32_t const pyIndex) -> int64_t const& {
|
||||
// Without these bounds checks, horrible infinite looping will occur.
|
||||
int32_t const index{(pyIndex < 0) ? static_cast<int32_t>(self.nbDims) + pyIndex : pyIndex};
|
||||
PY_ASSERT_INDEX_ERROR(index >= 0 && index < self.nbDims);
|
||||
return self.d[index];
|
||||
};
|
||||
|
||||
static const auto dims_getter_slice = [](Dims const& self, py::slice slice) {
|
||||
int64_t start, stop, step, slicelength;
|
||||
PY_ASSERT_VALUE_ERROR(
|
||||
slice.compute(self.nbDims, &start, &stop, &step, &slicelength), "Incorrect getter slice dims");
|
||||
// Disallow out-of-bounds things.
|
||||
PY_ASSERT_INDEX_ERROR(stop <= self.nbDims);
|
||||
|
||||
py::tuple ret{slicelength};
|
||||
for (int32_t i = start, index = 0; i < stop; i += step, ++index)
|
||||
ret[index] = self.d[i];
|
||||
return ret;
|
||||
};
|
||||
|
||||
static const auto dims_setter = [](Dims& self, int32_t const pyIndex, int64_t const item) {
|
||||
int32_t const index{(pyIndex < 0) ? static_cast<int32_t>(self.nbDims) + pyIndex : pyIndex};
|
||||
PY_ASSERT_INDEX_ERROR(index >= 0 && index < self.nbDims);
|
||||
self.d[index] = item;
|
||||
};
|
||||
|
||||
static const auto dims_setter_slice = [](Dims& self, py::slice slice, Dims const& other) {
|
||||
int64_t start, stop, step, slicelength;
|
||||
PY_ASSERT_VALUE_ERROR(
|
||||
slice.compute(self.nbDims, &start, &stop, &step, &slicelength), "Incorrect setter slice dims");
|
||||
// Disallow out-of-bounds things.
|
||||
PY_ASSERT_INDEX_ERROR(stop < self.nbDims);
|
||||
|
||||
for (int32_t i = start, index = 0; i < stop; i += step, ++index)
|
||||
self.d[i] = other.d[index];
|
||||
};
|
||||
|
||||
// For Dims2
|
||||
static const auto dims2_vector_constructor = [](std::vector<int64_t> const& in) {
|
||||
PY_ASSERT_VALUE_ERROR(in.size() == 2,
|
||||
"Input length " + std::to_string(in.size()) + " not equal to expected Dims2 length, which is 2");
|
||||
return new Dims2{in[0], in[1]};
|
||||
};
|
||||
|
||||
// For DimsHW
|
||||
static const auto dimshw_vector_constructor = [](std::vector<int64_t> const& in) {
|
||||
PY_ASSERT_VALUE_ERROR(in.size() == 2,
|
||||
"Input length " + std::to_string(in.size()) + " not equal to expected DimsHW length, which is 2");
|
||||
return new DimsHW{in[0], in[1]};
|
||||
};
|
||||
|
||||
// For Dims3
|
||||
static const auto dims3_vector_constructor = [](std::vector<int64_t> const& in) {
|
||||
PY_ASSERT_VALUE_ERROR(in.size() == 3,
|
||||
"Input length " + std::to_string(in.size()) + " not equal to expected Dims3 length, which is 3");
|
||||
return new Dims3{in[0], in[1], in[2]};
|
||||
};
|
||||
|
||||
// For Dims4
|
||||
static const auto dims4_vector_constructor = [](std::vector<int64_t> const& in) {
|
||||
PY_ASSERT_VALUE_ERROR(in.size() == 4,
|
||||
"Input length " + std::to_string(in.size()) + " not equal to expected Dims4 length, which is 4");
|
||||
return new Dims4{in[0], in[1], in[2], in[3]};
|
||||
};
|
||||
|
||||
// For IHostMemory
|
||||
static const auto host_memory_buffer_interface = [](IHostMemory& self) -> py::buffer_info {
|
||||
return py::buffer_info(self.data(), /* Pointer to buffer */
|
||||
utils::size(self.type()), /* Size of one scalar */
|
||||
py::format_descriptor<float>::format(), /* Python struct-style format descriptor */
|
||||
1, /* Number of dimensions */
|
||||
{self.size()}, /* Buffer dimensions */
|
||||
{utils::size(self.type())} /* Strides (in bytes) for each index */
|
||||
);
|
||||
};
|
||||
} // namespace lambdas
|
||||
|
||||
void bindFoundationalTypes(py::module& m)
|
||||
{
|
||||
// Bind the top level DataType enum.
|
||||
py::enum_<DataType>(m, "DataType", DataTypeDoc::descr, py::module_local())
|
||||
.value("FLOAT", DataType::kFLOAT, DataTypeDoc::float32)
|
||||
.value("HALF", DataType::kHALF, DataTypeDoc::float16)
|
||||
.value("BF16", DataType::kBF16, DataTypeDoc::bfloat16)
|
||||
.value("INT8", DataType::kINT8, DataTypeDoc::int8)
|
||||
.value("INT32", DataType::kINT32, DataTypeDoc::int32)
|
||||
.value("INT64", DataType::kINT64, DataTypeDoc::int64)
|
||||
.value("BOOL", DataType::kBOOL, DataTypeDoc::boolean)
|
||||
.value("UINT8", DataType::kUINT8, DataTypeDoc::uint8)
|
||||
.value("FP8", DataType::kFP8, DataTypeDoc::fp8)
|
||||
.value("INT4", DataType::kINT4, DataTypeDoc::int4)
|
||||
.value("FP4", DataType::kFP4, DataTypeDoc::fp4)
|
||||
.value("E8M0", DataType::kE8M0, DataTypeDoc::e8m0); // DataType
|
||||
|
||||
// Also create direct mappings (so we can call trt.float32, for example).
|
||||
m.attr("float32") = DataType::kFLOAT;
|
||||
m.attr("float16") = DataType::kHALF;
|
||||
m.attr("bfloat16") = DataType::kBF16;
|
||||
m.attr("int8") = DataType::kINT8;
|
||||
m.attr("int32") = DataType::kINT32;
|
||||
m.attr("int64") = DataType::kINT64;
|
||||
m.attr("bool") = DataType::kBOOL;
|
||||
m.attr("uint8") = DataType::kUINT8;
|
||||
m.attr("fp8") = DataType::kFP8;
|
||||
m.attr("int4") = DataType::kINT4;
|
||||
m.attr("fp4") = DataType::kFP4;
|
||||
m.attr("e8m0") = DataType::kE8M0;
|
||||
|
||||
py::enum_<WeightsRole>(m, "WeightsRole", WeightsRoleDoc::descr, py::module_local())
|
||||
.value("KERNEL", WeightsRole::kKERNEL, WeightsRoleDoc::KERNEL)
|
||||
.value("BIAS", WeightsRole::kBIAS, WeightsRoleDoc::BIAS)
|
||||
.value("SHIFT", WeightsRole::kSHIFT, WeightsRoleDoc::SHIFT)
|
||||
.value("SCALE", WeightsRole::kSCALE, WeightsRoleDoc::SCALE)
|
||||
.value("CONSTANT", WeightsRole::kCONSTANT, WeightsRoleDoc::CONSTANT)
|
||||
.value("ANY", WeightsRole::kANY, WeightsRoleDoc::ANY); // WeightsRole
|
||||
|
||||
// Weights
|
||||
py::class_<Weights>(m, "Weights", WeightsDoc::descr, py::module_local())
|
||||
// Can construct an empty weights object with type. Defaults to float32.
|
||||
.def(py::init(lambdas::weights_datatype_constructor), "type"_a = DataType::kFLOAT, WeightsDoc::init_type)
|
||||
.def(py::init(lambdas::weights_pointer_constructor), "type"_a, "ptr"_a, "count"_a, WeightsDoc::init_ptr)
|
||||
// Allows for construction through any contiguous numpy array. It then keeps a pointer to that buffer
|
||||
// (zero-copy).
|
||||
.def(py::init(lambdas::weights_numpy_constructor), "a"_a, py::keep_alive<1, 2>(), WeightsDoc::init_numpy)
|
||||
// Expose numpy-like attributes.
|
||||
.def_property_readonly("dtype", [](Weights const& self) -> DataType { return self.type; })
|
||||
.def_property_readonly("size", [](Weights const& self) { return self.count; })
|
||||
.def_property_readonly("nbytes", [](Weights const& self) { return utils::size(self.type) * self.count; })
|
||||
.def("numpy", utils::weights_to_numpy, py::return_value_policy::reference_internal, WeightsDoc::numpy)
|
||||
.def("__len__", [](Weights const& self) { return static_cast<size_t>(self.count); }); // Weights
|
||||
|
||||
// Also allow implicit construction, so we can pass in numpy arrays instead of Weights.
|
||||
py::implicitly_convertible<py::array, Weights>();
|
||||
|
||||
// Dims
|
||||
py::class_<Dims>(m, "Dims", DimsDoc::descr, py::module_local())
|
||||
.def(py::init<>())
|
||||
// Allows for construction from python lists and tuples.
|
||||
.def(py::init(lambdas::dims_vector_constructor), "shape"_a)
|
||||
// static_cast is required here, or MAX_DIMS does not get pulled in until LOAD time.
|
||||
.def_property_readonly_static(
|
||||
"MAX_DIMS", [](py::object /*self*/) { return static_cast<int32_t>(Dims::MAX_DIMS); }, DimsDoc::MAX_DIMS)
|
||||
// Allow for string representations (displays like a python tuple).
|
||||
.def("__str__", lambdas::dims_to_str)
|
||||
.def("__repr__", lambdas::dims_to_str)
|
||||
// Allow direct comparisons with tuples and lists.
|
||||
.def("__eq__", lambdas::dimsEqual<Dims, py::list>)
|
||||
.def("__eq__", lambdas::dimsEqual<Dims, py::tuple>)
|
||||
// These functions allow us to use Dims like an iterable.
|
||||
.def("__len__", lambdas::dims_len)
|
||||
.def("__getitem__", lambdas::dims_getter)
|
||||
.def("__getitem__", lambdas::dims_getter_slice)
|
||||
.def("__setitem__", lambdas::dims_setter)
|
||||
.def("__setitem__", lambdas::dims_setter_slice); // Dims
|
||||
|
||||
// Make it possible to use tuples/lists in Python in place of Dims.
|
||||
py::implicitly_convertible<std::vector<int64_t>, Dims>();
|
||||
|
||||
// 2D
|
||||
py::class_<Dims2, Dims>(m, "Dims2", Dims2Doc::descr, py::module_local())
|
||||
.def(py::init<>())
|
||||
.def(py::init<int64_t, int64_t>(), "dim0"_a, "dim1"_a)
|
||||
// Allows for construction from a tuple/list.
|
||||
.def(py::init(lambdas::dims2_vector_constructor), "shape"_a); // Dims2
|
||||
|
||||
py::implicitly_convertible<std::vector<int64_t>, Dims2>();
|
||||
|
||||
py::class_<DimsHW, Dims2>(m, "DimsHW", DimsHWDoc::descr, py::module_local())
|
||||
.def(py::init<>())
|
||||
.def(py::init<int64_t, int64_t>(), "h"_a, "w"_a)
|
||||
// Allows for construction from a tuple/list.
|
||||
.def(py::init(lambdas::dimshw_vector_constructor), "shape"_a)
|
||||
// Expose these functions as attributes in Python.
|
||||
.def_property(
|
||||
"h", [](DimsHW const& dims) { return dims.h(); }, [](DimsHW& dims, int64_t i) { dims.h() = i; })
|
||||
.def_property(
|
||||
"w", [](DimsHW const& dims) { return dims.w(); }, [](DimsHW& dims, int64_t i) { dims.w() = i; }); // DimsHW
|
||||
|
||||
py::implicitly_convertible<std::vector<int64_t>, DimsHW>();
|
||||
|
||||
// 3D
|
||||
py::class_<Dims3, Dims>(m, "Dims3", Dims3Doc::descr, py::module_local())
|
||||
.def(py::init<>())
|
||||
.def(py::init<int64_t, int64_t, int64_t>(), "dim0"_a, "dim1"_a, "dim2"_a)
|
||||
// Allows for construction from a tuple/list.
|
||||
.def(py::init(lambdas::dims3_vector_constructor), "shape"_a); // Dims3
|
||||
|
||||
py::implicitly_convertible<std::vector<int64_t>, Dims3>();
|
||||
|
||||
// 4D
|
||||
py::class_<Dims4, Dims>(m, "Dims4", Dims4Doc::descr, py::module_local())
|
||||
.def(py::init<>())
|
||||
.def(py::init<int64_t, int64_t, int64_t, int64_t>(), "dim0"_a, "dim1"_a, "dim2"_a, "dim3"_a)
|
||||
// Allows for construction from a tuple/list.
|
||||
.def(py::init(lambdas::dims4_vector_constructor), "shape"_a); // Dims4
|
||||
|
||||
py::implicitly_convertible<std::vector<int64_t>, Dims4>();
|
||||
|
||||
py::class_<IHostMemory>(m, "IHostMemory", py::buffer_protocol(), IHostMemoryDoc::descr, py::module_local())
|
||||
.def_property_readonly("dtype", [](IHostMemory const& mem) { return mem.type(); })
|
||||
.def_property_readonly("nbytes", [](IHostMemory const& mem) { return mem.size(); })
|
||||
// Expose buffer interface.
|
||||
.def_buffer(lambdas::host_memory_buffer_interface)
|
||||
.def("__del__", &utils::doNothingDel<IHostMemory>); // IHostMemory
|
||||
|
||||
py::class_<InterfaceInfo>(m, "InterfaceInfo", InterfaceInfoDoc::descr, py::module_local())
|
||||
.def_readwrite("kind", &InterfaceInfo::kind)
|
||||
.def_readwrite("major", &InterfaceInfo::major)
|
||||
.def_readwrite("minor", &InterfaceInfo::minor);
|
||||
|
||||
py::enum_<APILanguage>(m, "APILanguage", APILanguageDoc::descr, py::module_local())
|
||||
.value("CPP", APILanguage::kCPP)
|
||||
.value("PYTHON", APILanguage::kPYTHON);
|
||||
|
||||
py::class_<IVersionedInterface>(m, "IVersionedInterface", IVersionedInterfaceDoc::descr, py::module_local())
|
||||
.def_property_readonly("api_language", &IVersionedInterface::getAPILanguage)
|
||||
.def_property_readonly("interface_info", &IVersionedInterface::getInterfaceInfo);
|
||||
}
|
||||
|
||||
} // namespace tensorrt
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
|
||||
|
||||
# Note: This subdirectory is added multiple times, once for each binding library target.
|
||||
|
||||
# Indirectly call the current ADD_SOURCES_FUNCTION to populate target sources on the bindings lib that currently being setup.
|
||||
# The parser is only included by the full "tensorrt" or "tensorrt_rtx" binding module.
|
||||
if(${TRT_PYTHON_IS_FULL_BINDINGS})
|
||||
cmake_language(CALL ${ADD_SOURCES_FUNCTION}
|
||||
pyOnnx.cpp
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Implementation of PyBind11 Binding Code for OnnxParser
|
||||
#include "ForwardDeclarations.h"
|
||||
#include "NvOnnxParser.h"
|
||||
#include "parsers/pyOnnxDoc.h"
|
||||
#include "utils.h"
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl_bind.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace nvonnxparser;
|
||||
|
||||
namespace tensorrt
|
||||
{
|
||||
// Long lambda functions should go here rather than being inlined into the bindings (1 liners are OK).
|
||||
namespace lambdas
|
||||
{
|
||||
// NOLINTBEGIN(readability-identifier-naming)
|
||||
|
||||
static auto const parse = [](IParser& self, py::buffer const& model, char const* path = nullptr) {
|
||||
py::buffer_info info = model.request();
|
||||
|
||||
py::gil_scoped_release releaseGil{};
|
||||
return self.parse(info.ptr, info.size * info.itemsize, path);
|
||||
};
|
||||
|
||||
static auto const parseFromFile
|
||||
= [](IParser& self, std::string const& model) { return self.parseFromFile(model.c_str(), 0); };
|
||||
|
||||
static auto const supportsModelV2 = [](IParser& self, py::buffer const& model, char const* path = nullptr) {
|
||||
py::buffer_info info = model.request();
|
||||
return self.supportsModelV2(info.ptr, info.size * info.itemsize, path);
|
||||
};
|
||||
|
||||
static auto const isSubgraphSupported
|
||||
= [](IParser& self, int64_t const index) { return self.isSubgraphSupported(index); };
|
||||
|
||||
static auto const getSubgraphNodes = [](IParser& self, int64_t const index) {
|
||||
py::list py_nodes;
|
||||
int64_t nb_nodes = 0;
|
||||
int64_t* nodes = self.getSubgraphNodes(index, nb_nodes);
|
||||
for (int64_t i = 0; i < nb_nodes; i++)
|
||||
{
|
||||
py_nodes.append(nodes[i]);
|
||||
}
|
||||
return py_nodes;
|
||||
};
|
||||
|
||||
static auto const get_used_vc_plugin_libraries = [](IParser& self) {
|
||||
std::vector<std::string> vcPluginLibs;
|
||||
int64_t nbPluginLibs;
|
||||
auto libCArray = self.getUsedVCPluginLibraries(nbPluginLibs);
|
||||
if (nbPluginLibs < 0)
|
||||
{
|
||||
utils::throwPyError(PyExc_RuntimeError, "Internal error");
|
||||
}
|
||||
vcPluginLibs.reserve(nbPluginLibs);
|
||||
for (int64_t i = 0; i < nbPluginLibs; ++i)
|
||||
{
|
||||
vcPluginLibs.emplace_back(std::string{libCArray[i]});
|
||||
}
|
||||
return vcPluginLibs;
|
||||
};
|
||||
|
||||
static auto const pLoadModelProto = [](IParser& self, py::buffer const& model, char const* path = nullptr) {
|
||||
py::buffer_info info = model.request();
|
||||
return self.loadModelProto(info.ptr, info.size * info.itemsize, path);
|
||||
};
|
||||
|
||||
static auto const pLoadInitializer = [](IParser& self, std::string const& name, size_t const ptr, size_t const count) {
|
||||
return self.loadInitializer(name.c_str(), reinterpret_cast<void*>(ptr), count);
|
||||
};
|
||||
|
||||
static auto const get_local_function_stack = [](IParserError& self) {
|
||||
std::vector<std::string> localFunctionStack;
|
||||
int32_t localFunctionStackSize = self.localFunctionStackSize();
|
||||
if (localFunctionStackSize > 0)
|
||||
{
|
||||
auto localFunctionStackCArray = self.localFunctionStack();
|
||||
localFunctionStack.reserve(localFunctionStackSize);
|
||||
for (int32_t i = 0; i < localFunctionStackSize; ++i)
|
||||
{
|
||||
localFunctionStack.emplace_back(std::string{localFunctionStackCArray[i]});
|
||||
}
|
||||
}
|
||||
return localFunctionStack;
|
||||
};
|
||||
|
||||
static auto const refitFromBytes = [](IParserRefitter& self, py::buffer const& model, char const* path = nullptr) {
|
||||
py::buffer_info info = model.request();
|
||||
py::gil_scoped_release releaseGil{};
|
||||
return self.refitFromBytes(info.ptr, info.size * info.itemsize, path);
|
||||
};
|
||||
|
||||
static auto const refitFromFile
|
||||
= [](IParserRefitter& self, std::string const& model) { return self.refitFromFile(model.c_str()); };
|
||||
|
||||
static auto const rLoadModelProto = [](IParserRefitter& self, py::buffer const& model, char const* path = nullptr) {
|
||||
py::buffer_info info = model.request();
|
||||
return self.loadModelProto(info.ptr, info.size * info.itemsize, path);
|
||||
};
|
||||
|
||||
static auto const rLoadInitializer
|
||||
= [](IParserRefitter& self, std::string const& name, size_t const ptr, size_t const count) {
|
||||
return self.loadInitializer(name.c_str(), reinterpret_cast<void*>(ptr), count);
|
||||
};
|
||||
|
||||
// NOLINTEND(readability-identifier-naming)
|
||||
} // namespace lambdas
|
||||
|
||||
// Copies of functions from ONNX Parser code used for the Python Bindings.
|
||||
namespace pyonnx2trt
|
||||
{
|
||||
|
||||
inline char const* errorCodeStr(ErrorCode code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case ErrorCode::kSUCCESS: return "SUCCESS";
|
||||
case ErrorCode::kINTERNAL_ERROR: return "INTERNAL_ERROR";
|
||||
case ErrorCode::kMEM_ALLOC_FAILED: return "MEM_ALLOC_FAILED";
|
||||
case ErrorCode::kMODEL_DESERIALIZE_FAILED: return "MODEL_DESERIALIZE_FAILED";
|
||||
case ErrorCode::kINVALID_VALUE: return "INVALID_VALUE";
|
||||
case ErrorCode::kINVALID_GRAPH: return "INVALID_GRAPH";
|
||||
case ErrorCode::kINVALID_NODE: return "INVALID_NODE";
|
||||
case ErrorCode::kUNSUPPORTED_GRAPH: return "UNSUPPORTED_GRAPH";
|
||||
case ErrorCode::kUNSUPPORTED_NODE: return "UNSUPPORTED_NODE";
|
||||
case ErrorCode::kUNSUPPORTED_NODE_ATTR: return "UNSUPPORTED_NODE_ATTR";
|
||||
case ErrorCode::kUNSUPPORTED_NODE_INPUT: return "UNSUPPORTED_NODE_INPUT";
|
||||
case ErrorCode::kUNSUPPORTED_NODE_DATATYPE: return "UNSUPPORTED_NODE_DATATYPE";
|
||||
case ErrorCode::kUNSUPPORTED_NODE_DYNAMIC: return "UNSUPPORTED_NODE_DYNAMIC";
|
||||
case ErrorCode::kUNSUPPORTED_NODE_SHAPE: return "UNSUPPORTED_NODE_SHAPE";
|
||||
case ErrorCode::kREFIT_FAILED: return "REFIT_FAILED";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
inline std::string const parserErrorStr(nvonnxparser::IParserError const* error)
|
||||
{
|
||||
std::string const nodeInfo = "In node " + std::to_string(error->node()) + " with name: " + error->nodeName()
|
||||
+ " and operator: " + error->nodeOperator() + " ";
|
||||
std::string const errorInfo
|
||||
= std::string("(") + error->func() + "): " + errorCodeStr(error->code()) + ": " + error->desc();
|
||||
if (error->code() == ErrorCode::kMODEL_DESERIALIZE_FAILED || error->code() == ErrorCode::kREFIT_FAILED)
|
||||
{
|
||||
return errorInfo.c_str();
|
||||
}
|
||||
return (nodeInfo + errorInfo).c_str();
|
||||
}
|
||||
|
||||
} // namespace pyonnx2trt
|
||||
|
||||
void bindOnnx(py::module& m)
|
||||
{
|
||||
py::bind_vector<std::vector<size_t>>(m, "NodeIndices");
|
||||
|
||||
py::class_<IParser>(m, "OnnxParser", OnnxParserDoc::descr, py::module_local())
|
||||
// Use a lambda to force correct resolution. Pybind doesn't resolve noexcept factory methods correctly as
|
||||
// constructors. https://github.com/pybind/pybind11/issues/2856
|
||||
.def(py::init([](nvinfer1::INetworkDefinition& network, nvinfer1::ILogger& logger) {
|
||||
return nvonnxparser::createParser(network, logger);
|
||||
}),
|
||||
"network"_a, "logger"_a, OnnxParserDoc::init, py::keep_alive<1, 3>{}, py::keep_alive<2, 1>{})
|
||||
.def("parse", lambdas::parse, "model"_a, "path"_a = nullptr, OnnxParserDoc::parse)
|
||||
.def("parse_from_file", lambdas::parseFromFile, "model"_a, OnnxParserDoc::parse_from_file,
|
||||
py::call_guard<py::gil_scoped_release>{})
|
||||
.def("supports_operator", &IParser::supportsOperator, "op_name"_a, OnnxParserDoc::supports_operator)
|
||||
.def("supports_model_v2", lambdas::supportsModelV2, "model"_a, "path"_a = nullptr,
|
||||
OnnxParserDoc::supports_model_v2)
|
||||
.def_property_readonly("num_subgraphs", &IParser::getNbSubgraphs)
|
||||
.def("is_subgraph_supported", lambdas::isSubgraphSupported, "index"_a, OnnxParserDoc::is_subgraph_supported)
|
||||
.def("get_subgraph_nodes", lambdas::getSubgraphNodes, "index"_a, OnnxParserDoc::get_subgraph_nodes)
|
||||
.def_property_readonly("num_errors", &IParser::getNbErrors)
|
||||
.def("get_error", &IParser::getError, "index"_a, OnnxParserDoc::get_error)
|
||||
.def("clear_errors", &IParser::clearErrors, OnnxParserDoc::clear_errors)
|
||||
.def_property("flags", &IParser::getFlags, &IParser::setFlags)
|
||||
.def("clear_flag", &IParser::clearFlag, "flag"_a, OnnxParserDoc::clear_flag)
|
||||
.def("set_flag", &IParser::setFlag, "flag"_a, OnnxParserDoc::set_flag)
|
||||
.def("get_flag", &IParser::getFlag, "flag"_a, OnnxParserDoc::get_flag)
|
||||
.def("get_layer_output_tensor", &IParser::getLayerOutputTensor, "name"_a, "i"_a,
|
||||
OnnxParserDoc::get_layer_output_tensor)
|
||||
.def("get_used_vc_plugin_libraries", lambdas::get_used_vc_plugin_libraries,
|
||||
OnnxParserDoc::get_used_vc_plugin_libraries)
|
||||
.def("__del__", &utils::doNothingDel<IParser>)
|
||||
.def("load_model_proto", lambdas::pLoadModelProto, "model"_a, "path"_a = nullptr,
|
||||
OnnxParserDoc::load_model_proto, py::call_guard<py::gil_scoped_release>{})
|
||||
.def("load_initializer", lambdas::pLoadInitializer, "name"_a, "data"_a, "size"_a,
|
||||
OnnxParserDoc::load_initializer)
|
||||
.def("parse_model_proto", &IParser::parseModelProto, OnnxParserDoc::parse_model_proto)
|
||||
.def("set_builder_config", &IParser::setBuilderConfig, "builder_config"_a, OnnxParserDoc::set_builder_config,
|
||||
py::keep_alive<1, 2>{});
|
||||
|
||||
py::enum_<OnnxParserFlag>(m, "OnnxParserFlag", OnnxParserFlagDoc::descr, py::module_local())
|
||||
.value("NATIVE_INSTANCENORM", OnnxParserFlag::kNATIVE_INSTANCENORM, OnnxParserFlagDoc::NATIVE_INSTANCENORM)
|
||||
.value("ENABLE_UINT8_AND_ASYMMETRIC_QUANTIZATION_DLA",
|
||||
OnnxParserFlag::kENABLE_UINT8_AND_ASYMMETRIC_QUANTIZATION_DLA,
|
||||
OnnxParserFlagDoc::ENABLE_UINT8_AND_ASYMMETRIC_QUANTIZATION_DLA)
|
||||
.value(
|
||||
"REPORT_CAPABILITY_DLA", OnnxParserFlag::kREPORT_CAPABILITY_DLA, OnnxParserFlagDoc::REPORT_CAPABILITY_DLA)
|
||||
.value("ENABLE_PLUGIN_OVERRIDE", OnnxParserFlag::kENABLE_PLUGIN_OVERRIDE,
|
||||
OnnxParserFlagDoc::ENABLE_PLUGIN_OVERRIDE)
|
||||
.value("ADJUST_FOR_DLA", OnnxParserFlag::kADJUST_FOR_DLA, OnnxParserFlagDoc::ADJUST_FOR_DLA);
|
||||
|
||||
py::enum_<ErrorCode>(m, "ErrorCode", ErrorCodeDoc::descr, py::module_local())
|
||||
.value("SUCCESS", ErrorCode::kSUCCESS)
|
||||
.value("INTERNAL_ERROR", ErrorCode::kINTERNAL_ERROR)
|
||||
.value("MEM_ALLOC_FAILED", ErrorCode::kMEM_ALLOC_FAILED)
|
||||
.value("MODEL_DESERIALIZE_FAILED", ErrorCode::kMODEL_DESERIALIZE_FAILED)
|
||||
.value("INVALID_VALUE", ErrorCode::kINVALID_VALUE)
|
||||
.value("INVALID_GRAPH", ErrorCode::kINVALID_GRAPH)
|
||||
.value("INVALID_NODE", ErrorCode::kINVALID_NODE)
|
||||
.value("UNSUPPORTED_GRAPH", ErrorCode::kUNSUPPORTED_GRAPH)
|
||||
.value("UNSUPPORTED_NODE", ErrorCode::kUNSUPPORTED_NODE)
|
||||
.value("UNSUPPORTED_NODE_ATTR", ErrorCode::kUNSUPPORTED_NODE_ATTR)
|
||||
.value("UNSUPPORTED_NODE_INPUT", ErrorCode::kUNSUPPORTED_NODE_INPUT)
|
||||
.value("UNSUPPORTED_NODE_DATATYPE", ErrorCode::kUNSUPPORTED_NODE_DATATYPE)
|
||||
.value("UNSUPPORTED_NODE_DYNAMIC", ErrorCode::kUNSUPPORTED_NODE_DYNAMIC)
|
||||
.value("UNSUPPORTED_NODE_SHAPE", ErrorCode::kUNSUPPORTED_NODE_SHAPE)
|
||||
.value("REFIT_FAILED", ErrorCode::kREFIT_FAILED)
|
||||
.def("__str__", &pyonnx2trt::errorCodeStr)
|
||||
.def("__repr__", &pyonnx2trt::errorCodeStr);
|
||||
|
||||
py::class_<IParserError, std::unique_ptr<IParserError, py::nodelete>>(m, "ParserError", py::module_local())
|
||||
.def("code", &IParserError::code, ParserErrorDoc::code)
|
||||
.def("desc", &IParserError::desc, ParserErrorDoc::desc)
|
||||
.def("file", &IParserError::file, ParserErrorDoc::file)
|
||||
.def("line", &IParserError::line, ParserErrorDoc::line)
|
||||
.def("func", &IParserError::func, ParserErrorDoc::func)
|
||||
.def("node", &IParserError::node, ParserErrorDoc::node)
|
||||
.def("node_name", &IParserError::nodeName, ParserErrorDoc::node_name)
|
||||
.def("node_operator", &IParserError::nodeOperator, ParserErrorDoc::node_operator)
|
||||
.def("local_function_stack", lambdas::get_local_function_stack, ParserErrorDoc::local_function_stack)
|
||||
.def("local_function_stack_size", &IParserError::localFunctionStackSize,
|
||||
ParserErrorDoc::local_function_stack_size)
|
||||
.def("__str__", &pyonnx2trt::parserErrorStr)
|
||||
.def("__repr__", &pyonnx2trt::parserErrorStr);
|
||||
|
||||
py::class_<IParserRefitter>(m, "OnnxParserRefitter", OnnxParserRefitterDoc::descr, py::module_local())
|
||||
// Use a lambda to force correct resolution. Pybind doesn't resolve noexcept factory methods correctly as
|
||||
// constructors. https://github.com/pybind/pybind11/issues/2856
|
||||
.def(py::init([](nvinfer1::IRefitter& refitter, nvinfer1::ILogger& logger) {
|
||||
return nvonnxparser::createParserRefitter(refitter, logger);
|
||||
}),
|
||||
"refitter"_a, "logger"_a, OnnxParserRefitterDoc::init, py::keep_alive<1, 3>{}, py::keep_alive<2, 1>{})
|
||||
.def("refit_from_bytes", lambdas::refitFromBytes, "model"_a, "path"_a = nullptr,
|
||||
OnnxParserRefitterDoc::refit_from_bytes)
|
||||
.def("refit_from_file", lambdas::refitFromFile, "model"_a, OnnxParserRefitterDoc::refit_from_file,
|
||||
py::call_guard<py::gil_scoped_release>{})
|
||||
.def_property_readonly("num_errors", &IParserRefitter::getNbErrors)
|
||||
.def("get_error", &IParserRefitter::getError, "index"_a, OnnxParserRefitterDoc::get_error)
|
||||
.def("clear_errors", &IParserRefitter::clearErrors, OnnxParserRefitterDoc::clear_errors)
|
||||
.def("load_model_proto", lambdas::rLoadModelProto, "model"_a, "path"_a = nullptr,
|
||||
OnnxParserRefitterDoc::load_model_proto, py::call_guard<py::gil_scoped_release>{})
|
||||
.def("load_initializer", lambdas::rLoadInitializer, "name"_a, "data"_a, "size"_a,
|
||||
OnnxParserRefitterDoc::load_initializer)
|
||||
.def("refit_model_proto", &IParserRefitter::refitModelProto, OnnxParserRefitterDoc::refit_model_proto);
|
||||
|
||||
// Free functions.
|
||||
m.def("get_nv_onnx_parser_version", &getNvOnnxParserVersion, get_nv_onnx_parser_version);
|
||||
}
|
||||
} // namespace tensorrt
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 file contains top level bindings and defines the whole TRT Python package.
|
||||
#include "ForwardDeclarations.h"
|
||||
#include "NvInfer.h"
|
||||
#include "pyTensorRTDoc.h"
|
||||
#include <pybind11/stl_bind.h>
|
||||
|
||||
namespace tensorrt
|
||||
{
|
||||
PYBIND11_MODULE(TENSORRT_MODULE, m)
|
||||
{
|
||||
// Python strings can be automatically converted to FallbackStrings,
|
||||
// whose lifetime is tied to TRT objects that reference, but do not own, a string.
|
||||
// See ForwardDeclarations.h for more information about FallbackString.
|
||||
// Note that we cannot allow Python to deallocate this string, hence the py::nodelete.
|
||||
//
|
||||
// Important: *All* Python enum and class interfaces exported by this module *must* be
|
||||
// declared with py::module_local() scope, so that multiple TRT runtime modules
|
||||
// (e.g. tensorrt_lean and tensorrt_dispatch) may be imported by the same Python script
|
||||
// without conflicts.
|
||||
//
|
||||
// See https://pybind11.readthedocs.io/en/stable/advanced/classes.html#module-local-class-bindings
|
||||
// for more information.
|
||||
py::class_<FallbackString, std::unique_ptr<FallbackString, py::nodelete>>(m, "FallbackString", py::module_local())
|
||||
.def(py::init<std::string>())
|
||||
.def(py::init<py::str>());
|
||||
py::implicitly_convertible<std::string, FallbackString>();
|
||||
py::implicitly_convertible<py::str, FallbackString>();
|
||||
|
||||
// Make it so that we can use lists of PluginFields without creating unwanted copies.
|
||||
// This is declared opaque in ForwardDeclarations.h
|
||||
py::bind_vector<std::vector<nvinfer1::PluginField>>(m, "PluginFieldCollection");
|
||||
|
||||
// Order matters here - Dependencies must be resolved properly!
|
||||
// TODO: Maybe use actual forward declarations and define functions later.
|
||||
bindFoundationalTypes(m);
|
||||
bindPlugin(m);
|
||||
#if EXPORT_ALL_BINDINGS
|
||||
bindGraph(m);
|
||||
#endif
|
||||
bindCore(m);
|
||||
#if EXPORT_ALL_BINDINGS
|
||||
// Parsers
|
||||
bindOnnx(m);
|
||||
#endif
|
||||
}
|
||||
} // namespace tensorrt
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2025 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.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif // defined(WIN32_LEAN_AND_MEAN)
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#else // defined(_WIN32)
|
||||
#include <dlfcn.h>
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
namespace tensorrt
|
||||
{
|
||||
namespace utils
|
||||
{
|
||||
|
||||
void issueDeprecationWarning(char const* useInstead)
|
||||
{
|
||||
std::string msg{"Use " + std::string{useInstead} + " instead."};
|
||||
|
||||
py::gil_scoped_acquire acquire{};
|
||||
PyErr_WarnEx(PyExc_DeprecationWarning, msg.c_str(), 1);
|
||||
}
|
||||
|
||||
void* nvdllOpen(char const* libName)
|
||||
{
|
||||
std::ostringstream fullLibName;
|
||||
#if defined(_WIN32)
|
||||
fullLibName << "nv" << libName << ".dll";
|
||||
std::string strFullLibName = fullLibName.str();
|
||||
return static_cast<void*>(LoadLibraryA(strFullLibName.c_str()));
|
||||
#else // defined(_WIN32)
|
||||
fullLibName << "lib" << libName << ".so.1";
|
||||
std::string strFullLibName = fullLibName.str();
|
||||
return dlopen(strFullLibName.c_str(), RTLD_LAZY);
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
void dllClose(void* handle)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FreeLibrary(static_cast<HMODULE>(handle));
|
||||
#else // defined(_WIN32)
|
||||
dlclose(handle);
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
}
|
||||
|
||||
void* dllGetSym(void* handle, char const* name)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return GetProcAddress(static_cast<HMODULE>(handle), name);
|
||||
#else // defined(_WIN32)
|
||||
return dlsym(handle, name);
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
// Returns the size in bytes of the specified data type.
|
||||
size_t size(nvinfer1::DataType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case nvinfer1::DataType::kFLOAT: return 4;
|
||||
case nvinfer1::DataType::kHALF: return 2;
|
||||
case nvinfer1::DataType::kINT8: return 1;
|
||||
case nvinfer1::DataType::kINT32: return 4;
|
||||
case nvinfer1::DataType::kINT64: return 8;
|
||||
case nvinfer1::DataType::kBOOL: return 1;
|
||||
case nvinfer1::DataType::kUINT8: return 1;
|
||||
case nvinfer1::DataType::kFP8: return 1;
|
||||
case nvinfer1::DataType::kE8M0: return 1;
|
||||
case nvinfer1::DataType::kBF16: return 2;
|
||||
case nvinfer1::DataType::kINT4:
|
||||
case nvinfer1::DataType::kFP4: break; // TRT-22011 - need to address sub-byte element size
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::unique_ptr<py::dtype> nptype(nvinfer1::DataType type)
|
||||
{
|
||||
auto const makeDtype = [](char const* typeStr) { return std::make_unique<py::dtype>(typeStr); };
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case nvinfer1::DataType::kFLOAT: return makeDtype("f4");
|
||||
case nvinfer1::DataType::kHALF: return makeDtype("f2");
|
||||
case nvinfer1::DataType::kINT8: return makeDtype("i1");
|
||||
case nvinfer1::DataType::kINT32: return makeDtype("i4");
|
||||
case nvinfer1::DataType::kINT64: return makeDtype("i8");
|
||||
case nvinfer1::DataType::kBOOL: return makeDtype("b1");
|
||||
case nvinfer1::DataType::kUINT8: return makeDtype("u1");
|
||||
case nvinfer1::DataType::kFP8:
|
||||
case nvinfer1::DataType::kBF16:
|
||||
case nvinfer1::DataType::kINT4:
|
||||
case nvinfer1::DataType::kFP4:
|
||||
case nvinfer1::DataType::kE8M0: return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nvinfer1::DataType type(py::dtype const& type)
|
||||
{
|
||||
if (type.is(py::dtype("f4")))
|
||||
{
|
||||
return nvinfer1::DataType::kFLOAT;
|
||||
}
|
||||
else if (type.is(py::dtype("f2")))
|
||||
{
|
||||
return nvinfer1::DataType::kHALF;
|
||||
}
|
||||
else if (type.is(py::dtype("i8")))
|
||||
{
|
||||
return nvinfer1::DataType::kINT64;
|
||||
}
|
||||
else if (type.is(py::dtype("i4")))
|
||||
{
|
||||
return nvinfer1::DataType::kINT32;
|
||||
}
|
||||
else if (type.is(py::dtype("i1")))
|
||||
{
|
||||
return nvinfer1::DataType::kINT8;
|
||||
}
|
||||
else if (type.is(py::dtype("b1")))
|
||||
{
|
||||
return nvinfer1::DataType::kBOOL;
|
||||
}
|
||||
else if (type.is(py::dtype("u1")))
|
||||
{
|
||||
return nvinfer1::DataType::kUINT8;
|
||||
}
|
||||
int32_t constexpr kBITS_PER_BYTE{8};
|
||||
std::stringstream ss{};
|
||||
ss << "[TRT] [E] Could not implicitly convert NumPy data type: " << type.kind()
|
||||
<< (type.itemsize() * kBITS_PER_BYTE) << " to TensorRT.";
|
||||
std::cerr << ss.str() << std::endl;
|
||||
PY_ASSERT_VALUE_ERROR(false, ss.str());
|
||||
return nvinfer1::DataType::kFLOAT;
|
||||
}
|
||||
|
||||
void throwPyError(PyObject* type, std::string const& message)
|
||||
{
|
||||
PyErr_SetString(type, message.data());
|
||||
throw py::error_already_set();
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace tensorrt
|
||||
Reference in New Issue
Block a user