mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-29 20:14:01 +00:00
Cherry-picks for 1.16.1 release (#17741)
Cherry-pick the following PRs to the release branch: Fix: Fail to skip disabledmodel in winml (#17728) Move dotnet build and test into docker in Linux CPU CI (#17417) Run Nuget_Test_Linux_GPU in container (#17452) Run Final_Jar_Testing_Linux_GPU in docker (#17533) TreeEnsemble speed up (#17449) Remove onnxruntime extensions from list of gitmodules (#17615) Include onnxruntime_float16.h in the package. (#17637) Fix static quantization for QDQ and Percentile distribution (#17649) [TensorRT EP] Back out the PerThreadContext (#17690) Update nodejs to 18.x (#17657) Update linux-wasm-ci.yml: remove the ln command (#17735)
This commit is contained in:
parent
e7a0495a87
commit
264a7405e5
79 changed files with 14781 additions and 635 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -8,6 +8,3 @@
|
|||
path = cmake/external/emsdk
|
||||
url = https://github.com/emscripten-core/emsdk.git
|
||||
branch = 3.1.44
|
||||
[submodule "cmake/external/onnxruntime-extensions"]
|
||||
path = cmake/external/onnxruntime-extensions
|
||||
url = https://github.com/microsoft/onnxruntime-extensions.git
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.16.0
|
||||
1.16.1
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ For more information on ONNX Runtime, please see `aka.ms/onnxruntime <https://ak
|
|||
Changes
|
||||
-------
|
||||
|
||||
1.16.1
|
||||
^^^^^^
|
||||
|
||||
Release Notes : https://github.com/Microsoft/onnxruntime/releases/tag/v1.16.1
|
||||
|
||||
1.16.0
|
||||
^^^^^^
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
// This file is generated by /js/scripts/update-version.ts
|
||||
// Do not modify file content manually.
|
||||
|
||||
export const version = '1.16.0';
|
||||
export const version = '1.16.1';
|
||||
|
|
|
|||
4
js/common/package-lock.json
generated
4
js/common/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "onnxruntime-common",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "onnxruntime-common",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"typedoc": "^0.23.22"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"license": "MIT",
|
||||
"type": "module",
|
||||
"name": "onnxruntime-common",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"repository": {
|
||||
"url": "https://github.com/Microsoft/onnxruntime.git",
|
||||
"type": "git"
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
// This file is generated by /js/scripts/update-version.ts
|
||||
// Do not modify file content manually.
|
||||
|
||||
export const version = '1.16.0';
|
||||
export const version = '1.16.1';
|
||||
|
|
|
|||
6
js/node/package-lock.json
generated
6
js/node/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "onnxruntime-node",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "onnxruntime-node",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"license": "MIT",
|
||||
"os": [
|
||||
"win32",
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
},
|
||||
"../common": {
|
||||
"name": "onnxruntime-common",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"typedoc": "^0.23.22"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
3
|
||||
]
|
||||
},
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"dependencies": {
|
||||
"onnxruntime-common": "file:../common"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -66,12 +66,14 @@ class OnnxruntimeSessionHandler implements SessionHandler {
|
|||
let results: Binding.ModelLoadInfoType;
|
||||
// load a model
|
||||
if (typeof this.#pathOrBuffer === 'string') {
|
||||
// load model from model path
|
||||
results = await this.#inferenceSession.loadModel(normalizePath(this.#pathOrBuffer), options);
|
||||
} else {
|
||||
// load model from buffer
|
||||
if (!this.#inferenceSession.loadModelFromBlob) {
|
||||
throw new Error('Native module method "loadModelFromBlob" is not defined');
|
||||
}
|
||||
const modelBlob = jsiHelper.storeArrayBuffer(this.#pathOrBuffer);
|
||||
const modelBlob = jsiHelper.storeArrayBuffer(this.#pathOrBuffer.buffer);
|
||||
results = await this.#inferenceSession.loadModelFromBlob(modelBlob, options);
|
||||
}
|
||||
// resolve promise if onnxruntime session is successfully created
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
// This file is generated by /js/scripts/update-version.ts
|
||||
// Do not modify file content manually.
|
||||
|
||||
export const version = '1.16.0';
|
||||
export const version = '1.16.1';
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
"registry": "https://registry.npmjs.org/"
|
||||
},
|
||||
"source": "lib/index",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"main": "dist/commonjs/index",
|
||||
"homepage": "https://github.com/microsoft/onnxruntime/blob/main/js/react_native/README.md",
|
||||
"files": [
|
||||
|
|
|
|||
|
|
@ -5188,7 +5188,7 @@ onetime@^5.1.0, onetime@^5.1.2:
|
|||
mimic-fn "^2.1.0"
|
||||
|
||||
"onnxruntime-common@file:../common":
|
||||
version "1.16.0"
|
||||
version "1.16.1"
|
||||
|
||||
open@^6.2.0:
|
||||
version "6.4.0"
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
// This file is generated by /js/scripts/update-version.ts
|
||||
// Do not modify file content manually.
|
||||
|
||||
export const version = '1.16.0';
|
||||
export const version = '1.16.1';
|
||||
|
|
|
|||
6
js/web/package-lock.json
generated
6
js/web/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "onnxruntime-web",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "onnxruntime-web",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"flatbuffers": "^1.12.0",
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
},
|
||||
"../common": {
|
||||
"name": "onnxruntime-common",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"typedoc": "^0.23.22"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
"type": "git"
|
||||
},
|
||||
"author": "fs-eire",
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"jsdelivr": "dist/ort.min.js",
|
||||
"dependencies": {
|
||||
"flatbuffers": "^1.12.0",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ ONNX Runtime is a performance-focused scoring engine for Open Neural Network Exc
|
|||
For more information on ONNX Runtime, please see `aka.ms/onnxruntime <https://aka.ms/onnxruntime/>`_
|
||||
or the `Github project <https://github.com/microsoft/onnxruntime/>`_.
|
||||
"""
|
||||
__version__ = "1.16.0"
|
||||
__version__ = "1.16.1"
|
||||
__author__ = "Microsoft"
|
||||
|
||||
# we need to do device version validation (for example to check Cuda version for an onnxruntime-training package).
|
||||
|
|
|
|||
|
|
@ -140,27 +140,29 @@ Status Attention<T>::ComputeInternal(OpKernelContext* context) const {
|
|||
#endif
|
||||
|
||||
if (!use_flash_attention) {
|
||||
if (is_unidirectional_ && enable_fused_causal_attention_) { // GPT
|
||||
// GPT fused kernels requires left side padding. mask can be:
|
||||
// none (no padding), 1D sequence lengths or 2d mask.
|
||||
// Fused kernels don't support different sequence lengths of q and kv, so only apply to the first token
|
||||
// where past state is empty.
|
||||
bool is_mask_2d_key_padding = parameters.mask_type == AttentionMaskType::MASK_2D_KEY_PADDING;
|
||||
bool use_causal_fused_runner = (nullptr == mask_index || is_mask_1d_seq_len || is_mask_2d_key_padding) &&
|
||||
nullptr == relative_position_bias &&
|
||||
parameters.past_sequence_length == 0 &&
|
||||
parameters.hidden_size == parameters.v_hidden_size &&
|
||||
FusedMHARunnerFP16v2::is_supported(sm, parameters.head_size, sequence_length,
|
||||
enable_trt_flash_attention_, true);
|
||||
if (use_causal_fused_runner) {
|
||||
// Here we assume that num_heads, head_size and is_unidirectional does not change for an Attention node.
|
||||
if (nullptr == fused_fp16_runner_.get()) {
|
||||
fused_fp16_runner_ = FusedMHARunnerFP16v2::Create(num_heads_, parameters.head_size, sm, is_unidirectional_,
|
||||
enable_trt_flash_attention_, parameters.scale);
|
||||
}
|
||||
if (is_unidirectional_) { // GPT
|
||||
if (enable_fused_causal_attention_) {
|
||||
// GPT fused kernels requires left side padding. mask can be:
|
||||
// none (no padding), 1D sequence lengths or 2d mask.
|
||||
// Fused kernels don't support different sequence lengths of q and kv, so only apply to the first token
|
||||
// where past state is empty.
|
||||
bool is_mask_2d_key_padding = parameters.mask_type == AttentionMaskType::MASK_2D_KEY_PADDING;
|
||||
bool use_causal_fused_runner = (nullptr == mask_index || is_mask_1d_seq_len || is_mask_2d_key_padding) &&
|
||||
nullptr == relative_position_bias &&
|
||||
parameters.past_sequence_length == 0 &&
|
||||
parameters.hidden_size == parameters.v_hidden_size &&
|
||||
FusedMHARunnerFP16v2::is_supported(sm, parameters.head_size, sequence_length,
|
||||
enable_trt_flash_attention_, true);
|
||||
if (use_causal_fused_runner) {
|
||||
// Here we assume that num_heads, head_size and is_unidirectional does not change for an Attention node.
|
||||
if (nullptr == fused_fp16_runner_.get()) {
|
||||
fused_fp16_runner_ = FusedMHARunnerFP16v2::Create(num_heads_, parameters.head_size, sm, is_unidirectional_,
|
||||
enable_trt_flash_attention_, parameters.scale);
|
||||
}
|
||||
|
||||
// Here we assume all causal kernels can be loaded into shared memory. TODO: add a function to check.
|
||||
fused_runner = fused_fp16_runner_.get();
|
||||
// Here we assume all causal kernels can be loaded into shared memory. TODO: add a function to check.
|
||||
fused_runner = fused_fp16_runner_.get();
|
||||
}
|
||||
}
|
||||
} else { // BERT
|
||||
bool use_fused_runner = !disable_fused_self_attention_ &&
|
||||
|
|
|
|||
|
|
@ -64,6 +64,18 @@ enum MissingTrack : uint8_t {
|
|||
kFalse = 0
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TreeNodeElement;
|
||||
|
||||
template <typename T>
|
||||
union PtrOrWeight {
|
||||
TreeNodeElement<T>* ptr;
|
||||
struct WeightData {
|
||||
int32_t weight;
|
||||
int32_t n_weights;
|
||||
} weight_data;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TreeNodeElement {
|
||||
int feature_id;
|
||||
|
|
@ -71,24 +83,19 @@ struct TreeNodeElement {
|
|||
// Stores the node threshold or the weights if the tree has one target.
|
||||
T value_or_unique_weight;
|
||||
|
||||
// onnx specification says hitrates is used to store information about the node,
|
||||
// The onnx specification says hitrates is used to store information about the node,
|
||||
// but this information is not used for inference.
|
||||
// T hitrates;
|
||||
|
||||
// True node, false node are obtained by computing `this + truenode_inc_or_first_weight`,
|
||||
// `this + falsenode_inc_or_n_weights` if the node is not a leaf.
|
||||
// In case of a leaf, these attributes are used to indicate the position of the weight
|
||||
// in array `TreeEnsembleCommon::weights_`. If the number of targets or classes is one,
|
||||
// the weight is also stored in `value_or_unique_weight`.
|
||||
// This implementation assumes a tree has less than 2^31 nodes,
|
||||
// and the total number of leave in the set of trees is below 2^31.
|
||||
// A node cannot point to itself.
|
||||
int32_t truenode_inc_or_first_weight;
|
||||
// In case of a leaf, the following attribute indicates the number of weights
|
||||
// in array `TreeEnsembleCommon::weights_`. If not a leaf, it indicates
|
||||
// `this + falsenode_inc_or_n_weights` is the false node.
|
||||
// A node cannot point to itself.
|
||||
int32_t falsenode_inc_or_n_weights;
|
||||
// PtrOrWeight acts as a tagged union, with the "tag" being whether the node is a leaf or not (see `is_not_leaf`).
|
||||
|
||||
// If it is not a leaf, it is a pointer to the true child node when traversing the decision tree. The false branch is
|
||||
// always 1 position away from the TreeNodeElement in practice in `TreeEnsembleCommon::nodes_` so it is not stored.
|
||||
|
||||
// If it is a leaf, it contains `weight` and `n_weights` attributes which are used to indicate the position of the
|
||||
// weight in array `TreeEnsembleCommon::weights_`. If the number of targets or classes is one, the weight is also
|
||||
// stored in `value_or_unique_weight`.
|
||||
PtrOrWeight<T> truenode_or_weight;
|
||||
uint8_t flags;
|
||||
|
||||
inline NODE_MODE mode() const { return NODE_MODE(flags & 0xF); }
|
||||
|
|
@ -189,8 +196,8 @@ class TreeAggregatorSum : public TreeAggregator<InputType, ThresholdType, Output
|
|||
void ProcessTreeNodePrediction(InlinedVector<ScoreValue<ThresholdType>>& predictions,
|
||||
const TreeNodeElement<ThresholdType>& root,
|
||||
gsl::span<const SparseValue<ThresholdType>> weights) const {
|
||||
auto it = weights.begin() + root.truenode_inc_or_first_weight;
|
||||
for (int32_t i = 0; i < root.falsenode_inc_or_n_weights; ++i, ++it) {
|
||||
auto it = weights.begin() + root.truenode_or_weight.weight_data.weight;
|
||||
for (int32_t i = 0; i < root.truenode_or_weight.weight_data.n_weights; ++i, ++it) {
|
||||
ORT_ENFORCE(it->i < (int64_t)predictions.size());
|
||||
predictions[onnxruntime::narrow<size_t>(it->i)].score += it->value;
|
||||
predictions[onnxruntime::narrow<size_t>(it->i)].has_score = 1;
|
||||
|
|
@ -292,8 +299,8 @@ class TreeAggregatorMin : public TreeAggregator<InputType, ThresholdType, Output
|
|||
void ProcessTreeNodePrediction(InlinedVector<ScoreValue<ThresholdType>>& predictions,
|
||||
const TreeNodeElement<ThresholdType>& root,
|
||||
gsl::span<const SparseValue<ThresholdType>> weights) const {
|
||||
auto it = weights.begin() + root.truenode_inc_or_first_weight;
|
||||
for (int32_t i = 0; i < root.falsenode_inc_or_n_weights; ++i, ++it) {
|
||||
auto it = weights.begin() + root.truenode_or_weight.weight_data.weight;
|
||||
for (int32_t i = 0; i < root.truenode_or_weight.weight_data.n_weights; ++i, ++it) {
|
||||
predictions[onnxruntime::narrow<size_t>(it->i)].score =
|
||||
(!predictions[onnxruntime::narrow<size_t>(it->i)].has_score || it->value < predictions[onnxruntime::narrow<size_t>(it->i)].score)
|
||||
? it->value
|
||||
|
|
@ -349,8 +356,8 @@ class TreeAggregatorMax : public TreeAggregator<InputType, ThresholdType, Output
|
|||
void ProcessTreeNodePrediction(InlinedVector<ScoreValue<ThresholdType>>& predictions,
|
||||
const TreeNodeElement<ThresholdType>& root,
|
||||
gsl::span<const SparseValue<ThresholdType>> weights) const {
|
||||
auto it = weights.begin() + root.truenode_inc_or_first_weight;
|
||||
for (int32_t i = 0; i < root.falsenode_inc_or_n_weights; ++i, ++it) {
|
||||
auto it = weights.begin() + root.truenode_or_weight.weight_data.weight;
|
||||
for (int32_t i = 0; i < root.truenode_or_weight.weight_data.n_weights; ++i, ++it) {
|
||||
predictions[onnxruntime::narrow<size_t>(it->i)].score =
|
||||
(!predictions[onnxruntime::narrow<size_t>(it->i)].has_score || it->value > predictions[onnxruntime::narrow<size_t>(it->i)].score)
|
||||
? it->value
|
||||
|
|
|
|||
|
|
@ -85,6 +85,13 @@ class TreeEnsembleCommon : public TreeEnsembleCommonAttributes {
|
|||
|
||||
template <typename AGG>
|
||||
void ComputeAgg(concurrency::ThreadPool* ttp, const Tensor* X, Tensor* Y, Tensor* label, const AGG& agg) const;
|
||||
|
||||
private:
|
||||
size_t AddNodes(const size_t i, const InlinedVector<NODE_MODE>& cmodes, const InlinedVector<size_t>& truenode_ids,
|
||||
const InlinedVector<size_t>& falsenode_ids, const std::vector<int64_t>& nodes_featureids,
|
||||
const std::vector<ThresholdType>& nodes_values_as_tensor, const std::vector<float>& node_values,
|
||||
const std::vector<int64_t>& nodes_missing_value_tracks_true, std::vector<size_t>& updated_mapping,
|
||||
int64_t tree_id, const InlinedVector<TreeNodeElementId>& node_tree_ids);
|
||||
};
|
||||
|
||||
template <typename InputType, typename ThresholdType, typename OutputType>
|
||||
|
|
@ -186,7 +193,7 @@ Status TreeEnsembleCommon<InputType, ThresholdType, OutputType>::Init(
|
|||
max_tree_depth_ = 1000;
|
||||
ORT_ENFORCE(nodes_modes.size() < std::numeric_limits<uint32_t>::max());
|
||||
|
||||
// additional members
|
||||
// Additional members
|
||||
size_t limit;
|
||||
uint32_t i;
|
||||
InlinedVector<NODE_MODE> cmodes;
|
||||
|
|
@ -195,18 +202,14 @@ Status TreeEnsembleCommon<InputType, ThresholdType, OutputType>::Init(
|
|||
int fpos = -1;
|
||||
for (i = 0, limit = nodes_modes.size(); i < limit; ++i) {
|
||||
cmodes.push_back(MakeTreeNodeMode(nodes_modes[i]));
|
||||
if (cmodes[i] == NODE_MODE::LEAF)
|
||||
continue;
|
||||
if (cmodes[i] == NODE_MODE::LEAF) continue;
|
||||
if (fpos == -1) {
|
||||
fpos = static_cast<int>(i);
|
||||
continue;
|
||||
}
|
||||
if (cmodes[i] != cmodes[fpos])
|
||||
same_mode_ = false;
|
||||
if (cmodes[i] != cmodes[fpos]) same_mode_ = false;
|
||||
}
|
||||
|
||||
// filling nodes
|
||||
|
||||
n_nodes_ = nodes_treeids.size();
|
||||
limit = static_cast<size_t>(n_nodes_);
|
||||
InlinedVector<TreeNodeElementId> node_tree_ids;
|
||||
|
|
@ -214,156 +217,185 @@ Status TreeEnsembleCommon<InputType, ThresholdType, OutputType>::Init(
|
|||
nodes_.clear();
|
||||
nodes_.reserve(limit);
|
||||
roots_.clear();
|
||||
std::unordered_map<TreeNodeElementId, uint32_t, TreeNodeElementId::hash_fn> idi;
|
||||
idi.reserve(limit);
|
||||
std::unordered_map<TreeNodeElementId, size_t, TreeNodeElementId::hash_fn> node_tree_ids_map;
|
||||
node_tree_ids_map.reserve(limit);
|
||||
|
||||
InlinedVector<size_t> truenode_ids, falsenode_ids;
|
||||
truenode_ids.reserve(limit);
|
||||
falsenode_ids.reserve(limit);
|
||||
max_feature_id_ = 0;
|
||||
|
||||
// Build node_tree_ids and node_tree_ids_map and truenode_ids and falsenode_ids
|
||||
for (i = 0; i < limit; ++i) {
|
||||
TreeNodeElementId node_tree_id{static_cast<int>(nodes_treeids[i]),
|
||||
static_cast<int>(nodes_nodeids[i])};
|
||||
TreeNodeElement<ThresholdType> node;
|
||||
node.feature_id = static_cast<int>(nodes_featureids[i]);
|
||||
if (node.feature_id > max_feature_id_) {
|
||||
max_feature_id_ = node.feature_id;
|
||||
}
|
||||
node.value_or_unique_weight = nodes_values_as_tensor.empty()
|
||||
? static_cast<ThresholdType>(nodes_values[i])
|
||||
: nodes_values_as_tensor[i];
|
||||
|
||||
/* hitrates is not used for inference, they are ignored.
|
||||
if (nodes_hitrates_as_tensor.empty()) {
|
||||
node.hitrates = static_cast<ThresholdType>(i < nodes_hitrates.size() ? nodes_hitrates[i] : -1);
|
||||
} else {
|
||||
node.hitrates = i < nodes_hitrates_as_tensor.size() ? nodes_hitrates_as_tensor[i] : -1;
|
||||
} */
|
||||
|
||||
node.flags = static_cast<uint8_t>(cmodes[i]);
|
||||
node.truenode_inc_or_first_weight = 0; // nodes_truenodeids[i] if not a leaf
|
||||
node.falsenode_inc_or_n_weights = 0; // nodes_falsenodeids[i] if not a leaf
|
||||
|
||||
if (i < static_cast<size_t>(nodes_missing_value_tracks_true.size()) && nodes_missing_value_tracks_true[i] == 1) {
|
||||
node.flags |= static_cast<uint8_t>(MissingTrack::kTrue);
|
||||
}
|
||||
auto p = idi.insert(std::pair<TreeNodeElementId, uint32_t>(node_tree_id, i));
|
||||
TreeNodeElementId node_tree_id{static_cast<int>(nodes_treeids[i]), static_cast<int>(nodes_nodeids[i])};
|
||||
auto p = node_tree_ids_map.insert(std::pair<TreeNodeElementId, size_t>(node_tree_id, i));
|
||||
if (!p.second) {
|
||||
ORT_THROW("Node ", node_tree_id.node_id, " in tree ", node_tree_id.tree_id, " is already there.");
|
||||
}
|
||||
nodes_.emplace_back(node);
|
||||
node_tree_ids.emplace_back(node_tree_id);
|
||||
}
|
||||
|
||||
InlinedVector<int64_t> truenode_ids, falsenode_ids;
|
||||
truenode_ids.reserve(limit);
|
||||
falsenode_ids.reserve(limit);
|
||||
TreeNodeElementId coor;
|
||||
i = 0;
|
||||
for (auto it = nodes_.begin(); it != nodes_.end(); ++it, ++i) {
|
||||
if (!it->is_not_leaf()) {
|
||||
for (i = 0; i < limit; ++i) {
|
||||
if (cmodes[i] == NODE_MODE::LEAF) {
|
||||
truenode_ids.push_back(0);
|
||||
falsenode_ids.push_back(0);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
TreeNodeElementId& node_tree_id = node_tree_ids[i];
|
||||
coor.tree_id = node_tree_id.tree_id;
|
||||
coor.node_id = static_cast<int>(nodes_truenodeids[i]);
|
||||
ORT_ENFORCE((coor.node_id >= 0 && coor.node_id < n_nodes_));
|
||||
|
||||
TreeNodeElementId& node_tree_id = node_tree_ids[i];
|
||||
coor.tree_id = node_tree_id.tree_id;
|
||||
coor.node_id = static_cast<int>(nodes_truenodeids[i]);
|
||||
ORT_ENFORCE((coor.node_id >= 0 && coor.node_id < n_nodes_));
|
||||
auto found = node_tree_ids_map.find(coor);
|
||||
if (found == node_tree_ids_map.end()) {
|
||||
ORT_THROW("Unable to find node ", coor.tree_id, "-", coor.node_id, " (truenode).");
|
||||
}
|
||||
if (found->second == truenode_ids.size()) {
|
||||
ORT_THROW("A node cannot point to itself: ", coor.tree_id, "-", node_tree_id.node_id, " (truenode).");
|
||||
}
|
||||
truenode_ids.emplace_back(found->second);
|
||||
|
||||
auto found = idi.find(coor);
|
||||
if (found == idi.end()) {
|
||||
ORT_THROW("Unable to find node ", coor.tree_id, "-", coor.node_id, " (truenode).");
|
||||
coor.node_id = static_cast<int>(nodes_falsenodeids[i]);
|
||||
ORT_ENFORCE((coor.node_id >= 0 && coor.node_id < n_nodes_));
|
||||
found = node_tree_ids_map.find(coor);
|
||||
if (found == node_tree_ids_map.end()) {
|
||||
ORT_THROW("Unable to find node ", coor.tree_id, "-", coor.node_id, " (falsenode).");
|
||||
}
|
||||
if (found->second == falsenode_ids.size()) {
|
||||
ORT_THROW("A node cannot point to itself: ", coor.tree_id, "-", node_tree_id.node_id, " (falsenode).");
|
||||
}
|
||||
falsenode_ids.emplace_back(found->second);
|
||||
// We could also check that truenode_ids[truenode_ids.size() - 1] != falsenode_ids[falsenode_ids.size() - 1]).
|
||||
// It is valid but no training algorithm would produce a tree where left and right nodes are the same.
|
||||
}
|
||||
if (found->second == truenode_ids.size()) {
|
||||
ORT_THROW("A node cannot point to itself: ", coor.tree_id, "-", node_tree_id.node_id, " (truenode).");
|
||||
}
|
||||
truenode_ids.emplace_back(found->second);
|
||||
|
||||
coor.node_id = static_cast<int>(nodes_falsenodeids[i]);
|
||||
ORT_ENFORCE((coor.node_id >= 0 && coor.node_id < n_nodes_));
|
||||
found = idi.find(coor);
|
||||
if (found == idi.end()) {
|
||||
ORT_THROW("Unable to find node ", coor.tree_id, "-", coor.node_id, " (falsenode).");
|
||||
}
|
||||
if (found->second == falsenode_ids.size()) {
|
||||
ORT_THROW("A node cannot point to itself: ", coor.tree_id, "-", node_tree_id.node_id, " (falsenode).");
|
||||
}
|
||||
falsenode_ids.emplace_back(found->second);
|
||||
// We could also check that truenode_ids[truenode_ids.size() - 1] != falsenode_ids[falsenode_ids.size() - 1]).
|
||||
// It is valid but no training algorithm would produce a tree where left and right nodes are the same.
|
||||
}
|
||||
|
||||
// sort targets
|
||||
// Let's construct nodes_ such that the false branch is always the next element in nodes_.
|
||||
// updated_mapping will translates the old position of each node to the new node position in nodes_.
|
||||
std::vector<size_t> updated_mapping(nodes_treeids.size(), 0);
|
||||
int64_t previous_tree_id = -1;
|
||||
for (i = 0; i < n_nodes_; ++i) {
|
||||
if (previous_tree_id == -1 || (previous_tree_id != node_tree_ids[i].tree_id)) {
|
||||
// New tree.
|
||||
int64_t tree_id = node_tree_ids[i].tree_id;
|
||||
size_t root_position =
|
||||
AddNodes(i, cmodes, truenode_ids, falsenode_ids, nodes_featureids, nodes_values_as_tensor, nodes_values,
|
||||
nodes_missing_value_tracks_true, updated_mapping, tree_id, node_tree_ids);
|
||||
roots_.push_back(&nodes_[root_position]);
|
||||
previous_tree_id = tree_id;
|
||||
}
|
||||
}
|
||||
|
||||
n_trees_ = roots_.size();
|
||||
if (((int64_t)nodes_.size()) != n_nodes_) {
|
||||
ORT_THROW("Number of nodes in nodes_ (", nodes_.size(), ") is different from n_nodes (", n_nodes_, ").");
|
||||
}
|
||||
|
||||
// Sort targets
|
||||
InlinedVector<std::pair<TreeNodeElementId, uint32_t>> indices;
|
||||
indices.reserve(target_class_nodeids.size());
|
||||
for (i = 0, limit = target_class_nodeids.size(); i < limit; i++) {
|
||||
indices.emplace_back(std::pair<TreeNodeElementId, uint32_t>(
|
||||
TreeNodeElementId{target_class_treeids[i], target_class_nodeids[i]},
|
||||
i));
|
||||
indices.emplace_back(
|
||||
std::pair<TreeNodeElementId, uint32_t>(TreeNodeElementId{target_class_treeids[i], target_class_nodeids[i]}, i));
|
||||
}
|
||||
|
||||
std::sort(indices.begin(), indices.end());
|
||||
|
||||
// Initialize the leaves.
|
||||
TreeNodeElementId ind;
|
||||
SparseValue<ThresholdType> w;
|
||||
size_t indi;
|
||||
for (indi = 0, limit = target_class_nodeids.size(); indi < limit; ++indi) {
|
||||
ind = indices[indi].first;
|
||||
i = indices[indi].second;
|
||||
auto found = idi.find(ind);
|
||||
if (found == idi.end()) {
|
||||
auto found = node_tree_ids_map.find(ind);
|
||||
if (found == node_tree_ids_map.end()) {
|
||||
ORT_THROW("Unable to find node ", ind.tree_id, "-", ind.node_id, " (weights).");
|
||||
}
|
||||
|
||||
TreeNodeElement<ThresholdType>& leaf = nodes_[found->second];
|
||||
TreeNodeElement<ThresholdType>& leaf = nodes_[updated_mapping[found->second]];
|
||||
if (leaf.is_not_leaf()) {
|
||||
// An exception should be raised in that case. But this case may happen in
|
||||
// models converted with an old version of onnxmltools. These weights are ignored.
|
||||
// ORT_THROW("Node ", ind.tree_id, "-", ind.node_id, " is not a leaf.");
|
||||
continue;
|
||||
}
|
||||
|
||||
w.i = target_class_ids[i];
|
||||
w.value = target_class_weights_as_tensor.empty()
|
||||
? static_cast<ThresholdType>(target_class_weights[i])
|
||||
: target_class_weights_as_tensor[i];
|
||||
if (leaf.falsenode_inc_or_n_weights == 0) {
|
||||
leaf.truenode_inc_or_first_weight = static_cast<int32_t>(weights_.size());
|
||||
w.value = target_class_weights_as_tensor.empty() ? static_cast<ThresholdType>(target_class_weights[i])
|
||||
: target_class_weights_as_tensor[i];
|
||||
if (leaf.truenode_or_weight.weight_data.n_weights == 0) {
|
||||
leaf.truenode_or_weight.weight_data.weight = static_cast<int32_t>(weights_.size());
|
||||
leaf.value_or_unique_weight = w.value;
|
||||
}
|
||||
++leaf.falsenode_inc_or_n_weights;
|
||||
++leaf.truenode_or_weight.weight_data.n_weights;
|
||||
weights_.push_back(w);
|
||||
}
|
||||
|
||||
// Initialize all the nodes but the leaves.
|
||||
int64_t previous = -1;
|
||||
for (i = 0, limit = static_cast<uint32_t>(n_nodes_); i < limit; ++i) {
|
||||
if ((previous == -1) || (previous != node_tree_ids[i].tree_id))
|
||||
roots_.push_back(&(nodes_[idi[node_tree_ids[i]]]));
|
||||
previous = node_tree_ids[i].tree_id;
|
||||
if (!nodes_[i].is_not_leaf()) {
|
||||
if (nodes_[i].falsenode_inc_or_n_weights == 0) {
|
||||
ORT_THROW("Target is missing for leaf ", ind.tree_id, "-", ind.node_id, ".");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ORT_ENFORCE(truenode_ids[i] != i); // That would mean the left node is itself, leading to an infinite loop.
|
||||
nodes_[i].truenode_inc_or_first_weight = static_cast<int32_t>(truenode_ids[i] - i);
|
||||
ORT_ENFORCE(falsenode_ids[i] != i); // That would mean the right node is itself, leading to an infinite loop.
|
||||
nodes_[i].falsenode_inc_or_n_weights = static_cast<int32_t>(falsenode_ids[i] - i);
|
||||
}
|
||||
|
||||
n_trees_ = roots_.size();
|
||||
has_missing_tracks_ = false;
|
||||
for (auto itm = nodes_missing_value_tracks_true.begin();
|
||||
itm != nodes_missing_value_tracks_true.end(); ++itm) {
|
||||
for (auto itm = nodes_missing_value_tracks_true.begin(); itm != nodes_missing_value_tracks_true.end(); ++itm) {
|
||||
if (*itm) {
|
||||
has_missing_tracks_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
template <typename InputType, typename ThresholdType, typename OutputType>
|
||||
size_t TreeEnsembleCommon<InputType, ThresholdType, OutputType>::AddNodes(
|
||||
const size_t i, const InlinedVector<NODE_MODE>& cmodes, const InlinedVector<size_t>& truenode_ids,
|
||||
const InlinedVector<size_t>& falsenode_ids, const std::vector<int64_t>& nodes_featureids,
|
||||
const std::vector<ThresholdType>& nodes_values_as_tensor, const std::vector<float>& node_values,
|
||||
const std::vector<int64_t>& nodes_missing_value_tracks_true, std::vector<size_t>& updated_mapping, int64_t tree_id,
|
||||
const InlinedVector<TreeNodeElementId>& node_tree_ids) {
|
||||
// Validate this index maps to the same tree_id as the one we should be building.
|
||||
if (node_tree_ids[i].tree_id != tree_id) {
|
||||
ORT_THROW("Tree id mismatch. Expected ", tree_id, " but got ", node_tree_ids[i].tree_id, " at position ", i);
|
||||
}
|
||||
|
||||
if (updated_mapping[i] != 0) {
|
||||
// In theory we should not accept any cycles, however in practice LGBM conversion implements set membership via a
|
||||
// series of "Equals" nodes, with the true branches directed at the same child node (a cycle).
|
||||
// We may instead seek to formalize set membership in the future.
|
||||
return updated_mapping[i];
|
||||
}
|
||||
|
||||
size_t node_pos = nodes_.size();
|
||||
updated_mapping[i] = node_pos;
|
||||
|
||||
TreeNodeElement<ThresholdType> node;
|
||||
node.flags = static_cast<uint8_t>(cmodes[i]);
|
||||
node.feature_id = static_cast<int>(nodes_featureids[i]);
|
||||
if (node.feature_id > max_feature_id_) {
|
||||
max_feature_id_ = node.feature_id;
|
||||
}
|
||||
node.value_or_unique_weight =
|
||||
nodes_values_as_tensor.empty() ? static_cast<ThresholdType>(node_values[i]) : nodes_values_as_tensor[i];
|
||||
if (i < static_cast<size_t>(nodes_missing_value_tracks_true.size()) && nodes_missing_value_tracks_true[i] == 1) {
|
||||
node.flags |= static_cast<uint8_t>(MissingTrack::kTrue);
|
||||
}
|
||||
nodes_.push_back(std::move(node));
|
||||
if (nodes_[node_pos].is_not_leaf()) {
|
||||
size_t false_branch =
|
||||
AddNodes(falsenode_ids[i], cmodes, truenode_ids, falsenode_ids, nodes_featureids, nodes_values_as_tensor,
|
||||
node_values, nodes_missing_value_tracks_true, updated_mapping, tree_id, node_tree_ids);
|
||||
if (false_branch != node_pos + 1) {
|
||||
ORT_THROW("False node must always be the next node, but it isn't at index ", node_pos, " with flags ",
|
||||
static_cast<int>(nodes_[node_pos].flags));
|
||||
}
|
||||
size_t true_branch =
|
||||
AddNodes(truenode_ids[i], cmodes, truenode_ids, falsenode_ids, nodes_featureids, nodes_values_as_tensor,
|
||||
node_values, nodes_missing_value_tracks_true, updated_mapping, tree_id, node_tree_ids);
|
||||
// We don't need to store the false branch pointer since we know it is always in the immediate next entry in nodes_.
|
||||
// nodes_[node_pos].falsenode_inc_or_n_weights.ptr = &nodes_[false_branch];
|
||||
nodes_[node_pos].truenode_or_weight.ptr = &nodes_[true_branch];
|
||||
} else {
|
||||
nodes_[node_pos].truenode_or_weight.weight_data.weight = 0;
|
||||
nodes_[node_pos].truenode_or_weight.weight_data.n_weights = 0;
|
||||
}
|
||||
return node_pos;
|
||||
}
|
||||
|
||||
template <typename InputType, typename ThresholdType, typename OutputType>
|
||||
Status TreeEnsembleCommon<InputType, ThresholdType, OutputType>::compute(OpKernelContext* ctx,
|
||||
const Tensor* X,
|
||||
|
|
@ -637,22 +669,19 @@ void TreeEnsembleCommon<InputType, ThresholdType, OutputType>::ComputeAgg(concur
|
|||
}
|
||||
} // namespace detail
|
||||
|
||||
#define TREE_FIND_VALUE(CMP) \
|
||||
if (has_missing_tracks_) { \
|
||||
while (root->is_not_leaf()) { \
|
||||
val = x_data[root->feature_id]; \
|
||||
root += (val CMP root->value_or_unique_weight || \
|
||||
(root->is_missing_track_true() && _isnan_(val))) \
|
||||
? root->truenode_inc_or_first_weight \
|
||||
: root->falsenode_inc_or_n_weights; \
|
||||
} \
|
||||
} else { \
|
||||
while (root->is_not_leaf()) { \
|
||||
val = x_data[root->feature_id]; \
|
||||
root += val CMP root->value_or_unique_weight \
|
||||
? root->truenode_inc_or_first_weight \
|
||||
: root->falsenode_inc_or_n_weights; \
|
||||
} \
|
||||
#define TREE_FIND_VALUE(CMP) \
|
||||
if (has_missing_tracks_) { \
|
||||
while (root->is_not_leaf()) { \
|
||||
val = x_data[root->feature_id]; \
|
||||
root = (val CMP root->value_or_unique_weight || (root->is_missing_track_true() && _isnan_(val))) \
|
||||
? root->truenode_or_weight.ptr \
|
||||
: root + 1; \
|
||||
} \
|
||||
} else { \
|
||||
while (root->is_not_leaf()) { \
|
||||
val = x_data[root->feature_id]; \
|
||||
root = val CMP root->value_or_unique_weight ? root->truenode_or_weight.ptr : root + 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
inline bool _isnan_(float x) { return std::isnan(x); }
|
||||
|
|
@ -671,15 +700,14 @@ TreeEnsembleCommon<InputType, ThresholdType, OutputType>::ProcessTreeNodeLeave(
|
|||
if (has_missing_tracks_) {
|
||||
while (root->is_not_leaf()) {
|
||||
val = x_data[root->feature_id];
|
||||
root += (val <= root->value_or_unique_weight ||
|
||||
(root->is_missing_track_true() && _isnan_(val)))
|
||||
? root->truenode_inc_or_first_weight
|
||||
: root->falsenode_inc_or_n_weights;
|
||||
root = (val <= root->value_or_unique_weight || (root->is_missing_track_true() && _isnan_(val)))
|
||||
? root->truenode_or_weight.ptr
|
||||
: root + 1;
|
||||
}
|
||||
} else {
|
||||
while (root->is_not_leaf()) {
|
||||
val = x_data[root->feature_id];
|
||||
root += val <= root->value_or_unique_weight ? root->truenode_inc_or_first_weight : root->falsenode_inc_or_n_weights;
|
||||
root = val <= root->value_or_unique_weight ? root->truenode_or_weight.ptr : root + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -703,42 +731,36 @@ TreeEnsembleCommon<InputType, ThresholdType, OutputType>::ProcessTreeNodeLeave(
|
|||
}
|
||||
} else { // Different rules to compare to node thresholds.
|
||||
ThresholdType threshold;
|
||||
while (root->is_not_leaf()) {
|
||||
while (1) {
|
||||
val = x_data[root->feature_id];
|
||||
threshold = root->value_or_unique_weight;
|
||||
switch (root->mode()) {
|
||||
case NODE_MODE::BRANCH_LEQ:
|
||||
root += val <= threshold || (root->is_missing_track_true() && _isnan_(val))
|
||||
? root->truenode_inc_or_first_weight
|
||||
: root->falsenode_inc_or_n_weights;
|
||||
root = val <= threshold || (root->is_missing_track_true() && _isnan_(val)) ? root->truenode_or_weight.ptr
|
||||
: root + 1;
|
||||
break;
|
||||
case NODE_MODE::BRANCH_LT:
|
||||
root += val < threshold || (root->is_missing_track_true() && _isnan_(val))
|
||||
? root->truenode_inc_or_first_weight
|
||||
: root->falsenode_inc_or_n_weights;
|
||||
root = val < threshold || (root->is_missing_track_true() && _isnan_(val)) ? root->truenode_or_weight.ptr
|
||||
: root + 1;
|
||||
break;
|
||||
case NODE_MODE::BRANCH_GTE:
|
||||
root += val >= threshold || (root->is_missing_track_true() && _isnan_(val))
|
||||
? root->truenode_inc_or_first_weight
|
||||
: root->falsenode_inc_or_n_weights;
|
||||
root = val >= threshold || (root->is_missing_track_true() && _isnan_(val)) ? root->truenode_or_weight.ptr
|
||||
: root + 1;
|
||||
break;
|
||||
case NODE_MODE::BRANCH_GT:
|
||||
root += val > threshold || (root->is_missing_track_true() && _isnan_(val))
|
||||
? root->truenode_inc_or_first_weight
|
||||
: root->falsenode_inc_or_n_weights;
|
||||
root = val > threshold || (root->is_missing_track_true() && _isnan_(val)) ? root->truenode_or_weight.ptr
|
||||
: root + 1;
|
||||
break;
|
||||
case NODE_MODE::BRANCH_EQ:
|
||||
root += val == threshold || (root->is_missing_track_true() && _isnan_(val))
|
||||
? root->truenode_inc_or_first_weight
|
||||
: root->falsenode_inc_or_n_weights;
|
||||
root = val == threshold || (root->is_missing_track_true() && _isnan_(val)) ? root->truenode_or_weight.ptr
|
||||
: root + 1;
|
||||
break;
|
||||
case NODE_MODE::BRANCH_NEQ:
|
||||
root += val != threshold || (root->is_missing_track_true() && _isnan_(val))
|
||||
? root->truenode_inc_or_first_weight
|
||||
: root->falsenode_inc_or_n_weights;
|
||||
root = val != threshold || (root->is_missing_track_true() && _isnan_(val)) ? root->truenode_or_weight.ptr
|
||||
: root + 1;
|
||||
break;
|
||||
case NODE_MODE::LEAF:
|
||||
break;
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ class QLinearConv : public OpKernel {
|
|||
W_zero_point_value = W_zero_point_data[0];
|
||||
for (int64_t i = 1; i < W_zero_point_size; i++) {
|
||||
ORT_ENFORCE(W_zero_point_data[i] == W_zero_point_value,
|
||||
"QLinearConv : zero point of per-channel filter must be same");
|
||||
"QLinearConv : zero point of per-channel filter must be same. "
|
||||
"This happens by design if the quantization is symmetric.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1138,46 +1138,35 @@ bool TensorrtExecutionProvider::IsGraphCaptureEnabled() const {
|
|||
return cuda_graph_enable_;
|
||||
}
|
||||
|
||||
bool TensorrtExecutionProvider::IsGraphCaptured() const {
|
||||
return GetPerThreadContext().IsGraphCaptured();
|
||||
}
|
||||
|
||||
Status TensorrtExecutionProvider::ReplayGraph() {
|
||||
return GetPerThreadContext().ReplayGraph();
|
||||
}
|
||||
|
||||
void TensorrtExecutionProvider::PerThreadContext::SetGraphStream(cudaStream_t stream) {
|
||||
cuda_graph_.SetStream(stream);
|
||||
}
|
||||
|
||||
bool TensorrtExecutionProvider::PerThreadContext::IsGraphCaptureAllowed() const {
|
||||
bool TensorrtExecutionProvider::IsGraphCaptureAllowed() const {
|
||||
return regular_run_count_before_graph_capture_ >= min_num_runs_before_cuda_graph_capture_;
|
||||
}
|
||||
|
||||
void TensorrtExecutionProvider::PerThreadContext::CaptureBegin() {
|
||||
void TensorrtExecutionProvider::CaptureBegin() {
|
||||
cuda_graph_.Reset();
|
||||
cuda_graph_.CaptureBegin();
|
||||
}
|
||||
|
||||
void TensorrtExecutionProvider::PerThreadContext::CaptureEnd() {
|
||||
void TensorrtExecutionProvider::CaptureEnd() {
|
||||
cuda_graph_.CaptureEnd();
|
||||
is_graph_captured_ = true;
|
||||
}
|
||||
|
||||
bool TensorrtExecutionProvider::PerThreadContext::IsGraphCaptured() const {
|
||||
bool TensorrtExecutionProvider::IsGraphCaptured() const {
|
||||
return is_graph_captured_;
|
||||
}
|
||||
|
||||
Status TensorrtExecutionProvider::PerThreadContext::ReplayGraph() {
|
||||
Status TensorrtExecutionProvider::ReplayGraph() {
|
||||
ORT_ENFORCE(IsGraphCaptured());
|
||||
// Please note that CUDAGraph::Replay() is not thread safe.
|
||||
// The cuda graph object is maintained by a per thread basis,
|
||||
// ORT TRT calls ReplayGraph() in compute_func() where synchromization is enforced due to lock_guard(),
|
||||
// therefore calling CUDAGraph::Replay() here is guaranteed to be thread safe.
|
||||
return cuda_graph_.Replay();
|
||||
}
|
||||
|
||||
void TensorrtExecutionProvider::PerThreadContext::IncrementRegularRunCountBeforeGraphCapture() {
|
||||
// The cuda graph object is maintained by a per thread basis,
|
||||
void TensorrtExecutionProvider::IncrementRegularRunCountBeforeGraphCapture() {
|
||||
// Please note that this function is not thread safe.
|
||||
// ORT TRT calls this function in compute_func() where synchronization is enforced due to lock_guard(),
|
||||
// therefore following increment is guaranteed to be thread safe.
|
||||
++regular_run_count_before_graph_capture_;
|
||||
}
|
||||
|
|
@ -1208,18 +1197,6 @@ Status TensorrtExecutionProvider::OnRunEnd(bool sync_stream) {
|
|||
if (sync_stream && external_stream_) {
|
||||
CUDA_RETURN_IF_ERROR(cudaStreamSynchronize(stream_));
|
||||
}
|
||||
|
||||
// The reason of !IsGraphCaptureEnabled():
|
||||
// If cuda graph is enabled, the per thread context will not be released
|
||||
// because the per thread cuda graph needs to be maintained and replayed for
|
||||
// the next run.
|
||||
// The reason of PerThreadContextCache()->find(this) != PerThreadContextCache()->end():
|
||||
// In extreme cases (e.g., 1-op graph and that op fallbacks to CPU),
|
||||
// PerThreadContext won't be created and there is nothing to release.
|
||||
if (!IsGraphCaptureEnabled() &&
|
||||
PerThreadContextCache()->find(this) != PerThreadContextCache()->end()) {
|
||||
ReleasePerThreadContext();
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
|
|
@ -2373,6 +2350,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
// Save TRT engine, other TRT objects and input/output info to map
|
||||
parsers_.emplace(fused_node.Name(), std::move(trt_parser));
|
||||
engines_.emplace(fused_node.Name(), std::move(trt_engine));
|
||||
contexts_.emplace(fused_node.Name(), std::move(trt_context));
|
||||
builders_.emplace(fused_node.Name(), std::move(trt_builder));
|
||||
networks_.emplace(fused_node.Name(), std::move(trt_network));
|
||||
input_info_[fused_node.Name()].push_back(input_indexes);
|
||||
|
|
@ -2381,14 +2359,6 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
input_shape_ranges_[fused_node.Name()] = input_implicit_shape_ranges;
|
||||
profiles_.emplace(fused_node.Name(), std::move(trt_profiles));
|
||||
|
||||
// Save TRT context to PerThreadContext map since maintaining execution context in a per thread basis is suggested by TRT doc to avoid synchronization issue
|
||||
if (trt_context) {
|
||||
auto context_status = GetPerThreadContext().UpdateTensorRTContext(fused_node.Name(), std::move(trt_context));
|
||||
if (!context_status) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL, "TensorRT EP failed to create context.");
|
||||
}
|
||||
}
|
||||
|
||||
// Create function state
|
||||
// TODO: remove default capture
|
||||
NodeComputeInfo compute_info;
|
||||
|
|
@ -2400,7 +2370,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
tactics = GetTacticSourceFromString(tactic_sources_);
|
||||
}
|
||||
*p = {context->allocate_func, context->release_func, context->allocator_handle, context->node_name,
|
||||
&parsers_[context->node_name], &engines_[context->node_name], &builders_[context->node_name],
|
||||
&parsers_[context->node_name], &engines_[context->node_name], &contexts_[context->node_name], &builders_[context->node_name],
|
||||
&networks_[context->node_name], input_info_[context->node_name], output_info_[context->node_name],
|
||||
input_shape_ranges_[context->node_name], &tensorrt_mu_, fp16_enable_, int8_enable_, int8_calibration_cache_available_,
|
||||
dla_enable_, dla_core_, &max_workspace_size_, trt_node_name_with_precision, engine_cache_enable_, cache_path_,
|
||||
|
|
@ -2434,6 +2404,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
auto& shape_ranges = trt_state->input_shape_ranges;
|
||||
auto trt_builder = trt_state->builder->get();
|
||||
auto trt_engine = trt_state->engine->get();
|
||||
auto trt_context = trt_state->context->get();
|
||||
auto trt_profiles = trt_state->profiles;
|
||||
auto max_context_mem_size_ptr = trt_state->max_context_mem_size_ptr;
|
||||
int num_inputs = static_cast<int>(input_indexes.size());
|
||||
|
|
@ -2490,7 +2461,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
trt_state->engine->reset();
|
||||
*(trt_state->engine) = std::unique_ptr<nvinfer1::ICudaEngine>(
|
||||
trt_state->runtime->deserializeCudaEngine(engine_buf.get(), engine_size, nullptr));
|
||||
if (*(trt_state->engine) == nullptr) {
|
||||
if (!(*(trt_state->engine))) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL, "TensorRT EP Failed to Build Engine.");
|
||||
}
|
||||
LOGS_DEFAULT(VERBOSE) << "[TensorRT EP] DeSerialized " + engine_cache_path;
|
||||
|
|
@ -2515,7 +2486,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
// https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#threading
|
||||
trt_state->engine->reset();
|
||||
*(trt_state->engine) = std::unique_ptr<nvinfer1::ICudaEngine>(trt_state->runtime->deserializeCudaEngine(engine_buf.get(), engine_size, nullptr));
|
||||
if (*(trt_state->engine) == nullptr) {
|
||||
if (!(*(trt_state->engine))) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL,
|
||||
"TensorRT EP could not deserialize engine from encrypted cache: " + engine_cache_path);
|
||||
}
|
||||
|
|
@ -2544,10 +2515,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
// Regenerate engine
|
||||
if (engine_update) {
|
||||
// Destroy the IExecutionContext objects before destroying an engine object, otherwise it will lead to undefined behavior.
|
||||
if (GetPerThreadContext().IsTensorRTContextInMap(fused_node_name)) {
|
||||
GetPerThreadContext().ResetTensorRTContext(fused_node_name);
|
||||
}
|
||||
|
||||
trt_state->context->reset();
|
||||
trt_state->engine->reset();
|
||||
auto trt_config = std::unique_ptr<nvinfer1::IBuilderConfig>(trt_builder->createBuilderConfig());
|
||||
trt_config->setMaxWorkspaceSize(*(trt_state->max_workspace_size_ptr));
|
||||
|
|
@ -2648,7 +2616,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
LOGS_DEFAULT(INFO) << "TensorRT engine build for " << trt_state->trt_node_name_with_precision << " took: " << std::chrono::duration_cast<std::chrono::milliseconds>(engine_build_stop - engine_build_start).count() << "ms" << std::endl;
|
||||
}
|
||||
}
|
||||
if (*(trt_state->engine) == nullptr) {
|
||||
if (!(*(trt_state->engine))) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL, "TensorRT EP Failed to Build Engine.");
|
||||
}
|
||||
trt_engine = trt_state->engine->get();
|
||||
|
|
@ -2689,32 +2657,20 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
context_update = true;
|
||||
}
|
||||
|
||||
// Build execution context if either of the following conditions is true:
|
||||
// (1) The engine is built or updated by this thread.
|
||||
// (2) The first inference run for this thread where there is no IExecutionContext object yet.
|
||||
// (3) The engine is updated by another thread. (We compare the profile shapes maintained by the PerThreadContext to the profile shapes maintained by TRT EP)
|
||||
//
|
||||
// Note: Creating an execution context from an engine is thread safe per TRT doc
|
||||
// https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#threading
|
||||
if (context_update ||
|
||||
!GetPerThreadContext().IsTensorRTContextInMap(fused_node_name) ||
|
||||
GetPerThreadContext().CompareProfileShapes(fused_node_name, shape_ranges)) {
|
||||
std::unique_ptr<nvinfer1::IExecutionContext> new_context;
|
||||
if (context_update) {
|
||||
if (trt_state->context_memory_sharing_enable) {
|
||||
new_context.reset(trt_state->engine->get()->createExecutionContextWithoutDeviceMemory());
|
||||
*(trt_state->context) = std::unique_ptr<nvinfer1::IExecutionContext>(
|
||||
trt_state->engine->get()->createExecutionContextWithoutDeviceMemory());
|
||||
} else {
|
||||
new_context.reset(trt_state->engine->get()->createExecutionContext());
|
||||
*(trt_state->context) = std::unique_ptr<nvinfer1::IExecutionContext>(
|
||||
trt_state->engine->get()->createExecutionContext());
|
||||
}
|
||||
auto context_status = GetPerThreadContext().UpdateTensorRTContext(fused_node_name, std::move(new_context));
|
||||
if (!context_status) {
|
||||
if (!(*(trt_state->context))) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL, "TensorRT EP failed to create context.");
|
||||
}
|
||||
GetPerThreadContext().UpdateProfileShapes(fused_node_name, shape_ranges);
|
||||
trt_context = trt_state->context->get();
|
||||
}
|
||||
|
||||
// Get the reference to the IExecutionContext object that is maintained on a per thread basis.
|
||||
nvinfer1::IExecutionContext& trt_context = GetPerThreadContext().GetTensorRTContext(fused_node_name);
|
||||
|
||||
// Get input and output binding names
|
||||
int total_bindings = trt_engine->getNbBindings();
|
||||
std::vector<void*> buffers(total_bindings);
|
||||
|
|
@ -2750,12 +2706,12 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
int nb_dims = dimensions.nbDims;
|
||||
if (input_names.count(input_name) == 1) {
|
||||
if (trt_engine->isShapeBinding(binding_index)) {
|
||||
trt_context.setInputShapeBinding(binding_index, &tensor_shape_values[input_name][0]);
|
||||
trt_context->setInputShapeBinding(binding_index, &tensor_shape_values[input_name][0]);
|
||||
} else {
|
||||
for (int j = 0, end = nb_dims; j < end; ++j) {
|
||||
dimensions.d[j] = static_cast<int32_t>(tensor_shapes[j]);
|
||||
}
|
||||
const bool status = trt_context.setBindingDimensions(binding_index, dimensions);
|
||||
const bool status = trt_context->setBindingDimensions(binding_index, dimensions);
|
||||
if (!status) {
|
||||
ORT_THROW_IF_ERROR(ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL,
|
||||
"TensorRT EP cannot set the dynamic dimensions of a binding"));
|
||||
|
|
@ -2894,7 +2850,7 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
if (index_iter != output_indexes.end()) {
|
||||
output_index = index_iter->second;
|
||||
}
|
||||
nvinfer1::Dims dimensions = trt_context.getBindingDimensions(static_cast<int>(binding_index));
|
||||
nvinfer1::Dims dimensions = trt_context->getBindingDimensions(static_cast<int>(binding_index));
|
||||
int nb_dims = dimensions.nbDims;
|
||||
std::vector<int64_t> output_shapes(nb_dims);
|
||||
for (int j = 0, end = nb_dims; j < end; ++j) {
|
||||
|
|
@ -3028,20 +2984,20 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
if (mem_size > *max_context_mem_size_ptr) {
|
||||
*max_context_mem_size_ptr = mem_size;
|
||||
}
|
||||
trt_context.setDeviceMemory(IAllocator::MakeUniquePtrFromOrtAllocator<void>(alloc, *max_context_mem_size_ptr).get());
|
||||
trt_context->setDeviceMemory(IAllocator::MakeUniquePtrFromOrtAllocator<void>(alloc, *max_context_mem_size_ptr).get());
|
||||
}
|
||||
|
||||
// Start CUDA graph capture.
|
||||
// Note: The reason we don't put graph capture in OnRunStart() like CUDA EP does is because
|
||||
// current ORT TRT doesn't get cuda stream until compute time and graph capture requires cuda stream.
|
||||
if (cuda_graph_enable_ && GetPerThreadContext().IsGraphCaptureAllowed() && !GetPerThreadContext().IsGraphCaptured()) {
|
||||
if (cuda_graph_enable_ && IsGraphCaptureAllowed() && !IsGraphCaptured()) {
|
||||
LOGS_DEFAULT(INFO) << "Capturing the cuda graph for this model";
|
||||
GetPerThreadContext().SetGraphStream(stream);
|
||||
GetPerThreadContext().CaptureBegin();
|
||||
cuda_graph_.SetStream(stream);
|
||||
CaptureBegin();
|
||||
}
|
||||
|
||||
// Run TRT inference
|
||||
if (!trt_context.enqueueV2(&buffers[0], stream, nullptr)) {
|
||||
if (!trt_context->enqueueV2(&buffers[0], stream, nullptr)) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "TensorRT EP execution context enqueue failed.");
|
||||
}
|
||||
|
||||
|
|
@ -3072,14 +3028,14 @@ common::Status TensorrtExecutionProvider::Compile(const std::vector<FusedNodeAnd
|
|||
// Note: One reason we don't put end of graph capture in OnRunEnd() like CUDA EP does is because of cuda stream mentioned in graph capture
|
||||
// above, another reason is because OnRunEnd() is not synchronized with OnRunStart() and ExecuteGraph() per inference_session.cc.
|
||||
// It's safe to start/end CUDA graph capture in compute_func() here since cuda graph object is maintained by a per thread basis.
|
||||
if (cuda_graph_enable_ && !GetPerThreadContext().IsGraphCaptured()) {
|
||||
if (GetPerThreadContext().IsGraphCaptureAllowed()) {
|
||||
GetPerThreadContext().CaptureEnd();
|
||||
if (cuda_graph_enable_ && !IsGraphCaptured()) {
|
||||
if (IsGraphCaptureAllowed()) {
|
||||
CaptureEnd();
|
||||
// CUDA work issued to a capturing stream doesn’t actually run on the GPU,
|
||||
// so run the captured graph here to actually execute the work.
|
||||
ORT_RETURN_IF_ERROR(GetPerThreadContext().ReplayGraph());
|
||||
ORT_RETURN_IF_ERROR(ReplayGraph());
|
||||
} else {
|
||||
GetPerThreadContext().IncrementRegularRunCountBeforeGraphCapture();
|
||||
IncrementRegularRunCountBeforeGraphCapture();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3099,8 +3055,8 @@ void TensorrtExecutionProvider::RegisterStreamHandlers(IStreamCommandHandleRegis
|
|||
true /* release_cpu_buffer_on_cuda_stream */,
|
||||
stream_,
|
||||
external_stream_ /* use_existing_stream */,
|
||||
GetPerThreadContext().CudnnHandle(),
|
||||
GetPerThreadContext().CublasHandle());
|
||||
external_cudnn_handle_,
|
||||
external_cublas_handle_);
|
||||
}
|
||||
|
||||
OrtDevice TensorrtExecutionProvider::GetOrtDeviceByMemType(OrtMemType mem_type) const {
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ struct TensorrtFuncState {
|
|||
std::string fused_node_name;
|
||||
tensorrt_ptr::unique_pointer<nvonnxparser::IParser>* parser = nullptr;
|
||||
std::unique_ptr<nvinfer1::ICudaEngine>* engine = nullptr;
|
||||
std::unique_ptr<nvinfer1::IExecutionContext>* context = nullptr;
|
||||
std::unique_ptr<nvinfer1::IBuilder>* builder = nullptr;
|
||||
std::unique_ptr<nvinfer1::INetworkDefinition>* network = nullptr;
|
||||
std::vector<std::unordered_map<std::string, size_t>> input_info;
|
||||
|
|
@ -246,6 +247,7 @@ class TensorrtExecutionProvider : public IExecutionProvider {
|
|||
// For those non thread safe operations, TRT EP uses (1) lock_guard or (2) PerThreadContext to make sure synchronization.
|
||||
std::unordered_map<std::string, tensorrt_ptr::unique_pointer<nvonnxparser::IParser>> parsers_;
|
||||
std::unordered_map<std::string, std::unique_ptr<nvinfer1::ICudaEngine>> engines_;
|
||||
std::unordered_map<std::string, std::unique_ptr<nvinfer1::IExecutionContext>> contexts_;
|
||||
std::unordered_map<std::string, std::unique_ptr<nvinfer1::IBuilder>> builders_;
|
||||
std::unordered_map<std::string, std::unique_ptr<nvinfer1::INetworkDefinition>> networks_;
|
||||
std::unordered_map<std::string, std::vector<std::unordered_map<std::string, size_t>>> input_info_;
|
||||
|
|
@ -256,6 +258,21 @@ class TensorrtExecutionProvider : public IExecutionProvider {
|
|||
std::unordered_map<std::string, ShapeRangesMap> input_shape_ranges_; // The profile shape ranges that the engine is built with
|
||||
std::unordered_map<std::string, std::vector<nvinfer1::IOptimizationProfile*>> profiles_;
|
||||
|
||||
// for external stream, we need to create its cudnn/cublass handle before cuda EP enable cuda graph capture
|
||||
cudnnHandle_t external_cudnn_handle_ = nullptr;
|
||||
cublasHandle_t external_cublas_handle_ = nullptr;
|
||||
|
||||
CUDAGraph cuda_graph_;
|
||||
bool is_graph_captured_ = false;
|
||||
int regular_run_count_before_graph_capture_ = 0;
|
||||
// There is chance (currently only happens in CUDA EP) that the second regular run allocates GPU memory for causes like:
|
||||
// (1) memory pattern is enabled. (2) arena allocation for stream.
|
||||
// Since no GPU memory allocation is allowed during graph capturing, we need at least two regular runs
|
||||
// to allocate enough memory in Arena before graph capturing.
|
||||
const int min_num_runs_before_cuda_graph_capture_ = 1; // required min regular runs before graph capture for the necessary memory allocations.
|
||||
|
||||
// [Note] We don't use PerThreadContext for now since it has issue with multithreading
|
||||
//
|
||||
// TRT or CUDA objects that must be maintained on a per thread basis will be put under this PerThreadContext data structure.
|
||||
// For example, TensorRT execution context and CUDA graph are the ones to be put here.
|
||||
class PerThreadContext final {
|
||||
|
|
|
|||
|
|
@ -2711,9 +2711,8 @@ static constexpr OrtApi ort_api_1_to_16 = {
|
|||
&OrtApis::GetTensorRTProviderOptionsByName,
|
||||
&OrtApis::UpdateCUDAProviderOptionsWithValue,
|
||||
&OrtApis::GetCUDAProviderOptionsByName,
|
||||
// End of Version 16 - DO NOT MODIFY ABOVE (see above text for more information)
|
||||
|
||||
&OrtApis::KernelContext_GetResource,
|
||||
// End of Version 16 - DO NOT MODIFY ABOVE (see above text for more information)
|
||||
};
|
||||
|
||||
// OrtApiBase can never change as there is no way to know what version of OrtApiBase is returned by OrtGetApiBase.
|
||||
|
|
@ -2742,10 +2741,10 @@ static_assert(offsetof(OrtApi, ReleaseKernelInfo) / sizeof(void*) == 218, "Size
|
|||
static_assert(offsetof(OrtApi, ReleaseCANNProviderOptions) / sizeof(void*) == 224, "Size of version 13 API cannot change");
|
||||
static_assert(offsetof(OrtApi, GetSessionConfigEntry) / sizeof(void*) == 238, "Size of version 14 API cannot change");
|
||||
static_assert(offsetof(OrtApi, GetBuildInfoString) / sizeof(void*) == 254, "Size of version 15 API cannot change");
|
||||
static_assert(offsetof(OrtApi, GetCUDAProviderOptionsByName) / sizeof(void*) == 264, "Size of version 16 API cannot change");
|
||||
static_assert(offsetof(OrtApi, KernelContext_GetResource) / sizeof(void*) == 265, "Size of version 16 API cannot change");
|
||||
|
||||
// So that nobody forgets to finish an API version, this check will serve as a reminder:
|
||||
static_assert(std::string_view(ORT_VERSION) == "1.16.0",
|
||||
static_assert(std::string_view(ORT_VERSION) == "1.16.1",
|
||||
"ORT_Version change detected, please follow below steps to ensure OrtApi is updated properly");
|
||||
// 1. Update the hardcoded version string in above static_assert to silence it
|
||||
// 2. If there were any APIs added to ort_api_1_to_16 above:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from .quant_utils import apply_plot, load_model_with_shape_infer, smooth_distrib
|
|||
|
||||
|
||||
class TensorData:
|
||||
_allowed = frozenset(["avg", "std", "lowest", "highest", "hist", "hist_edges"])
|
||||
_allowed = frozenset(["avg", "std", "lowest", "highest", "hist", "hist_edges", "bins"])
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
|
|
@ -55,7 +55,7 @@ class TensorsData:
|
|||
self.data[k] = TensorData(lowest=v[0], highest=v[1])
|
||||
continue
|
||||
if len(v) == 4:
|
||||
self.data[k] = TensorData(lowest=v[0], highest=v[1], histogram=v[2], bins=v[3])
|
||||
self.data[k] = TensorData(lowest=v[0], highest=v[1], hist=v[2], bins=v[3])
|
||||
continue
|
||||
raise TypeError(f"Unexpected tuple for {k:r}, it has {len(v)} elements: {v}.")
|
||||
if not isinstance(v, TensorData):
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class QLinearConv(QuantOperatorBase):
|
|||
nodes,
|
||||
) = self.quantizer.quantize_activation(node, [0])
|
||||
quant_weight_tuple = self.quantizer.quantize_weight_per_channel(
|
||||
node.input[1], onnx_proto.TensorProto.INT8, 0
|
||||
node.input[1], onnx_proto.TensorProto.INT8, 0 # self.quantizer.weight_qType?
|
||||
)
|
||||
quantized_input_names.append(quant_weight_tuple[0])
|
||||
zero_point_names.append(quant_weight_tuple[1])
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ class LSTMQuant(QuantOperatorBase):
|
|||
R.dims[0] = R_num_dir * R_4_hidden_size
|
||||
|
||||
quant_input_weight_tuple = self.quantizer.quantize_weight_per_channel(
|
||||
node.input[1], onnx_proto.TensorProto.INT8, 0
|
||||
node.input[1], onnx_proto.TensorProto.INT8, 0 # self.quantizer.weight_qType?
|
||||
)
|
||||
quant_recurrent_weight_tuple = self.quantizer.quantize_weight_per_channel(
|
||||
node.input[2], onnx_proto.TensorProto.INT8, 0
|
||||
node.input[2], onnx_proto.TensorProto.INT8, 0 # self.quantizer.weight_qType?
|
||||
)
|
||||
|
||||
W_quant_weight = model.get_initializer(quant_input_weight_tuple[0]) # noqa: N806
|
||||
|
|
|
|||
|
|
@ -266,7 +266,13 @@ class QDQQuantizer(ONNXQuantizer):
|
|||
raise ValueError("Per-Channel support with QDQ format requires onnx opset version 13 or above.")
|
||||
q_weight_name, zp_name, scale_name = self.quantize_weight_per_channel(
|
||||
weight_name,
|
||||
self.weight_qType if tensor_type is QDQQuantTensorType.WEIGHT else self.activation_qType,
|
||||
# Quantization type is forced to be TensorProto.INT8.
|
||||
# when the expected value would be (see below)
|
||||
# self.weight_qType if tensor_type is QDQQuantTensorType.WEIGHT else self.activation_qType.
|
||||
# QLinearConv expects to have a unique value for all channels.
|
||||
# This code does not enforce that but it is necessarily the case when the
|
||||
# quantization is symmetric (as for INT8).
|
||||
onnx_proto.TensorProto.INT8,
|
||||
axis,
|
||||
keep_float_weight=self.add_qdq_pair_to_weight,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -99,7 +99,10 @@ def quant_pre_process(
|
|||
sess_option = onnxruntime.SessionOptions()
|
||||
sess_option.optimized_model_filepath = opt_model_path
|
||||
sess_option.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_BASIC
|
||||
_ = onnxruntime.InferenceSession(input_model_path, sess_option, providers=["CPUExecutionProvider"])
|
||||
sess = onnxruntime.InferenceSession(input_model_path, sess_option, providers=["CPUExecutionProvider"])
|
||||
# Close the session to avoid the cleanup error on Windows for temp folders
|
||||
# https://github.com/microsoft/onnxruntime/issues/17627
|
||||
del sess
|
||||
except Exception:
|
||||
logger.error(
|
||||
"ONNX Runtime Model Optimization Failed! Consider rerun with option `--skip_optimization'."
|
||||
|
|
|
|||
13763
onnxruntime/test/python/quantization/resnet_code.py
Normal file
13763
onnxruntime/test/python/quantization/resnet_code.py
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,138 @@
|
|||
# -------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for
|
||||
# license information.
|
||||
# --------------------------------------------------------------------------
|
||||
import os
|
||||
import random
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
import onnx
|
||||
from numpy.testing import assert_allclose
|
||||
from onnx.numpy_helper import to_array
|
||||
from resnet_code import create_model
|
||||
|
||||
from onnxruntime import InferenceSession
|
||||
from onnxruntime import __version__ as ort_version
|
||||
from onnxruntime.quantization import QuantFormat, QuantType, quantize_static
|
||||
from onnxruntime.quantization.calibrate import CalibrationDataReader, CalibrationMethod
|
||||
|
||||
|
||||
class FakeResnetCalibrationDataReader(CalibrationDataReader):
|
||||
def __init__(self, batch_size: int = 16):
|
||||
super().__init__()
|
||||
self.dataset = [
|
||||
(np.random.rand(1, 3, 32, 32).astype(np.float32), random.randint(0, 9)) for _ in range(batch_size)
|
||||
]
|
||||
self.iterator = iter(self.dataset)
|
||||
|
||||
def get_next(self) -> dict:
|
||||
try:
|
||||
return {"input": next(self.iterator)[0]}
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
class TestStaticQuantizationResNet(unittest.TestCase):
|
||||
def test_quantize_static_resnet(self):
|
||||
kwargs = {
|
||||
"activation_type": QuantType.QUInt8,
|
||||
"weight_type": QuantType.QInt8,
|
||||
"calibrate_method": CalibrationMethod.Percentile,
|
||||
"extra_options": {
|
||||
"ActivationSymmetric": False,
|
||||
"EnableSubgraph": False,
|
||||
"ForceQuantizeNoInputCheck": False,
|
||||
"MatMulConstBOnly": False,
|
||||
"WeightSymmetric": True,
|
||||
"extra.Sigmoid.nnapi": False,
|
||||
},
|
||||
"nodes_to_exclude": None,
|
||||
"nodes_to_quantize": None,
|
||||
"op_types_to_quantize": None,
|
||||
"per_channel": True,
|
||||
"quant_format": QuantFormat.QDQ,
|
||||
"reduce_range": False,
|
||||
}
|
||||
|
||||
proto = create_model()
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
model = os.path.join(temp, "resnet_first_nodes.onnx")
|
||||
with open(model, "wb") as f:
|
||||
f.write(proto.SerializeToString())
|
||||
|
||||
for per_channel in [True, False]:
|
||||
kwargs["per_channel"] = per_channel
|
||||
dataloader = FakeResnetCalibrationDataReader(16)
|
||||
with self.subTest(per_channel=per_channel):
|
||||
qdq_file = os.path.join(
|
||||
temp, f"preprocessed-small-qdq-{1 if per_channel else 0}-ort-{ort_version}.onnx"
|
||||
)
|
||||
quantize_static(
|
||||
model_input=model,
|
||||
model_output=qdq_file,
|
||||
calibration_data_reader=dataloader,
|
||||
use_external_data_format=False,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
# With onnxruntime==1.15.1, the initializer 'onnx::Conv_504_zero_point' is:
|
||||
# * uint8(128) if per_channel is False
|
||||
# * int8([0, 0, ....]) if per_channel is True
|
||||
# With onnxruntime>1.16.0
|
||||
# * uint8(128) if per_channel is False
|
||||
# * uint8([128, 128, ..., 127, ...]) if per_channel is True
|
||||
# QLinearConv : zero point of per-channel filter must be same.
|
||||
# That's why the quantization forces a symmetric quantization into INT8.
|
||||
# zero_point is guaranted to be zero whatever the channel is.
|
||||
|
||||
with open(qdq_file, "rb") as f:
|
||||
onx = onnx.load(f)
|
||||
for init in onx.graph.initializer:
|
||||
arr = to_array(init)
|
||||
if (
|
||||
arr.dtype == np.int8
|
||||
and "zero_point" not in init.name
|
||||
and not init.name.endswith("quantized")
|
||||
):
|
||||
raise AssertionError(
|
||||
f"Initializer {init.name!r} has type {arr.dtype} and "
|
||||
f"shape {arr.shape} but should be {np.uint8}."
|
||||
)
|
||||
|
||||
sess = InferenceSession(qdq_file, providers=["CPUExecutionProvider"])
|
||||
shape = (1, 3, 32, 32)
|
||||
size = np.prod(shape)
|
||||
dummy = (np.arange(size) / float(size)).astype(np.float32).reshape(shape)
|
||||
got = sess.run(None, {"input": dummy})
|
||||
self.assertEqual(got[0].shape, (1, 64, 8, 8))
|
||||
self.assertEqual(got[0].dtype, np.float32)
|
||||
if per_channel:
|
||||
expected = np.array(
|
||||
[
|
||||
[[1.0862497091293335, 0.9609132409095764], [1.0862497091293335, 0.9191343784332275]],
|
||||
[[0.7520190477371216, 1.0026921033859253], [1.0444709062576294, 1.0862497091293335]],
|
||||
[[0.0, 0.0], [0.0, 0.0]],
|
||||
[[0.0, 0.0], [0.9609132409095764, 0.7937979102134705]],
|
||||
],
|
||||
dtype=np.float32,
|
||||
)
|
||||
assert_allclose(expected, got[0][0, :4, :2, :2], atol=0.2)
|
||||
else:
|
||||
expected = np.array(
|
||||
[
|
||||
[[1.428238868713379, 1.2602107524871826], [1.3442248106002808, 1.2182037830352783]],
|
||||
[[0.8821475505828857, 1.0921826362609863], [1.1341897249221802, 1.1761966943740845]],
|
||||
[[0.0, 0.0], [0.0, 0.0]],
|
||||
[[0.0, 0.0], [1.2182037830352783, 1.050175666809082]],
|
||||
],
|
||||
dtype=np.float32,
|
||||
)
|
||||
assert_allclose(expected, got[0][0, :4, :2, :2], atol=0.2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
|
|
@ -356,19 +356,32 @@ stages:
|
|||
- checkout: self
|
||||
submodules: false
|
||||
- template: templates/set-version-number-variables-step.yml
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Final Jar'
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: 'onnxruntime-java-gpu'
|
||||
targetPath: '$(Build.BinariesDirectory)/final-jar'
|
||||
|
||||
- task: Bash@3
|
||||
- template: templates/flex-downloadPipelineArtifact.yml
|
||||
parameters:
|
||||
StepName: 'Download Final Jar'
|
||||
ArtifactName: onnxruntime-java-gpu
|
||||
TargetPath: '$(Build.BinariesDirectory)/final-jar'
|
||||
SpecificArtifact: ${{ parameters.specificArtifact }}
|
||||
BuildId: ${{ parameters.BuildId }}
|
||||
|
||||
- template: templates/get-docker-image-steps.yml
|
||||
parameters:
|
||||
Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.package_ubi8_cuda11_8_tensorrt8_6
|
||||
Context: tools/ci_build/github/linux/docker/
|
||||
DockerBuildArgs: "--build-arg BUILD_UID=$( id -u )"
|
||||
Repository: onnxruntimeubi8packagestest
|
||||
UpdateDepsTxt: false
|
||||
|
||||
- bash: |
|
||||
docker run --rm \
|
||||
--gpus all \
|
||||
--volume $(Build.SourcesDirectory):/onnxruntime_src \
|
||||
--volume $(Build.BinariesDirectory):/build \
|
||||
--volume /data/models:/build/models:ro \
|
||||
onnxruntimeubi8packagestest \
|
||||
/bin/bash /onnxruntime_src/tools/ci_build/github/linux/java_linux_final_test.sh -r /build -v $(OnnxRuntimeVersion)
|
||||
displayName: 'Test'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: 'tools/ci_build/github/linux/java_linux_final_test.sh'
|
||||
arguments: '-r $(Build.BinariesDirectory) -v $(OnnxRuntimeVersion)'
|
||||
|
||||
- template: templates/component-governance-component-detection-steps.yml
|
||||
parameters:
|
||||
|
|
|
|||
|
|
@ -45,10 +45,6 @@ stages:
|
|||
clean: true
|
||||
submodules: none
|
||||
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.8'
|
||||
|
|
@ -74,7 +70,6 @@ stages:
|
|||
inputs:
|
||||
script: |
|
||||
mkdir -p $HOME/.onnx
|
||||
mkdir -p $(Pipeline.Workspace)/ccache
|
||||
docker run --rm \
|
||||
--volume /data/onnx:/data/onnx:ro \
|
||||
--volume $(Build.SourcesDirectory):/onnxruntime_src \
|
||||
|
|
@ -90,7 +85,7 @@ stages:
|
|||
set -ex; \
|
||||
ccache -s; \
|
||||
/opt/python/cp38-cp38/bin/python3 /onnxruntime_src/tools/ci_build/build.py \
|
||||
--build_dir /build --cmake_generator Ninja \
|
||||
--build_dir /build --cmake_generator 'Ninja' \
|
||||
--config Debug Release \
|
||||
--skip_submodule_sync \
|
||||
--build_shared_lib \
|
||||
|
|
@ -105,43 +100,31 @@ stages:
|
|||
ccache -z"
|
||||
workingDirectory: $(Build.SourcesDirectory)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: "Setup dotnet"
|
||||
inputs:
|
||||
version: '6.0.408'
|
||||
- script: |
|
||||
ln -s /data/models $(Build.BinariesDirectory)/models
|
||||
displayName: link model dir
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: "Restore C# packages"
|
||||
inputs:
|
||||
command: 'restore'
|
||||
projects: '$(Build.SourcesDirectory)/csharp/OnnxRuntime.DesktopOnly.CSharp.sln'
|
||||
|
||||
# the props file was generated with docker container paths. convert to the 'real' path by replacing the
|
||||
# the container path of '/build'. The '>' prefix is to match the closing angle bracket of the tag.
|
||||
# e.g. <OnnxRuntimeBuildDirectory>/build/... so we only match the start of a path.
|
||||
# We use powershell so we don't need extra escaping of the '/' chars in the path.
|
||||
- task: CmdLine@2
|
||||
displayName: 'Update props from docker path to local and create models link'
|
||||
inputs:
|
||||
script: |
|
||||
pwsh -Command '(Get-Content $(Build.SourcesDirectory)/csharp/Directory.Build.props) -replace ">/build", ">$(Build.BinariesDirectory)" | Set-Content $(Build.SourcesDirectory)/csharp/Directory.Build.props'
|
||||
cat $(Build.SourcesDirectory)/csharp/Directory.Build.props
|
||||
ln -s /data/models $(Build.BinariesDirectory)/models
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'dotnet build C# sln'
|
||||
inputs:
|
||||
command: 'build'
|
||||
projects: '$(Build.SourcesDirectory)/csharp/OnnxRuntime.DesktopOnly.CSharp.sln'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'dotnet test C#'
|
||||
inputs:
|
||||
command: 'test'
|
||||
projects: '$(Build.SourcesDirectory)/csharp/OnnxRuntime.DesktopOnly.CSharp.sln'
|
||||
# extra logging so all tests are listed in output to validate what's actually run
|
||||
arguments: '-f net6.0 --no-build -l "console;verbosity=normal"'
|
||||
workingDirectory: $(Build.SourcesDirectory)/csharp
|
||||
- bash: |
|
||||
mkdir -p $HOME/.onnx
|
||||
docker run --rm \
|
||||
--volume /data/onnx:/data/onnx:ro \
|
||||
--volume $(Build.SourcesDirectory):/onnxruntime_src \
|
||||
--volume $(Build.BinariesDirectory):/build \
|
||||
--volume /data/models:/build/models:ro \
|
||||
--volume $HOME/.onnx:/home/onnxruntimedev/.onnx \
|
||||
-e ALLOW_RELEASED_ONNX_OPSET_ONLY=0 \
|
||||
-e NIGHTLY_BUILD \
|
||||
-e BUILD_BUILDNUMBER \
|
||||
onnxruntimecpubuild \
|
||||
/bin/bash -c "
|
||||
set -ex; \
|
||||
pushd /onnxruntime_src/csharp; \
|
||||
dotnet restore /onnxruntime_src/csharp/OnnxRuntime.DesktopOnly.CSharp.sln; \
|
||||
dotnet build /onnxruntime_src/csharp/OnnxRuntime.DesktopOnly.CSharp.sln; \
|
||||
dotnet test /onnxruntime_src/csharp/OnnxRuntime.DesktopOnly.CSharp.sln -f net6.0 --no-build -l \"console;verbosity=normal\"; \
|
||||
popd
|
||||
"
|
||||
displayName: 'Dotnet build C# sln and Test'
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: 'Install python deps and run java tests'
|
||||
|
|
@ -245,8 +228,11 @@ stages:
|
|||
- stage: arm64_test
|
||||
dependsOn: ['arm64_build']
|
||||
jobs:
|
||||
- template: templates/py-packaging-linux-test.yml
|
||||
- template: templates/py-packaging-linux-test-cpu.yml
|
||||
parameters:
|
||||
arch: 'aarch64'
|
||||
machine_pool: 'onnxruntime-linux-ARM64-CPU-2019'
|
||||
device: 'CPU'
|
||||
base_image: 'arm64v8/centos:7'
|
||||
devtoolset_rootpath: /opt/rh/devtoolset-10/root
|
||||
ld_library_path_arg: /opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/usr/local/lib64
|
||||
prepend_path: '/opt/rh/devtoolset-10/root/usr/bin:'
|
||||
|
|
|
|||
|
|
@ -50,10 +50,6 @@ jobs:
|
|||
clean: true
|
||||
submodules: recursive
|
||||
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
|
||||
- template: templates/get-docker-image-steps.yml
|
||||
parameters:
|
||||
Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_aten_cpu
|
||||
|
|
|
|||
|
|
@ -33,5 +33,3 @@ jobs:
|
|||
JobName: 'Linux_CI_Multi_GPU_TensorRT_Dev'
|
||||
# The latest TensorRT container only supports ubuntu20.04 and python 3.8
|
||||
RunDockerBuildArgs: '-o ubuntu20.04 -d tensorrt -x "--enable_multi_device_test"'
|
||||
DoNugetPack: 'false'
|
||||
ArtifactName: 'drop-linux'
|
||||
|
|
|
|||
|
|
@ -32,6 +32,4 @@ jobs:
|
|||
AgentPool : 'Linux-CPU-2019'
|
||||
JobName: 'Linux_CI_Dev'
|
||||
RunDockerBuildArgs: '-o ubuntu20.04 -d openvino -v 2023.0.0 -x "--use_openvino CPU_FP32 --build_wheel"'
|
||||
DoNugetPack: 'false'
|
||||
ArtifactName: 'drop-linux'
|
||||
TimeoutInMinutes: 120
|
||||
|
|
|
|||
|
|
@ -50,19 +50,52 @@ stages:
|
|||
script: |
|
||||
ln -sf /data/models $(Build.BinariesDirectory)
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Run Package Test'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '$(Build.SourcesDirectory)/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.sh'
|
||||
arguments: '$(Build.BinariesDirectory)/nuget-artifact $(NuGetPackageVersionNumber)'
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
env:
|
||||
OnnxRuntimeBuildDirectory: $(Build.BinariesDirectory)
|
||||
DisableContribOps: $(DisableContribOps)
|
||||
DisableMlOps: $(DisableMlOps)
|
||||
IsReleaseBuild: $(IsReleaseBuild)
|
||||
PACKAGENAME: ${{ parameters.NugetPackageName }}
|
||||
- ${{if contains(parameters.StageSuffix , 'GPU') }}:
|
||||
- template: ../../templates/get-docker-image-steps.yml
|
||||
parameters:
|
||||
Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.package_ubuntu_cuda11_8_tensorrt8_6
|
||||
Context: tools/ci_build/github/linux/docker/
|
||||
DockerBuildArgs: "--build-arg BUILD_UID=$( id -u )"
|
||||
Repository: onnxruntimepackagestest
|
||||
- bash: |
|
||||
docker run --rm \
|
||||
--gpus all \
|
||||
--volume $(Build.SourcesDirectory):/onnxruntime_src \
|
||||
--volume $(Build.BinariesDirectory):/build \
|
||||
--volume /data/models:/build/models:ro \
|
||||
-e BUILD_SOURCESDIRECTORY='/onnxruntime_src' \
|
||||
-e OnnxRuntimeBuildDirectory='/build' \
|
||||
-e DisableContribOps='$(DisableContribOps)' \
|
||||
-e DisableMlOps='$(DisableMlOps)' \
|
||||
-e IsReleaseBuild='$(IsReleaseBuild)' \
|
||||
-e PACKAGENAME='${{ parameters.NugetPackageName }}' \
|
||||
onnxruntimepackagestest \
|
||||
/bin/bash -c "
|
||||
set -ex; \
|
||||
pushd /build; \
|
||||
bash /onnxruntime_src/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.sh /build/nuget-artifact $(NuGetPackageVersionNumber); \
|
||||
popd
|
||||
"
|
||||
displayName: 'Run Package Test'
|
||||
- ${{ else }}:
|
||||
- task: CmdLine@2
|
||||
displayName: 'Create symlink for test models'
|
||||
inputs:
|
||||
script: |
|
||||
ln -sf /data/models $(Build.BinariesDirectory)
|
||||
- task: Bash@3
|
||||
displayName: 'Run Package Test'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '$(Build.SourcesDirectory)/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.sh'
|
||||
arguments: '$(Build.BinariesDirectory)/nuget-artifact $(NuGetPackageVersionNumber)'
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
env:
|
||||
OnnxRuntimeBuildDirectory: $(Build.BinariesDirectory)
|
||||
DisableContribOps: $(DisableContribOps)
|
||||
DisableMlOps: $(DisableMlOps)
|
||||
IsReleaseBuild: $(IsReleaseBuild)
|
||||
PACKAGENAME: ${{ parameters.NugetPackageName }}
|
||||
|
||||
- template: ../../templates/component-governance-component-detection-steps.yml
|
||||
parameters:
|
||||
|
|
|
|||
|
|
@ -51,10 +51,6 @@ jobs:
|
|||
clean: true
|
||||
submodules: none
|
||||
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.8'
|
||||
|
|
@ -85,6 +81,7 @@ jobs:
|
|||
mkdir -p $(Pipeline.Workspace)/ccache
|
||||
docker run --rm \
|
||||
--volume /data/onnx:/data/onnx:ro \
|
||||
--volume /data/models:/build/models:ro \
|
||||
--volume $(Build.SourcesDirectory):/onnxruntime_src \
|
||||
--volume $(Build.BinariesDirectory):/build \
|
||||
--volume $HOME/.onnx:/home/onnxruntimedev/.onnx \
|
||||
|
|
@ -107,53 +104,11 @@ jobs:
|
|||
--enable_onnx_tests \
|
||||
--enable_training \
|
||||
--use_cache \
|
||||
--build_java --build_nodejs --update --build; \
|
||||
--build_java --build_nodejs; \
|
||||
ccache -sv; \
|
||||
ccache -z"
|
||||
workingDirectory: $(Build.SourcesDirectory)
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: 'Install python deps and run java tests'
|
||||
inputs:
|
||||
script: |
|
||||
set -e -x
|
||||
python3 -m pip uninstall -y ort-nightly-gpu ort-nightly onnxruntime onnxruntime-gpu onnxruntime-training onnxruntime-directml ort-nightly-directml onnx -qq
|
||||
cp $(Build.SourcesDirectory)/tools/ci_build/github/linux/docker/scripts/manylinux/requirements.txt $(Build.BinariesDirectory)/requirements.txt
|
||||
# Test ORT with the latest ONNX release.
|
||||
sed -i "s/git+http:\/\/github\.com\/onnx\/onnx.*/onnx/" $(Build.BinariesDirectory)/requirements.txt
|
||||
python3 -m pip install -r $(Build.BinariesDirectory)/requirements.txt
|
||||
mkdir $(Build.BinariesDirectory)/requirements_torch_cpu/
|
||||
cp $(Build.SourcesDirectory)/tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/requirements_torch_cpu/requirements.txt $(Build.BinariesDirectory)/requirements_torch_cpu/requirements.txt
|
||||
python3 -m pip install -r $(Build.BinariesDirectory)/requirements_torch_cpu/requirements.txt
|
||||
cd $(Build.SourcesDirectory)/java
|
||||
$(Build.SourcesDirectory)/java/gradlew "cmakeCheck" "-DcmakeBuildDir=$(Build.BinariesDirectory)/Release"
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: 'Install Release python package'
|
||||
inputs:
|
||||
script: |
|
||||
rm -rf $(Build.BinariesDirectory)/Release/onnxruntime $(Build.BinariesDirectory)/Release/pybind11
|
||||
python3 -m pip install $(Build.BinariesDirectory)/Release/dist/*.whl
|
||||
|
||||
- task: PythonScript@0
|
||||
displayName: 'Run Release unit tests'
|
||||
inputs:
|
||||
scriptPath: $(Build.SourcesDirectory)/tools/ci_build/build.py
|
||||
workingDirectory: $(Build.BinariesDirectory)/Release
|
||||
arguments: >-
|
||||
--build_dir $(Build.BinariesDirectory)
|
||||
--cmake_generator Ninja
|
||||
--config Release
|
||||
--test
|
||||
--skip_submodule_sync
|
||||
--build_shared_lib
|
||||
--parallel
|
||||
--build_wheel
|
||||
--enable_onnx_tests
|
||||
--enable_training
|
||||
--build_nodejs
|
||||
--ctest_path ""
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish unit test results'
|
||||
inputs:
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ jobs:
|
|||
parameters:
|
||||
AgentPool : 'Onnxruntime-Linux-GPU-NC6sv3'
|
||||
JobName: 'Onnxruntime_Linux_GPU_Training'
|
||||
SubmoduleCheckoutMode: 'recursive'
|
||||
RunDockerBuildArgs: >
|
||||
-o ubuntu20.04 -d gpu
|
||||
-t onnxruntime_orttraining_ortmodule_tests_image
|
||||
|
|
@ -26,24 +25,16 @@ jobs:
|
|||
-e
|
||||
-x "
|
||||
--enable_training
|
||||
--config $(buildConfig)
|
||||
--config Release
|
||||
--use_cuda --cuda_version=11.8 --cuda_home=/usr/local/cuda-11.8 --cudnn_home=/usr/local/cuda-11.8
|
||||
--build_wheel
|
||||
--enable_nvtx_profile
|
||||
--cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=70
|
||||
"
|
||||
DoNugetPack: 'false'
|
||||
RunInjectedPipeline: 'true'
|
||||
InjectedPipeline: 'orttraining-linux-gpu-ortmodule-test-ci-pipeline.yml'
|
||||
DockerImageTag: 'onnxruntime_orttraining_ortmodule_tests_image'
|
||||
BuildConfig: $(buildConfig)
|
||||
ArtifactName: 'drop-linux'
|
||||
TimeoutInMinutes: 140
|
||||
# Enable unreleased onnx opsets in CI builds
|
||||
# This facilitates testing the implementation for the new opsets
|
||||
AllowReleasedOpsetOnly: '0'
|
||||
Strategy:
|
||||
maxParallel: 2
|
||||
matrix:
|
||||
Release:
|
||||
buildConfig: Release
|
||||
|
|
|
|||
|
|
@ -3,24 +3,38 @@ resources:
|
|||
- pipeline: build
|
||||
source: 'Python packaging pipeline'
|
||||
trigger: true
|
||||
branch: rel-1.16.0 # branch to pick the artifact, Used only for manual triggered pipeline runs for testing the pipeline itself
|
||||
#TODO: Remove the following dependency. Running python tests should not need to use manylinux.
|
||||
repositories:
|
||||
- repository: manylinux # The name used to reference this repository in the checkout step
|
||||
type: Github
|
||||
endpoint: Microsoft
|
||||
name: pypa/manylinux
|
||||
ref: 5eda9aded5462201e6310105728d33016e637ea7
|
||||
|
||||
stages:
|
||||
- stage: Linux_Test_CPU_x86_64_stage
|
||||
jobs:
|
||||
- template: templates/py-packaging-linux-test.yml
|
||||
- template: templates/py-packaging-linux-test-cpu.yml
|
||||
parameters:
|
||||
arch: 'x86_64'
|
||||
machine_pool: 'onnxruntime-Ubuntu2004-AMD-CPU'
|
||||
device: 'CPU'
|
||||
base_image: 'centos:7'
|
||||
devtoolset_rootpath: /opt/rh/devtoolset-11/root
|
||||
ld_library_path_arg: /opt/rh/devtoolset-11/root/usr/lib64:/opt/rh/devtoolset-11/root/usr/lib:/opt/rh/devtoolset-11/root/usr/lib64/dyninst:/opt/rh/devtoolset-11/root/usr/lib/dyninst:/usr/local/lib64
|
||||
prepend_path: '/opt/rh/devtoolset-11/root/usr/bin:'
|
||||
|
||||
- stage: Linux_Test_CPU_aarch64_stage
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/py-packaging-linux-test.yml
|
||||
- template: templates/py-packaging-linux-test-cpu.yml
|
||||
parameters:
|
||||
arch: 'aarch64'
|
||||
machine_pool: 'aiinfra-linux-ARM64-CPU-2019'
|
||||
device: 'CPU'
|
||||
base_image: 'arm64v8/centos:7'
|
||||
devtoolset_rootpath: /opt/rh/devtoolset-10/root
|
||||
ld_library_path_arg: /opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/usr/local/lib64
|
||||
prepend_path: '/opt/rh/devtoolset-10/root/usr/bin:'
|
||||
|
||||
- stage: Packages_Somking_Test
|
||||
dependsOn: []
|
||||
|
|
@ -31,19 +45,6 @@ stages:
|
|||
machine_pool:
|
||||
vmImage: 'macOS-13'
|
||||
itemPattern: '*/*mac*x86_64.whl'
|
||||
- template: templates/py-package-smoking-test.yml
|
||||
parameters:
|
||||
job_name: Test_WIN_64_Wheels
|
||||
itemPattern: '*/*win_amd64.whl'
|
||||
machine_pool:
|
||||
vmImage: 'windows-2022'
|
||||
- template: templates/py-package-smoking-test.yml
|
||||
parameters:
|
||||
job_name: Test_WIN_32_Wheels
|
||||
itemPattern: '*/*win32.whl'
|
||||
python_arch: 'x86'
|
||||
machine_pool:
|
||||
vmImage: 'windows-2022'
|
||||
- template: templates/py-package-smoking-test.yml
|
||||
parameters:
|
||||
job_name: Test_LINUX_x86_64_Wheels
|
||||
|
|
@ -61,7 +62,7 @@ stages:
|
|||
- Linux_Test_CPU_aarch64_stage
|
||||
- Packages_Somking_Test
|
||||
jobs:
|
||||
- template: templates/py-packaging-linux-test.yml
|
||||
- template: templates/py-packaging-linux-test-cuda.yml
|
||||
parameters:
|
||||
arch: 'x86_64'
|
||||
machine_pool: 'Onnxruntime-Linux-GPU'
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ parameters:
|
|||
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: ${{ parameters.StepName }}}
|
||||
displayName: ${{ parameters.StepName }}
|
||||
inputs:
|
||||
artifactName: ${{ parameters.ArtifactName}}
|
||||
targetPath: '${{ parameters.TargetPath }}'
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ jobs:
|
|||
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
force32bit: ${{ parameters.isX86 }}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,14 @@
|
|||
parameters:
|
||||
AgentPool : 'onnxruntime-Ubuntu2004-AMD-CPU'
|
||||
StageName : 'Linux_CI_Dev'
|
||||
SubmoduleCheckoutMode: ''
|
||||
RunDockerBuildArgs: '-o ubuntu20.04 -d cpu -x "--build_wheel"'
|
||||
DoNodejsPack: 'false'
|
||||
DoNugetPack: 'false'
|
||||
NuPackScript: ''
|
||||
RunInjectedPipeline: 'false'
|
||||
InjectedPipeline: ''
|
||||
DockerImageTag: ''
|
||||
BuildConfig: ''
|
||||
ArtifactName: 'drop-linux'
|
||||
TimeoutInMinutes: 120
|
||||
# Controls whether unreleased onnx opsets are allowed. Default is set to 1
|
||||
AllowReleasedOpsetOnly: '1'
|
||||
# to inject strategy, you need to pass in the whole yaml structure -
|
||||
# https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#strategies
|
||||
# see example in orttraining-linux-gpu-ci-pipeline.yml
|
||||
Strategy: ''
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.StageName }}
|
||||
|
|
@ -28,16 +19,8 @@ jobs:
|
|||
ALLOW_RELEASED_ONNX_OPSET_ONLY: ${{ parameters.AllowReleasedOpsetOnly }}
|
||||
skipComponentGovernanceDetection: true
|
||||
pool: ${{ parameters.AgentPool }}
|
||||
${{ if ne(parameters.Strategy, '') }}:
|
||||
strategy:
|
||||
${{ parameters.Strategy }}
|
||||
steps:
|
||||
- checkout: self
|
||||
${{ if ne(parameters.SubmoduleCheckoutMode, '') }}:
|
||||
submodules: ${{ parameters.SubmoduleCheckoutMode }}
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
- template: run-docker-build-steps.yml
|
||||
parameters:
|
||||
RunDockerBuildArgs: '${{ parameters.RunDockerBuildArgs }}'
|
||||
|
|
@ -48,31 +31,10 @@ jobs:
|
|||
searchFolder: '$(Build.BinariesDirectory)'
|
||||
testRunTitle: 'Unit Test Run'
|
||||
condition: succeededOrFailed()
|
||||
- ${{ if eq(parameters['DoNugetPack'], 'true') }}:
|
||||
- script: |
|
||||
${{ parameters.NuPackScript }}
|
||||
displayName: 'Create Artifacts'
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Pipeline Artifact'
|
||||
inputs:
|
||||
artifactName: ${{ parameters.ArtifactName }}
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||
- ${{ if eq(parameters['DoNodejsPack'], 'true') }}:
|
||||
- script: |
|
||||
npm pack
|
||||
cp $(Build.SourcesDirectory)/js/node/onnxruntime-*.tgz $(Build.ArtifactStagingDirectory)
|
||||
cp -R $(Build.SourcesDirectory)/js/node/prebuilds $(Build.ArtifactStagingDirectory)/prebuilds
|
||||
workingDirectory: '$(Build.SourcesDirectory)/js/node'
|
||||
displayName: 'Create NPM Package'
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish Pipeline Artifact: ${{ parameters.ArtifactName }}'
|
||||
inputs:
|
||||
artifactName: ${{ parameters.ArtifactName }}
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||
- ${{ if eq(parameters['RunInjectedPipeline'], 'true') }}:
|
||||
- template: |
|
||||
${{ parameters.InjectedPipeline }}
|
||||
parameters:
|
||||
DockerImageTag: ${{ parameters.DockerImageTag }}
|
||||
BuildConfig: ${{ parameters.BuildConfig }}
|
||||
BuildConfig: Release
|
||||
- template: clean-agent-build-directory-step.yml
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ jobs:
|
|||
architecture: $(buildArch)
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
- template: download-deps.yml
|
||||
|
||||
- task: PythonScript@0
|
||||
|
|
@ -94,7 +94,6 @@ jobs:
|
|||
cd '$(Build.SourcesDirectory)/cmake/external/emsdk'
|
||||
./emsdk install 3.1.44 ccache-git-emscripten-64bit
|
||||
./emsdk activate 3.1.44 ccache-git-emscripten-64bit
|
||||
ln -s $(Build.SourcesDirectory)/cmake/external/emsdk/ccache/git-emscripten_64bit/bin/ccache /usr/local/bin/ccache
|
||||
displayName: 'emsdk install and activate ccache for emscripten'
|
||||
condition: eq('${{ parameters.WithCache }}', 'true')
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
versionSpec: 3.11
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
|
||||
- template: set-version-number-variables-step.yml
|
||||
|
||||
|
|
|
|||
|
|
@ -39,36 +39,22 @@ jobs:
|
|||
versionSpec: $(PythonVersion)
|
||||
architecture: ${{ parameters.python_arch }}
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Pipeline Artifact'
|
||||
inputs:
|
||||
artifactName: 'onnxruntime'
|
||||
targetPath: '$(Build.BinariesDirectory)/whl'
|
||||
itemPattern: ${{parameters.itemPattern}}
|
||||
# The public ADO project
|
||||
${{ if eq(variables['System.CollectionId'], 'f3ad12f2-e480-4533-baf2-635c95467d29') }}:
|
||||
buildType: current
|
||||
# The private ADO project
|
||||
${{ if eq(variables['System.CollectionId'], 'bc038106-a83b-4dab-9dd3-5a41bc58f34c') }}:
|
||||
project: '530acbc4-21bc-487d-8cd8-348ff451d2ff'
|
||||
definition: 841
|
||||
preferTriggeringPipeline: true
|
||||
runVersion: 'latest'
|
||||
buildType: specific
|
||||
- download: build # pipeline resource identifier.
|
||||
artifact: 'onnxruntime'
|
||||
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
set -ex
|
||||
files=(whl/*.whl)
|
||||
files=(*.whl)
|
||||
FILE_NAME="${files[0]}"
|
||||
FILE_NAME=$(basename $FILE_NAME)
|
||||
PYTHON_PACKAGE_NAME=$(echo "$FILE_NAME" | cut -f 1 -d '-')
|
||||
python3 -m pip install --find-links "$(Build.BinariesDirectory)/whl" $PYTHON_PACKAGE_NAME
|
||||
pip show $PYTHON_PACKAGE_NAME
|
||||
python -c "import onnxruntime as ort; print(ort.__version__)"
|
||||
workingDirectory: $(Build.BinariesDirectory)
|
||||
python3 -m pip install --find-links "$(Pipeline.Workspace)/build/onnxruntime" $PYTHON_PACKAGE_NAME
|
||||
python3 -m pip show $PYTHON_PACKAGE_NAME
|
||||
python3 -c "import onnxruntime as ort; print(ort.__version__)"
|
||||
workingDirectory: $(Pipeline.Workspace)/build/onnxruntime
|
||||
displayName: Test Package Installation
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
parameters:
|
||||
- name: arch
|
||||
type: string
|
||||
|
||||
- name: base_image
|
||||
type: string
|
||||
|
||||
- name: devtoolset_rootpath
|
||||
type: string
|
||||
|
||||
- name: ld_library_path_arg
|
||||
type: string
|
||||
|
||||
- name: prepend_path
|
||||
type: string
|
||||
|
||||
- name: machine_pool
|
||||
type: string
|
||||
|
||||
- name: extra_job_id
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: python_wheel_suffix
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
|
||||
# TODO: Ideally it should fetch information from the build that triggers it
|
||||
- name: cmake_build_type
|
||||
type: string
|
||||
default: 'Release'
|
||||
values:
|
||||
- Debug
|
||||
- Release
|
||||
- RelWithDebInfo
|
||||
- MinSizeRel
|
||||
|
||||
- name: timeout
|
||||
type: number
|
||||
default: 120
|
||||
|
||||
jobs:
|
||||
- job: Linux_Test_CPU${{ parameters.extra_job_id }}_${{ parameters.arch }}
|
||||
timeoutInMinutes: ${{ parameters.timeout }}
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
workspace:
|
||||
clean: all
|
||||
pool: ${{ parameters.machine_pool }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: none
|
||||
# The public ADO project
|
||||
- ${{ if eq(variables['System.CollectionId'], 'f3ad12f2-e480-4533-baf2-635c95467d29') }}:
|
||||
- download: current # pipeline resource identifier.
|
||||
artifact: 'drop-linux-cpu-${{ parameters.arch }}'
|
||||
|
||||
- download: current # pipeline resource identifier.
|
||||
artifact: 'onnxruntime${{ parameters.python_wheel_suffix }}'
|
||||
|
||||
- bash: |
|
||||
set -e -x
|
||||
mv "$(Pipeline.Workspace)/drop-linux-cpu-${{ parameters.arch }}" $(Build.BinariesDirectory)/${{parameters.cmake_build_type}}
|
||||
mv "$(Pipeline.Workspace)/onnxruntime${{ parameters.python_wheel_suffix }}" "$(Build.BinariesDirectory)/whl"
|
||||
cp -r "$(Build.BinariesDirectory)/whl" $(Build.BinariesDirectory)/tmp
|
||||
find "$(Build.BinariesDirectory)/tmp" -name '*.whl' -exec bash -c 'unzip -d "${1%.*}" "$1"' _ {} \;
|
||||
# The private ADO project
|
||||
- ${{ if eq(variables['System.CollectionId'], 'bc038106-a83b-4dab-9dd3-5a41bc58f34c') }}:
|
||||
- download: build # pipeline resource identifier.
|
||||
artifact: 'drop-linux-cpu-${{ parameters.arch }}'
|
||||
|
||||
- download: build # pipeline resource identifier.
|
||||
artifact: 'onnxruntime${{ parameters.python_wheel_suffix }}'
|
||||
|
||||
- bash: |
|
||||
set -e -x
|
||||
ls $(Pipeline.Workspace)/build
|
||||
mv "$(Pipeline.Workspace)/build/drop-linux-cpu-${{ parameters.arch }}" $(Build.BinariesDirectory)/${{parameters.cmake_build_type}}
|
||||
mv "$(Pipeline.Workspace)/build/onnxruntime${{ parameters.python_wheel_suffix }}" "$(Build.BinariesDirectory)/whl"
|
||||
cp -r "$(Build.BinariesDirectory)/whl" $(Build.BinariesDirectory)/tmp
|
||||
find "$(Build.BinariesDirectory)/tmp" -name '*.whl' -exec bash -c 'unzip -d "${1%.*}" "$1"' _ {} \;
|
||||
|
||||
# The BinSkim task uses a dotnet program which doesn't support ARM CPUs yet
|
||||
- ${{ if eq(parameters.arch, 'x86_64') }}:
|
||||
- task: BinSkim@4
|
||||
displayName: 'Run BinSkim'
|
||||
inputs:
|
||||
AnalyzeTargetGlob: '$(Build.BinariesDirectory)/tmp/**/*.so'
|
||||
continueOnError: true
|
||||
|
||||
- template: get-docker-image-steps.yml
|
||||
parameters:
|
||||
Dockerfile: tools/ci_build/github/linux/docker/inference/x64/python/cpu/Dockerfile.manylinux2014_cpu
|
||||
Context: tools/ci_build/github/linux/docker/inference/x64/python/cpu
|
||||
DockerBuildArgs: "--build-arg BUILD_UID=$( id -u ) --build-arg BASEIMAGE=${{ parameters.base_image }} --build-arg PLATFORM=${{ parameters.arch }} --build-arg PREPEND_PATH=${{ parameters.prepend_path }} --build-arg LD_LIBRARY_PATH_ARG=${{ parameters.ld_library_path_arg }} --build-arg DEVTOOLSET_ROOTPATH=${{ parameters.devtoolset_rootpath }}"
|
||||
Repository: onnxruntimecpubuildpython${{ parameters.arch }}
|
||||
${{ if eq(parameters.arch, 'aarch64') }}:
|
||||
UpdateDepsTxt: false
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Bash Script'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: tools/ci_build/github/linux/run_python_dockertest.sh
|
||||
arguments: -d CPU -c ${{parameters.cmake_build_type}} -i onnxruntimecpubuildpython${{ parameters.arch }}
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
displayName: 'Clean Agent Directories'
|
||||
condition: always()
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
parameters:
|
||||
- name: arch
|
||||
type: string
|
||||
|
||||
- name: device
|
||||
type: string
|
||||
values:
|
||||
- CPU
|
||||
- GPU
|
||||
|
||||
- name: machine_pool
|
||||
type: string
|
||||
|
||||
- name: extra_job_id
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: python_wheel_suffix
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
|
||||
# TODO: Ideally it should fetch information from the build that triggers it
|
||||
- name: cmake_build_type
|
||||
type: string
|
||||
default: 'Release'
|
||||
values:
|
||||
- Debug
|
||||
- Release
|
||||
- RelWithDebInfo
|
||||
- MinSizeRel
|
||||
|
||||
- name: timeout
|
||||
type: number
|
||||
default: 120
|
||||
|
||||
jobs:
|
||||
- job: Linux_Test_GPU${{ parameters.extra_job_id }}_${{ parameters.arch }}
|
||||
timeoutInMinutes: ${{ parameters.timeout }}
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
workspace:
|
||||
clean: all
|
||||
pool: ${{ parameters.machine_pool }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: none
|
||||
# The public ADO project
|
||||
# - ${{ if eq(variables['System.CollectionId'], 'f3ad12f2-e480-4533-baf2-635c95467d29') }}:
|
||||
|
||||
# The private ADO project
|
||||
- ${{ if eq(variables['System.CollectionId'], 'bc038106-a83b-4dab-9dd3-5a41bc58f34c') }}:
|
||||
- download: build # pipeline resource identifier.
|
||||
artifact: 'drop-linux-gpu-${{ parameters.arch }}'
|
||||
|
||||
- download: build # pipeline resource identifier.
|
||||
artifact: 'onnxruntime${{ parameters.python_wheel_suffix }}'
|
||||
|
||||
- bash: |
|
||||
set -e -x
|
||||
ls $(Pipeline.Workspace)/build
|
||||
mv "$(Pipeline.Workspace)/build/drop-linux-gpu-${{ parameters.arch }}" $(Build.BinariesDirectory)/${{parameters.cmake_build_type}}
|
||||
mv "$(Pipeline.Workspace)/build/onnxruntime${{ parameters.python_wheel_suffix }}" "$(Build.BinariesDirectory)/whl"
|
||||
cp -r "$(Build.BinariesDirectory)/whl" $(Build.BinariesDirectory)/tmp
|
||||
find "$(Build.BinariesDirectory)/tmp" -name '*.whl' -exec bash -c 'unzip -d "${1%.*}" "$1"' _ {} \;
|
||||
|
||||
# The BinSkim task uses a dotnet program which doesn't support ARM CPUs yet
|
||||
- ${{ if eq(parameters.arch, 'x86_64') }}:
|
||||
- task: BinSkim@4
|
||||
displayName: 'Run BinSkim'
|
||||
inputs:
|
||||
AnalyzeTargetGlob: '$(Build.BinariesDirectory)/tmp/**/*.so'
|
||||
continueOnError: true
|
||||
|
||||
|
||||
- template: get-docker-image-steps.yml
|
||||
parameters:
|
||||
Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2014_cuda11_8_tensorrt8_6
|
||||
Context: tools/ci_build/github/linux/docker
|
||||
DockerBuildArgs: "--network=host --build-arg POLICY=manylinux2014 --build-arg PLATFORM=x86_64 --build-arg DEVTOOLSET_ROOTPATH=/opt/rh/devtoolset-11/root --build-arg PREPEND_PATH=/opt/rh/devtoolset-11/root/usr/bin: --build-arg LD_LIBRARY_PATH_ARG=/opt/rh/devtoolset-11/root/usr/lib64:/opt/rh/devtoolset-11/root/usr/lib:/opt/rh/devtoolset-11/root/usr/lib64/dyninst:/opt/rh/devtoolset-11/root/usr/lib/dyninst:/usr/local/lib64 --build-arg BUILD_UID=$( id -u ) --build-arg PLATFORM=${{ parameters.arch }}"
|
||||
Repository: onnxruntimecuda118xtrt86build${{ parameters.arch }}
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Bash Script'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: tools/ci_build/github/linux/run_python_dockertest.sh
|
||||
arguments: -d GPU -c ${{parameters.cmake_build_type}} -i onnxruntimecuda118xtrt86build${{ parameters.arch }}
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
displayName: 'Clean Agent Directories'
|
||||
condition: always()
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
parameters:
|
||||
- name: arch
|
||||
type: string
|
||||
|
||||
- name: device
|
||||
type: string
|
||||
|
||||
- name: machine_pool
|
||||
type: string
|
||||
|
||||
- name: extra_job_id
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: python_wheel_suffix
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
|
||||
# TODO: Ideally it should fetch information from the build that triggers it
|
||||
- name: cmake_build_type
|
||||
type: string
|
||||
default: 'Release'
|
||||
values:
|
||||
- Debug
|
||||
- Release
|
||||
- RelWithDebInfo
|
||||
- MinSizeRel
|
||||
|
||||
- name: timeout
|
||||
type: number
|
||||
default: 120
|
||||
|
||||
jobs:
|
||||
- job: Linux_Test_${{ parameters.device }}${{ parameters.extra_job_id }}_${{ parameters.arch }}
|
||||
timeoutInMinutes: ${{ parameters.timeout }}
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
workspace:
|
||||
clean: all
|
||||
pool: ${{ parameters.machine_pool }}
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Pipeline Artifact'
|
||||
inputs:
|
||||
artifactName: 'drop-linux-${{ lower(parameters.device) }}-${{ parameters.arch }}'
|
||||
targetPath: '$(Build.BinariesDirectory)/${{parameters.cmake_build_type}}'
|
||||
# The public ADO project
|
||||
${{ if eq(variables['System.CollectionId'], 'f3ad12f2-e480-4533-baf2-635c95467d29') }}:
|
||||
buildType: current
|
||||
# The private ADO project
|
||||
${{ if eq(variables['System.CollectionId'], 'bc038106-a83b-4dab-9dd3-5a41bc58f34c') }}:
|
||||
project: '530acbc4-21bc-487d-8cd8-348ff451d2ff'
|
||||
definition: 841
|
||||
preferTriggeringPipeline: true
|
||||
runVersion: 'latest'
|
||||
buildType: specific
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Pipeline Artifact'
|
||||
inputs:
|
||||
artifactName: 'onnxruntime${{ parameters.python_wheel_suffix }}'
|
||||
targetPath: '$(Build.BinariesDirectory)/whl'
|
||||
# The public ADO project
|
||||
${{ if eq(variables['System.CollectionId'], 'f3ad12f2-e480-4533-baf2-635c95467d29') }}:
|
||||
buildType: current
|
||||
# The private ADO project
|
||||
${{ if eq(variables['System.CollectionId'], 'bc038106-a83b-4dab-9dd3-5a41bc58f34c') }}:
|
||||
project: '530acbc4-21bc-487d-8cd8-348ff451d2ff'
|
||||
definition: 841
|
||||
preferTriggeringPipeline: true
|
||||
runVersion: 'latest'
|
||||
buildType: specific
|
||||
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Bash Script'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: tools/ci_build/github/linux/run_python_tests.sh
|
||||
arguments: -d ${{ parameters.device }} -c ${{parameters.cmake_build_type}}
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
displayName: 'Clean Agent Directories'
|
||||
condition: always()
|
||||
|
|
@ -80,7 +80,7 @@ stages:
|
|||
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
|
||||
- script:
|
||||
brew install coreutils ninja npm yarn
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
patterns: 'Release_*/**/*'
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ stages:
|
|||
displayName: 'Checkout submodule onnx'
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
- template: linux-web-init-and-check.yml
|
||||
- task: Bash@3
|
||||
displayName: 'Extract commit SHA and save to __commit.txt'
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ stages:
|
|||
- task: NodeTool@0
|
||||
condition: and(succeeded(), eq('${{ parameters.buildNodejs}}', true))
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
|
||||
- template: jobs/set-winenv.yml
|
||||
parameters:
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ jobs:
|
|||
architecture: $(buildArch)
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
- template: download-deps.yml
|
||||
|
||||
- task: PythonScript@0
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ jobs:
|
|||
displayName: 'Testing: force EOL to lf on windows for /js/**'
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
patterns: '${{ parameters.BuildConfig }}_*/**/*'
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
displayName: 'Checkout submodule onnx'
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
patterns: 'Release_*/**/*'
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '16.x'
|
||||
versionSpec: '18.x'
|
||||
|
||||
- task: BatchScript@1
|
||||
displayName: 'setup env'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
export CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -fstack-clash-protection -fcf-protection -O3 -Wl,--strip-all"
|
||||
export CXXFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -fstack-clash-protection -fcf-protection -O3 -Wl,--strip-all"
|
||||
docker run --gpus all -e CFLAGS -e CXXFLAGS -e NVIDIA_VISIBLE_DEVICES=all --rm --volume \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
set -e -x
|
||||
|
||||
# This script invokes build.py
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
set -e -o -x
|
||||
SCRIPT_DIR="$( dirname "${BASH_SOURCE[0]}" )"
|
||||
TARGET_FOLDER="/datadrive/ARM"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
set -e -o -x
|
||||
|
||||
while getopts r:a:l:c:s:t: parameter_Option
|
||||
|
|
@ -44,6 +46,7 @@ fi
|
|||
cp $SOURCE_DIR/include/onnxruntime/core/session/onnxruntime_c_api.h $BINARY_DIR/$ARTIFACT_NAME/include
|
||||
cp $SOURCE_DIR/include/onnxruntime/core/session/onnxruntime_cxx_api.h $BINARY_DIR/$ARTIFACT_NAME/include
|
||||
cp $SOURCE_DIR/include/onnxruntime/core/session/onnxruntime_cxx_inline.h $BINARY_DIR/$ARTIFACT_NAME/include
|
||||
cp $SOURCE_DIR/include/onnxruntime/core/session/onnxruntime_float16.h $BINARY_DIR/$ARTIFACT_NAME/include
|
||||
cp $SOURCE_DIR/include/onnxruntime/core/providers/cpu/cpu_provider_factory.h $BINARY_DIR/$ARTIFACT_NAME/include
|
||||
cp $SOURCE_DIR/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h $BINARY_DIR/$ARTIFACT_NAME/include
|
||||
cp $SOURCE_DIR/include/onnxruntime/core/session/onnxruntime_run_options_config_keys.h $BINARY_DIR/$ARTIFACT_NAME/include
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
set -e
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPT_DIR=`dirname $SCRIPT`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
# --------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
# --------------------------------------------------------------
|
||||
# Dockerfile to Test ONNX Runtime on UBI8 with CUDA 11.8 and TensorRT 8.6
|
||||
|
||||
# Build base image with required system packages
|
||||
FROM nvidia/cuda:11.8.0-cudnn8-devel-ubi8 AS base
|
||||
|
||||
ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/src/tensorrt/bin:${PATH}
|
||||
|
||||
RUN dnf install -y bash wget &&\
|
||||
dnf clean dbcache
|
||||
|
||||
# Install python3
|
||||
RUN dnf install -y \
|
||||
python3.8 \
|
||||
python38-pip \
|
||||
python38-wheel &&\
|
||||
cd /usr/local/bin &&\
|
||||
ln -s /usr/bin/python3 python3.8 &&\
|
||||
ln -s /usr/bin/pip3 pip3.8;
|
||||
|
||||
RUN pip3 install --upgrade pip
|
||||
RUN pip3 install setuptools>=41.0.0
|
||||
|
||||
# Install TensorRT
|
||||
RUN dnf install -y libnvinfer8 libnvonnxparsers8 libnvparsers8 libnvinfer-plugin8 libnvinfer-lean8 libnvinfer-vc-plugin8 libnvinfer-dispatch8
|
||||
RUN v="8.6.1.6-1+cuda11.8" &&\
|
||||
dnf downgrade -y libnvinfer8-${v} libnvinfer8-${v} libnvonnxparsers8-${v} libnvparsers8-${v} libnvinfer-plugin8-${v} libnvinfer-lean8-${v} libnvinfer-vc-plugin8-${v} libnvinfer-dispatch8-${v} &&\
|
||||
dnf install -y dnf-plugin-versionlock &&\
|
||||
dnf versionlock libnvinfer8 libnvonnxparsers8 libnvparsers8 libnvinfer-plugin8 libnvinfer-lean8 libnvinfer-vc-plugin8 libnvinfer-dispatch8
|
||||
RUN dnf clean dbcache
|
||||
|
||||
|
||||
ADD scripts /tmp/scripts
|
||||
RUN cd /tmp/scripts && /tmp/scripts/install_dotnet.sh && /tmp/scripts/install_java.sh && rm -rf /tmp/scripts
|
||||
|
||||
# Build final image from base.
|
||||
FROM base as final
|
||||
ARG BUILD_USER=onnxruntimedev
|
||||
ARG BUILD_UID=1000
|
||||
RUN adduser --uid $BUILD_UID $BUILD_USER
|
||||
WORKDIR /home/$BUILD_USER
|
||||
USER $BUILD_USER
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# --------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
# --------------------------------------------------------------
|
||||
# Dockerfile to run ONNXRuntime with TensorRT integration
|
||||
|
||||
# Build base image with required system packages
|
||||
FROM nvidia/cuda:11.8.0-cudnn8-devel-ubuntu20.04 AS base
|
||||
|
||||
# The local directory into which to build and install CMAKE
|
||||
ARG ONNXRUNTIME_LOCAL_CODE_DIR=/code
|
||||
|
||||
ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/src/tensorrt/bin:${ONNXRUNTIME_LOCAL_CODE_DIR}/cmake-3.27.3-linux-x86_64/bin:/opt/miniconda/bin:${PATH}
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update &&\
|
||||
apt-get install -y sudo git bash unattended-upgrades wget
|
||||
RUN unattended-upgrade
|
||||
|
||||
# Install python3
|
||||
RUN apt-get install -y --no-install-recommends \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-dev \
|
||||
python3-wheel &&\
|
||||
cd /usr/local/bin &&\
|
||||
ln -s /usr/bin/python3 python &&\
|
||||
ln -s /usr/bin/pip3 pip;
|
||||
|
||||
RUN pip install --upgrade pip
|
||||
RUN pip install setuptools>=41.0.0
|
||||
|
||||
# Install TensorRT
|
||||
RUN v="8.6.1.6-1+cuda11.8" &&\
|
||||
apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub &&\
|
||||
apt-get update &&\
|
||||
sudo apt-get install -y libnvinfer8=${v} libnvonnxparsers8=${v} libnvparsers8=${v} libnvinfer-plugin8=${v} libnvinfer-lean8=${v} libnvinfer-vc-plugin8=${v} libnvinfer-dispatch8=${v}\
|
||||
libnvinfer-headers-dev=${v} libnvinfer-headers-plugin-dev=${v} libnvinfer-dev=${v} libnvonnxparsers-dev=${v} libnvparsers-dev=${v} libnvinfer-plugin-dev=${v} libnvinfer-lean-dev=${v} libnvinfer-vc-plugin-dev=${v} libnvinfer-dispatch-dev=${v}\
|
||||
python3-libnvinfer=${v} libnvinfer-samples=${v} tensorrt-dev=${v} tensorrt-libs=${v}
|
||||
|
||||
# Install Valgrind
|
||||
RUN apt-get install -y valgrind
|
||||
|
||||
ADD scripts /tmp/scripts
|
||||
RUN cd /tmp/scripts && /tmp/scripts/install_dotnet.sh && rm -rf /tmp/scripts
|
||||
|
||||
# Build final image from base.
|
||||
FROM base as final
|
||||
ARG BUILD_USER=onnxruntimedev
|
||||
ARG BUILD_UID=1000
|
||||
RUN adduser --uid $BUILD_UID $BUILD_USER
|
||||
WORKDIR /home/$BUILD_USER
|
||||
USER $BUILD_USER
|
||||
|
|
@ -6,5 +6,5 @@ setuptools>=41.4.0
|
|||
wheel
|
||||
git+http://github.com/onnx/onnx.git@e2525550194ce3d8a2c4a3af451c9d9b3ae6650e#egg=onnx
|
||||
protobuf==3.20.2
|
||||
sympy==1.10.1
|
||||
sympy==1.12
|
||||
flatbuffers
|
||||
|
|
|
|||
24
tools/ci_build/github/linux/docker/scripts/install_dotnet.sh
Executable file
24
tools/ci_build/github/linux/docker/scripts/install_dotnet.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
set -e -x
|
||||
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
|
||||
yum install -y dotnet-sdk-6.0
|
||||
elif [ -f /etc/os-release ]; then
|
||||
# Get Ubuntu version
|
||||
declare repo_version=$(if command -v lsb_release &> /dev/null; then lsb_release -r -s; else grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"'; fi)
|
||||
# Download Microsoft signing key and repository
|
||||
wget https://packages.microsoft.com/config/ubuntu/$repo_version/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||
# Install Microsoft signing key and repository
|
||||
dpkg -i packages-microsoft-prod.deb
|
||||
# Clean up
|
||||
rm packages-microsoft-prod.deb
|
||||
# Update packages
|
||||
apt-get update && apt-get install -y dotnet-sdk-6.0
|
||||
else
|
||||
echo "Unsupported OS"
|
||||
exit 1
|
||||
fi
|
||||
12
tools/ci_build/github/linux/docker/scripts/install_java.sh
Executable file
12
tools/ci_build/github/linux/docker/scripts/install_java.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
set -e -x
|
||||
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
dnf install -y java-11-openjdk-devel \
|
||||
&& dnf clean dbcache
|
||||
elif [ -f /etc/os-release ]; then
|
||||
apt-get update && apt-get install -y openjdk-11-jdk
|
||||
else
|
||||
echo "Unsupported OS"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -13,6 +13,9 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Install dotnet
|
||||
source $(cd "$(dirname "${BASH_SOURCE[0]}")/.." &> /dev/null && pwd)/install_dotnet.sh
|
||||
|
||||
if [ ! -d "/opt/conda/bin" ]; then
|
||||
PYTHON_EXES=("/opt/python/cp38-cp38/bin/python3.8" "/opt/python/cp39-cp39/bin/python3.9" "/opt/python/cp310-cp310/bin/python3.10" "/opt/python/cp311-cp311/bin/python3.11")
|
||||
else
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@ setuptools>=41.4.0
|
|||
wheel
|
||||
git+http://github.com/onnx/onnx.git@e2525550194ce3d8a2c4a3af451c9d9b3ae6650e#egg=onnx
|
||||
protobuf==3.20.2
|
||||
sympy==1.10.1
|
||||
sympy==1.12
|
||||
flatbuffers
|
||||
neural-compressor>=2.2.1
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ setuptools>=41.4.0
|
|||
wheel>=0.35.1
|
||||
git+http://github.com/onnx/onnx.git@e2525550194ce3d8a2c4a3af451c9d9b3ae6650e#egg=onnx
|
||||
argparse
|
||||
sympy==1.10.1
|
||||
sympy==1.12
|
||||
flatbuffers
|
||||
protobuf==3.20.2
|
||||
packaging
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
set -e -o -x
|
||||
|
||||
while getopts a: parameter_Option
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
set -e -o -x
|
||||
|
||||
while getopts r:a:l:n:c:h:v: parameter_Option
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
set -e -x
|
||||
BUILD_CONFIG="Release"
|
||||
|
||||
|
|
|
|||
31
tools/ci_build/github/linux/run_python_dockertest.sh
Executable file
31
tools/ci_build/github/linux/run_python_dockertest.sh
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
set -e -x
|
||||
BUILD_CONFIG="Release"
|
||||
|
||||
while getopts "i:d:x:c:" parameter_Option
|
||||
do case "${parameter_Option}"
|
||||
in
|
||||
i) DOCKER_IMAGE=${OPTARG};;
|
||||
d) DEVICE=${OPTARG};;
|
||||
c) BUILD_CONFIG=${OPTARG};;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $DEVICE = "GPU" ]; then
|
||||
ADDITIONAL_DOCKER_PARAMETER="--gpus all"
|
||||
fi
|
||||
|
||||
mkdir -p $HOME/.onnx
|
||||
docker run --rm \
|
||||
--volume /data/onnx:/data/onnx:ro \
|
||||
--volume $BUILD_SOURCESDIRECTORY:/onnxruntime_src \
|
||||
--volume $BUILD_BINARIESDIRECTORY:/build \
|
||||
--volume /data/models:/build/models:ro \
|
||||
--volume $HOME/.onnx:/home/onnxruntimedev/.onnx \
|
||||
-w /onnxruntime_src \
|
||||
-e NIGHTLY_BUILD \
|
||||
-e BUILD_BUILDNUMBER \
|
||||
$ADDITIONAL_DOCKER_PARAMETER \
|
||||
$DOCKER_IMAGE tools/ci_build/github/linux/run_python_tests.sh -d $DEVICE -c $BUILD_CONFIG
|
||||
|
|
@ -15,7 +15,8 @@ c) BUILD_CONFIG=${OPTARG};;
|
|||
esac
|
||||
done
|
||||
|
||||
cd $BUILD_BINARIESDIRECTORY
|
||||
export PATH=/opt/python/cp38-cp38/bin:$PATH
|
||||
cd /build
|
||||
files=(whl/*.whl)
|
||||
FILE_NAME="${files[0]}"
|
||||
FILE_NAME=$(basename $FILE_NAME)
|
||||
|
|
@ -23,7 +24,7 @@ PYTHON_PACKAGE_NAME=$(echo "$FILE_NAME" | cut -f 1 -d '-')
|
|||
|
||||
echo "Package name:$PYTHON_PACKAGE_NAME"
|
||||
|
||||
BUILD_ARGS="--build_dir $BUILD_BINARIESDIRECTORY --config $BUILD_CONFIG --test --skip_submodule_sync --parallel --enable_lto --build_wheel "
|
||||
BUILD_ARGS="--build_dir /build --config $BUILD_CONFIG --test --skip_submodule_sync --parallel --enable_lto --build_wheel "
|
||||
|
||||
ARCH=$(uname -m)
|
||||
|
||||
|
|
@ -34,20 +35,15 @@ fi
|
|||
if [ $BUILD_DEVICE == "GPU" ]; then
|
||||
BUILD_ARGS="$BUILD_ARGS --use_cuda --use_tensorrt --cuda_version=11.8 --tensorrt_home=/usr --cuda_home=/usr/local/cuda-11.8 --cudnn_home=/usr/local/cuda-11.8"
|
||||
fi
|
||||
# We assume the machine doesn't have gcc and python development header files, so we don't build onnxruntime from source
|
||||
sudo rm -rf /build /onnxruntime_src
|
||||
sudo ln -s $BUILD_SOURCESDIRECTORY /onnxruntime_src
|
||||
python3 -m pip uninstall -y $PYTHON_PACKAGE_NAME ort-nightly-gpu ort-nightly onnxruntime onnxruntime-gpu onnxruntime-training onnxruntime-directml ort-nightly-directml onnx -qq
|
||||
python3 -m pip install --upgrade pip
|
||||
# Install the packages that are needed for installing the onnxruntime python package
|
||||
python3 -m pip install -r $BUILD_BINARIESDIRECTORY/$BUILD_CONFIG/requirements.txt
|
||||
python3 -m pip install -r /build/$BUILD_CONFIG/requirements.txt
|
||||
# Install the packages that are needed for running test scripts
|
||||
# Install the latest ONNX release which may contain not fixed bugs. However, it is what most people use.
|
||||
python3 -m pip install onnx pytest
|
||||
python3 -m pip install pytest
|
||||
# The "--no-index" flag is crucial. The local whl folder is just an additional source. Pypi's doc says "there is no
|
||||
# ordering in the locations that are searched" if we don't disable the default one with "--no-index"
|
||||
python3 -m pip install --no-index --find-links $BUILD_BINARIESDIRECTORY/whl $PYTHON_PACKAGE_NAME
|
||||
ln -s /data/models $BUILD_BINARIESDIRECTORY
|
||||
cd $BUILD_BINARIESDIRECTORY/$BUILD_CONFIG
|
||||
python3 -m pip install --no-index --find-links /build/whl $PYTHON_PACKAGE_NAME
|
||||
cd /build/$BUILD_CONFIG
|
||||
# Restore file permissions
|
||||
xargs -a perms.txt chmod a+x
|
||||
python3 $BUILD_SOURCESDIRECTORY/tools/ci_build/build.py $BUILD_ARGS --ctest_path ''
|
||||
python3 /onnxruntime_src/tools/ci_build/build.py $BUILD_ARGS --ctest_path ''
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
pip3 install --user --upgrade pip
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
set -e -o -x
|
||||
|
||||
while getopts a:r:i:c:p:b: parameter_Option
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
set -e
|
||||
|
||||
YOCTO_VERSION="4.19"
|
||||
|
|
|
|||
|
|
@ -379,13 +379,6 @@ std::string GetFullNameOfTest(ITestCase* testCase, winml::LearningModelDeviceKin
|
|||
name += tokenizedModelPath[tokenizedModelPath.size() - 2] += "_"; // model name
|
||||
name += tokenizedModelPath[tokenizedModelPath.size() - 3]; // opset version
|
||||
|
||||
// To introduce models from model zoo, the model path is structured like this "<source>/<opset>/<model_name>/?.onnx"
|
||||
std::string source = tokenizedModelPath[tokenizedModelPath.size() - 4];
|
||||
// `models` means the root of models, to be ompatible with the old structure, that is, the source name is empty.
|
||||
if (source != "models") {
|
||||
name += "_" + source;
|
||||
}
|
||||
|
||||
std::replace_if(
|
||||
name.begin(), name.end(), [](char c) { return !google::protobuf::ascii_isalnum(c); }, '_'
|
||||
);
|
||||
|
|
@ -404,6 +397,13 @@ std::string GetFullNameOfTest(ITestCase* testCase, winml::LearningModelDeviceKin
|
|||
ModifyNameIfDisabledTest(/*inout*/ name, deviceKind);
|
||||
}
|
||||
|
||||
// To introduce models from model zoo, the model path is structured like this "<source>/<opset>/<model_name>/?.onnx"
|
||||
std::string source = tokenizedModelPath[tokenizedModelPath.size() - 4];
|
||||
// `models` means the root of models, to be ompatible with the old structure, that is, the source name is empty.
|
||||
if (source != "models") {
|
||||
name += "_" + source;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue