Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c14118f
Fix/winml image dimension overflow (#32046)
apsonawane Aug 13, 2026
a75bbd9
Reject non-finite CPU RoiAlign coordinates (#32011)
apsonawane Aug 13, 2026
5a69eae
Validate Slice starts rank in transpose optimizer (#32044)
apsonawane Aug 13, 2026
de17ab8
Bound TreeEnsemble subtree comparison (#32043)
apsonawane Aug 13, 2026
4753dd0
Extract Rust string tensor outputs safely (#32045)
apsonawane Aug 13, 2026
8239590
Pin C# RunAsync arguments until completion (#32015)
apsonawane Aug 13, 2026
b1def2f
Add BTI support to MLAS AArch64 assembly (#32070)
mustjab Aug 13, 2026
d58b31e
Fix prepacked weight reference lifetime (#32040)
apsonawane Aug 13, 2026
3d3cfa6
Fix Whisper encoder input diagnostic (#32037)
apsonawane Aug 13, 2026
27080ee
Validate TreeEnsemble v5 node references (#32031)
apsonawane Aug 13, 2026
36e2f9d
Serialize CPU ScatterND string updates (#32033)
apsonawane Aug 13, 2026
2b801da
Validate Rust tensor element types (#32035)
apsonawane Aug 13, 2026
91769bb
Harden contrib CPU int narrowing for attention attrs (#31648)
apsonawane Aug 14, 2026
3fb2344
[CUDA] Fix Abs signed zero handling (#31477)
MohamedElashri Aug 14, 2026
e82c4e0
[Build] Update cuda plugin package test pipeline (#32072)
tianleiwu Aug 14, 2026
28ff956
Merge branch 'microsoft:main' into master
hdharpure9922 Aug 14, 2026
36bb4ed
[WebNN EP] Fix bug introduced by output rank validation (#32067)
Honry Aug 14, 2026
aabdbf6
[CUDA] Update cuda archs in packaging pipelines (#31989)
tianleiwu Aug 14, 2026
68aa29c
Validate FastGelu fusion scale node (#32016)
apsonawane Aug 14, 2026
c07c419
Validate GQA fusion projection shapes (#32018)
apsonawane Aug 14, 2026
6a86c06
Validate CUDA QDQ element counts (#32029)
apsonawane Aug 14, 2026
0da10ef
Validate MatMulFpQ4 shape inputs (#32032)
apsonawane Aug 14, 2026
927b53a
Fix/qdq optional zero point input (#32051)
apsonawane Aug 14, 2026
85d9292
Validate in-memory initializer references (#32042)
apsonawane Aug 14, 2026
2b9a948
Validate CUDA GatherElements count (#32030)
apsonawane Aug 14, 2026
337ec52
Validate generation subgraph shapes (#32078)
apsonawane Aug 14, 2026
4816399
Enable WebGPU CI for WebGPU plugin EP release branches (#32090)
edgchen1 Aug 14, 2026
87ae6fa
Merge remote-tracking branch 'upstream/main'
AIFrameworksIntegration Aug 14, 2026
b3a8bb3
Merge remote-tracking branch 'origin/master' into sync_msft_15082026
AIFrameworksIntegration Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/linux_webgpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Linux WebGPU CI

on:
push:
branches: [main, 'rel-*']
branches: [main, 'rel-*', 'plugin-ep-webgpu/rel-*']
pull_request:
branches: [main, 'rel-*']
branches: [main, 'rel-*', 'plugin-ep-webgpu/rel-*']
workflow_dispatch:

concurrency:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ on:
branches:
- main
- rel-*
- plugin-ep-webgpu/rel-*
pull_request:
branches:
- main
- rel-*
- plugin-ep-webgpu/rel-*
workflow_dispatch:

concurrency:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ on:
branches:
- main
- rel-*
- plugin-ep-webgpu/rel-*
pull_request:
branches:
- main
- rel-*
- plugin-ep-webgpu/rel-*
workflow_dispatch:

concurrency:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/windows_webgpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ on:
branches:
- main
- rel-*
- plugin-ep-webgpu/rel-*
pull_request:
branches:
- main
- rel-*
- plugin-ep-webgpu/rel-*
workflow_dispatch:

concurrency:
Expand Down
89 changes: 79 additions & 10 deletions csharp/src/Microsoft.ML.OnnxRuntime/InferenceSession.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,7 @@ private static void OrtCallback(IntPtr userData, IntPtr[] outputs, uint numOutpu
}
finally
{
host.Dispose();
hostHdl.Free();
}
}
Expand All @@ -1143,8 +1144,10 @@ private static void OrtCallback(IntPtr userData, IntPtr[] outputs, uint numOutpu

private delegate void UserCallbackDelegate(IReadOnlyCollection<OrtValue> outputs, IntPtr status);

private class CallbackHost
private class CallbackHost : IDisposable
{
public InferenceSession session { get; }
public RunOptions options { get; }
public IReadOnlyCollection<string> inputNames { get; }
public IReadOnlyCollection<OrtValue> inputValues { get; }
public IReadOnlyCollection<string> outputNames { get; }
Expand All @@ -1156,14 +1159,21 @@ private class CallbackHost
public IntPtr[] rawOutputNames { get; }
public IntPtr[] rawOutputValues { get; }

public IntPtr rawInputNamesPointer => GetPinnedPointer(rawInputNamesHandle);
public IntPtr rawInputValuesPointer => GetPinnedPointer(rawInputValuesHandle);
public IntPtr rawOutputNamesPointer => GetPinnedPointer(rawOutputNamesHandle);
public IntPtr rawOutputValuesPointer => GetPinnedPointer(rawOutputValuesHandle);

public CallbackHost(InferenceSession session,
RunOptions options,
IReadOnlyCollection<string> cbInputNames,
IReadOnlyCollection<OrtValue> cbinputValues,
IReadOnlyCollection<string> cbOutputNames,
IReadOnlyCollection<OrtValue> cbOutputValues,
UserCallbackDelegate userCallback)
{

this.session = session;
this.options = options;
inputNames = cbInputNames;
inputValues = cbinputValues;
outputNames = cbOutputNames;
Expand All @@ -1175,7 +1185,52 @@ public CallbackHost(InferenceSession session,

rawOutputNames = LookupUtf8Names(outputNames, n => n, session.LookupOutputMetadata);
rawOutputValues = outputValues.Select(v => v.Handle).ToArray();

// Native RunAsync retains these array addresses after the P/Invoke call returns.
try
{
rawInputNamesHandle = PinArray(rawInputNames);
rawInputValuesHandle = PinArray(rawInputValues);
rawOutputNamesHandle = PinArray(rawOutputNames);
rawOutputValuesHandle = PinArray(rawOutputValues);
}
catch
{
Dispose();
throw;
}
}

public void Dispose()
{
FreeHandle(ref rawInputNamesHandle);
FreeHandle(ref rawInputValuesHandle);
FreeHandle(ref rawOutputNamesHandle);
FreeHandle(ref rawOutputValuesHandle);
}

private static GCHandle PinArray(IntPtr[] array)
{
return array.Length == 0 ? default : GCHandle.Alloc(array, GCHandleType.Pinned);
}

private static IntPtr GetPinnedPointer(GCHandle handle)
{
return handle.IsAllocated ? handle.AddrOfPinnedObject() : IntPtr.Zero;
}

private static void FreeHandle(ref GCHandle handle)
{
if (handle.IsAllocated)
{
handle.Free();
}
}

private GCHandle rawInputNamesHandle = default;
private GCHandle rawInputValuesHandle = default;
private GCHandle rawOutputNamesHandle = default;
private GCHandle rawOutputValuesHandle = default;
}

private void RunAsyncInternal(RunOptions options,
Expand All @@ -1185,27 +1240,41 @@ private void RunAsyncInternal(RunOptions options,
IReadOnlyCollection<OrtValue> outputValues,
UserCallbackDelegate callback)
{
CallbackHost host = new CallbackHost(this, inputNames, inputValues, outputNames, outputValues, callback);
var host_hdl = GCHandle.Alloc(host, GCHandleType.Normal);
if (inputNames.Count != inputValues.Count)
{
throw new ArgumentException($"Length of {nameof(inputNames)} ({inputNames.Count}) must match that of {nameof(inputValues)} ({inputValues.Count}).");
}
if (outputNames.Count != outputValues.Count)
{
throw new ArgumentException($"Length of {nameof(outputNames)} ({outputNames.Count}) must match that of {nameof(outputValues)} ({outputValues.Count}).");
}

CallbackHost host = new CallbackHost(this, options, inputNames, inputValues, outputNames, outputValues, callback);
GCHandle host_hdl = default;

try
{
host_hdl = GCHandle.Alloc(host, GCHandleType.Normal);
NativeApiStatus.VerifySuccess(NativeMethods.OrtRunAsync(
_nativeHandle,
options == null ? (IntPtr)null : options.Handle,
host.rawInputNames,
host.rawInputValues,
host.rawInputNamesPointer,
host.rawInputValuesPointer,
(UIntPtr)host.rawInputNames.Length,
host.rawOutputNames,
host.rawOutputNamesPointer,
(UIntPtr)host.rawOutputNames.Length,
host.rawOutputValues,
host.rawOutputValuesPointer,
Marshal.GetFunctionPointerForDelegate(ortCallback),
GCHandle.ToIntPtr(host_hdl)
));
}
catch (OnnxRuntimeException)
catch
{
host_hdl.Free();
host.Dispose();
if (host_hdl.IsAllocated)
{
host_hdl.Free();
}
throw;
}
}
Expand Down
8 changes: 4 additions & 4 deletions csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1585,12 +1585,12 @@ IntPtr[] outputValues /* An array of output value pointers. Array must be alloca
public delegate IntPtr /*(ONNStatus*)*/ DOrtRunAsync(
IntPtr /*(OrtSession*)*/ session,
IntPtr /*(OrtSessionRunOptions*)*/ runOptions, // can be null to use the default options
IntPtr[] /*(char**)*/ inputNames,
IntPtr[] /*(OrtValue*[])*/ inputValues,
IntPtr /*(char**)*/ inputNames,
IntPtr /*(OrtValue*[])*/ inputValues,
UIntPtr /*(size_t)*/ inputCount,
IntPtr[] /*(char**)*/ outputNames,
IntPtr /*(char**)*/ outputNames,
UIntPtr /*(size_t)*/ outputCount,
IntPtr[] /*(OrtValue*[])*/ outputValues,
IntPtr /*(OrtValue*[])*/ outputValues,
IntPtr /*(void (*RunAsyncCallbackFn)(void* user_data, OrtValue** outputs, size_t num_outputs, OrtStatusPtr status))*/ callback, // callback function
IntPtr /*(void*)*/ user_data);
public static DOrtRunAsync OrtRunAsync;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1965,7 +1965,12 @@ private async Task TestModelRunAsyncTask()
{
try
{
var task = session.RunAsync(null, inputNames, inputValues, outputNames, outputValues);
RunOptions runOptions = new RunOptions();
var task = session.RunAsync(runOptions, inputNames, inputValues, outputNames, outputValues);
runOptions = null;
// Exercise the managed argument and RunOptions lifetimes while native work is outstanding.
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true, true);
GC.WaitForPendingFinalizers();
var outputs = await task;
var valueOut = outputs.ElementAt<OrtValue>(0);
var float16s = valueOut.GetTensorDataAsSpan<Float16>().ToArray();
Expand All @@ -1980,6 +1985,34 @@ private async Task TestModelRunAsyncTask()
}
#endif

[Fact(DisplayName = "TestModelRunAsyncRejectsMismatchedArgumentCounts")]
private async Task TestModelRunAsyncRejectsMismatchedArgumentCounts()
{
Float16[] inputData = { new Float16(15360), new Float16(16384), new Float16(16896), new Float16(17408), new Float16(17664) };
long[] shape = { 1, 5 };

var inputNames = new List<string> { "input" };
var outputNames = new List<string> { "output" };

var model = TestDataLoader.LoadModelFromEmbeddedResource("test_types_FLOAT16.onnx");
using (var inputValue = OrtValue.CreateTensorValueFromMemory(inputData, shape))
using (var outputValue = OrtValue.CreateAllocatedTensorValue(OrtAllocator.DefaultInstance,
TensorElementType.Float16, shape))
using (var session = new InferenceSession(model))
{
var inputValues = new List<OrtValue> { inputValue };
var outputValues = new List<OrtValue> { outputValue };

var inputException = await Assert.ThrowsAsync<ArgumentException>(() =>
session.RunAsync(null, new List<string>(), inputValues, outputNames, outputValues));
Assert.StartsWith("Length of inputNames (0) must match that of inputValues (1).", inputException.Message);

var outputException = await Assert.ThrowsAsync<ArgumentException>(() =>
session.RunAsync(null, inputNames, inputValues, new List<string>(), outputValues));
Assert.StartsWith("Length of outputNames (0) must match that of outputValues (1).", outputException.Message);
}
}

[Fact(DisplayName = "TestModelRunAsyncTaskFail")]
private async Task TestModelRunAsyncTaskFail()
{
Expand Down
5 changes: 5 additions & 0 deletions include/onnxruntime/core/graph/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,11 @@ class Graph { // NOLINT(clang-analyzer-optin.performance.Padding): preserve exi
/// <returns></returns>
Status ConvertInitializersIntoOrtValues();

/// <summary>
/// Validates that all in-memory external data references are backed by matching OrtValues.
/// </summary>
Status ValidateInMemoryInitializers();

/**
* @brief This function examines the specified initializers in the graph and converts them inline
* if any has external data in memory.
Expand Down
14 changes: 10 additions & 4 deletions onnxruntime/contrib_ops/cpu/bert/linear_attention.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include <algorithm>
#include <cmath>
#include <limits>

Check notice on line 15 in onnxruntime/contrib_ops/cpu/bert/linear_attention.cc

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] onnxruntime/contrib_ops/cpu/bert/linear_attention.cc#L15

Found C++ system header after other header. Should be: linear_attention.h, c system, c++ system, other. [build/include_order] [4]
Raw output
onnxruntime/contrib_ops/cpu/bert/linear_attention.cc:15:  Found C++ system header after other header. Should be: linear_attention.h, c system, c++ system, other.  [build/include_order] [4]
#include <vector>

Check notice on line 16 in onnxruntime/contrib_ops/cpu/bert/linear_attention.cc

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] onnxruntime/contrib_ops/cpu/bert/linear_attention.cc#L16

Found C++ system header after other header. Should be: linear_attention.h, c system, c++ system, other. [build/include_order] [4]
Raw output
onnxruntime/contrib_ops/cpu/bert/linear_attention.cc:16:  Found C++ system header after other header. Should be: linear_attention.h, c system, c++ system, other.  [build/include_order] [4]
#include <cstring>

using onnxruntime::concurrency::ThreadPool;
Expand Down Expand Up @@ -46,13 +48,17 @@
template <typename T>
LinearAttention<T>::LinearAttention(const OpKernelInfo& info) : OpKernel(info) {
int64_t q_num_heads = 0;
ORT_ENFORCE(info.GetAttr("q_num_heads", &q_num_heads).IsOK() && q_num_heads > 0,
"q_num_heads must be a positive integer");
ORT_ENFORCE(info.GetAttr("q_num_heads", &q_num_heads).IsOK() &&
q_num_heads > 0 &&
q_num_heads <= std::numeric_limits<int>::max(),
"q_num_heads must be an integer in [1, INT_MAX]");
q_num_heads_ = static_cast<int>(q_num_heads);

int64_t kv_num_heads = 0;
ORT_ENFORCE(info.GetAttr("kv_num_heads", &kv_num_heads).IsOK() && kv_num_heads > 0,
"kv_num_heads must be a positive integer");
ORT_ENFORCE(info.GetAttr("kv_num_heads", &kv_num_heads).IsOK() &&
kv_num_heads > 0 &&
kv_num_heads <= std::numeric_limits<int>::max(),
"kv_num_heads must be an integer in [1, INT_MAX]");
kv_num_heads_ = static_cast<int>(kv_num_heads);

update_rule_ = info.GetAttrOrDefault<std::string>("update_rule", "gated_delta");
Expand Down
11 changes: 9 additions & 2 deletions onnxruntime/contrib_ops/cpu/bert/longformer_attention_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "core/common/common.h"
#include <limits>

Check notice on line 7 in onnxruntime/contrib_ops/cpu/bert/longformer_attention_base.h

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] onnxruntime/contrib_ops/cpu/bert/longformer_attention_base.h#L7

Found C++ system header after other header. Should be: longformer_attention_base.h, c system, c++ system, other. [build/include_order] [4]
Raw output
onnxruntime/contrib_ops/cpu/bert/longformer_attention_base.h:7:  Found C++ system header after other header. Should be: longformer_attention_base.h, c system, c++ system, other.  [build/include_order] [4]
#ifndef SHARED_PROVIDER
#include "core/framework/op_kernel.h"
#endif
Expand All @@ -25,11 +26,17 @@
template <typename KernelInfoType>
LongformerAttentionBase(const KernelInfoType& info) {
int64_t num_heads = 0;
ORT_ENFORCE(info.GetAttr("num_heads", &num_heads).IsOK() && num_heads > 0);
ORT_ENFORCE(info.GetAttr("num_heads", &num_heads).IsOK() &&
num_heads > 0 &&
num_heads <= std::numeric_limits<int>::max(),
"num_heads must be an integer in [1, INT_MAX]");
num_heads_ = static_cast<int>(num_heads);

int64_t window = 0;
ORT_ENFORCE(info.GetAttr("window", &window).IsOK() && window > 0);
ORT_ENFORCE(info.GetAttr("window", &window).IsOK() &&
window > 0 &&
window <= std::numeric_limits<int>::max(),
"window must be an integer in [1, INT_MAX]");
window_ = static_cast<int>(window);
}

Expand Down
5 changes: 5 additions & 0 deletions onnxruntime/contrib_ops/cpu/transformers/subgraph_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ Status Subgraph::Setup(const SessionState& session_state,
session_state_ = &session_state;
subgraph_session_state_ = &subgraph_session_state;

ORT_RETURN_IF(subgraph_output_names.empty(), "subgraph must have at least one output");

InlinedVector<std::string_view> feed_names;
feed_names.reserve(static_cast<size_t>(num_subgraph_inputs) + static_cast<size_t>(num_implicit_inputs));

Expand Down Expand Up @@ -140,6 +142,9 @@ const IExecutionProvider* Subgraph::GetProvider() const {
Status Subgraph::GetParameters(const ONNX_NAMESPACE::TensorShapeProto* past_shape,
const ONNX_NAMESPACE::TensorShapeProto* logits_shape,
bool merged_past) {
ORT_RETURN_IF(past_shape == nullptr,
"subgraph past state shape cannot be nullptr");

if (merged_past) {
// Merged past state shape is like (2, batch_size, num_heads, past_seq_len, hidden_size/num_heads)
ORT_RETURN_IF(past_shape->dim_size() != 5,
Expand Down
12 changes: 11 additions & 1 deletion onnxruntime/contrib_ops/cpu/transformers/subgraph_gpt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "core/framework/utils.h"
#include "core/providers/cpu/tensor/utils.h"
#include <gsl/gsl>
#include <limits>

Check notice on line 10 in onnxruntime/contrib_ops/cpu/transformers/subgraph_gpt.cc

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] onnxruntime/contrib_ops/cpu/transformers/subgraph_gpt.cc#L10

Found C++ system header after other header. Should be: subgraph_gpt.h, c system, c++ system, other. [build/include_order] [4]
Raw output
onnxruntime/contrib_ops/cpu/transformers/subgraph_gpt.cc:10:  Found C++ system header after other header. Should be: subgraph_gpt.h, c system, c++ system, other.  [build/include_order] [4]
#include "contrib_ops/cpu/transformers/subgraph_gpt.h"
#include "contrib_ops/cpu/utils/dump_tensor.h"

Expand Down Expand Up @@ -166,11 +167,20 @@

// Logits shape is like (batch_size, seq_len, 50257). Here 50257 is the vocabulary size.
const ONNX_NAMESPACE::TensorShapeProto* logits_shape = subgraph_outputs[0]->Shape();
ORT_RETURN_IF(logits_shape == nullptr,
"subgraph logits output shape cannot be nullptr");
ORT_RETURN_IF(logits_shape->dim_size() != 3,
"subgraph logits output is expected to have 3 dimension, got ", logits_shape->dim_size());

ORT_RETURN_IF(!logits_shape->dim(2).has_dim_value() || logits_shape->dim(2).dim_value() <= 0,
"subgraph past state dimension 2 shall have a positive value for vocabulary size");
"subgraph logits dimension 2 shall have a positive value for vocabulary size");

ORT_RETURN_IF(past_shape->dim(2).dim_value() > std::numeric_limits<int>::max(),
"subgraph past state dimension 2 is too large for int");
ORT_RETURN_IF(past_shape->dim(4).dim_value() > std::numeric_limits<int>::max(),
"subgraph past state dimension 4 is too large for int");
ORT_RETURN_IF(logits_shape->dim(2).dim_value() > std::numeric_limits<int>::max(),
"subgraph logits dimension 2 is too large for int");

// Save parameters related to the subgraph.
num_heads = static_cast<int>(past_shape->dim(2).dim_value());
Expand Down
Loading
Loading