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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions cmake/vcpkg-ports/pybind11/portfile.cmake
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO pybind/pybind11
REF "v${VERSION}"
# SHA512 for the zip (not tar.gz) file.
# Manually define the download for the .zip archive (to be consistent with deps.txt)
# If we used vcpkg_from_github, it would download the .tar.gz archive,
# which has different SHA512: 19bee2c76320e25202ee078b5680ff8a7acfb33494dec29dad984ab04de8bcb01340d9fec37c8cc5ac9015dfc367e60312dcd8506e66ce8f0af4c49db562ddef
vcpkg_download_distfile(ARCHIVE
URLS "https://github.com/pybind/pybind11/archive/refs/tags/v${VERSION}.zip"
FILENAME "pybind11-${VERSION}.zip"
SHA512 786b1bf534ac67a8d5669f8babf67bb13e48b3a3da1b6344e43ae10a84b80bbc8fea5f12a65fd18739c341fefef5622c5dc096db964dff33cc62ea4259b2e2c1
HEAD_REF master
)

vcpkg_extract_source_archive(
SOURCE_PATH
ARCHIVE "${ARCHIVE}"
)

vcpkg_cmake_configure(
Expand Down
22 changes: 19 additions & 3 deletions csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,9 +476,25 @@ internal static class NativeMethods
static NativeMethods()
{
#if !NETSTANDARD2_0 && !__ANDROID__ && !__IOS__
// Register a custom DllImportResolver to handle platform-specific library loading.
// Replaces default resolution specifically on Windows for case-sensitivity.
NativeLibrary.SetDllImportResolver(typeof(NativeMethods).Assembly, DllImportResolver);
if (!OrtEnv.DisableDllImportResolver)
{
try
{
// Register a custom DllImportResolver to handle platform-specific library loading.
// Replaces default resolution specifically on Windows for case-sensitivity.
NativeLibrary.SetDllImportResolver(typeof(NativeMethods).Assembly, DllImportResolver);
}
catch (InvalidOperationException)
{
// A resolver is already registered for this assembly (e.g., by the host application).
// This is not fatal — the host's resolver will handle library loading.
System.Diagnostics.Trace.WriteLine(
"[OnnxRuntime] A DllImportResolver is already registered for this assembly. "
+ "OnnxRuntime's built-in resolver will not be used. "
+ "To suppress this message, set OrtEnv.DisableDllImportResolver = true "
+ "before using any OnnxRuntime APIs.");
}
}
#endif

#if NETSTANDARD2_0
Expand Down
36 changes: 29 additions & 7 deletions csharp/src/Microsoft.ML.OnnxRuntime/OrtEnv.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Microsoft.ML.OnnxRuntime
/// </summary>
/// <remarks>
/// This enum is used to determine whether a pre-compiled model can be used with specific execution providers
/// and devices, or if recompilation is needed.
/// and devices, or if recompilation is needed.
/// </remarks>
public enum OrtCompiledModelCompatibility
{
Expand Down Expand Up @@ -77,14 +77,14 @@ public struct EnvironmentCreationOptions
/// <summary>
/// The singleton class OrtEnv contains the process-global ONNX Runtime environment.
/// It sets up logging, creates system wide thread-pools (if Thread Pool options are provided)
/// and other necessary things for OnnxRuntime to function.
///
/// and other necessary things for OnnxRuntime to function.
///
/// Create or access OrtEnv by calling the Instance() method. Instance() can be called multiple times.
/// It would return the same instance.
///
///
/// CreateInstanceWithOptions() provides a way to create environment with options.
/// It must be called once before Instance() is called, otherwise it would not have effect.
///
///
/// If the environment is not explicitly created, it will be created as needed, e.g.,
/// when creating a SessionOptions instance.
/// </summary>
Expand All @@ -93,6 +93,28 @@ public sealed class OrtEnv : SafeHandle
#region Static members
private static readonly int ORT_PROJECTION_CSHARP = 2;

/// <summary>
/// Set this to <c>true</c> before accessing any OnnxRuntime type to prevent OnnxRuntime
/// from registering its own <c>DllImportResolver</c> via
/// <c>NativeLibrary.SetDllImportResolver</c>.
/// This is useful when the host application needs to register its own custom resolver
/// for the OnnxRuntime assembly. Must be set before any OnnxRuntime API is used
/// (i.e., before the internal NativeMethods static constructor runs).
/// </summary>
/// <example>
/// <code>
/// // Disable OnnxRuntime's built-in resolver before any ORT usage
/// OrtEnv.DisableDllImportResolver = true;
///
/// // Register your own resolver
/// NativeLibrary.SetDllImportResolver(typeof(OrtEnv).Assembly, MyCustomResolver);
///
/// // Now use OnnxRuntime normally
/// var env = OrtEnv.Instance();
/// </code>
/// </example>
public static bool DisableDllImportResolver { get; set; } = false;

private static readonly byte[] _defaultLogId = NativeOnnxValueHelper.StringToZeroTerminatedUtf8(@"CSharpOnnxRuntime");

// This must be static and set before the first creation call, otherwise, has no effect.
Expand Down Expand Up @@ -274,7 +296,7 @@ private static void SetLanguageProjection(OrtEnv env)
/// <summary>
/// Instantiates (if not already done so) a new OrtEnv instance with the default logging level
/// and no other options. Otherwise returns the existing instance.
///
///
/// It returns the same instance on every call - `OrtEnv` is singleton
/// </summary>
/// <returns>Returns a singleton instance of OrtEnv that represents native OrtEnv object</returns>
Expand Down Expand Up @@ -523,7 +545,7 @@ public OrtLoggingLevel EnvLogLevel
/// A registered execution provider library can be used by all sessions created with the OrtEnv instance.
/// Devices the execution provider can utilize are added to the values returned by GetEpDevices() and can
/// be used in SessionOptions.AppendExecutionProvider to select an execution provider for a device.
///
///
/// Coming: A selection policy can be specified and ORT will automatically select the best execution providers
/// and devices for the model.
/// </summary>
Expand Down
96 changes: 96 additions & 0 deletions csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/OrtEnvTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -532,4 +532,100 @@ public void TestDllImportResolverDoesNotThrow()
}
}
}

#if !NETSTANDARD2_0
[Collection("Ort Inference Tests")]
public class OrtEnvExternalDllImportResolverTest
{
private System.Reflection.Assembly LoadIsolatedOnnxRuntimeAssembly(out System.Runtime.Loader.AssemblyLoadContext alc)
{
// Load a fresh copy of the ONNX Runtime assembly into a new AssemblyLoadContext.
// This guarantees we get a clean slate for static fields/constructors, avoiding
// interference from other xUnit tests that may have already initialized OrtEnv
// in the default context.
//
// Native library resolution (e.g., onnxruntime.dll) falls through to the default
// ALC when the isolated context cannot resolve it, so P/Invoke calls still work.
alc = new System.Runtime.Loader.AssemblyLoadContext("IsolatedORT_" + Guid.NewGuid(), isCollectible: true);
string asmPath = typeof(OrtEnv).Assembly.Location;
return alc.LoadFromAssemblyPath(asmPath);
}

/// <summary>
/// Verifies the scenario where an external caller registers a DllImportResolver FIRST,
/// and then OrtEnv is initialized. ORT's try/catch should handle the conflict gracefully.
/// </summary>
[Fact(DisplayName = "TestExternalResolverRegisteredFirst")]
public void TestExternalResolverRegisteredFirst()
{
var asm = LoadIsolatedOnnxRuntimeAssembly(out var alc);
try
{
// 1. External application registers its own resolver FIRST.
// Returning IntPtr.Zero means "not handled" — the runtime falls back to
// its default resolution logic, so native libraries still load normally.
NativeLibrary.SetDllImportResolver(asm, (libraryName, a, searchPath) => IntPtr.Zero);

// 2. ORT initializes (triggers NativeMethods static constructor).
// It will attempt to register its own resolver, which will throw
// InvalidOperationException internally, but the try/catch safety net
// prevents an unhandled TypeInitializationException.
var ortEnvType = asm.GetType("Microsoft.ML.OnnxRuntime.OrtEnv");
var instanceMethod = ortEnvType.GetMethod("Instance", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
var ortEnvInstance = instanceMethod.Invoke(null, null);
Assert.NotNull(ortEnvInstance);

// Verify ORT is fully functional despite the resolver conflict.
var getVersionMethod = ortEnvType.GetMethod("GetVersionString", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
var version = (string)getVersionMethod.Invoke(ortEnvInstance, null);
Assert.False(string.IsNullOrEmpty(version));
}
finally
{
alc.Unload();
}
}

/// <summary>
/// Verifies that setting DisableDllImportResolver = true BEFORE ORT initializes
/// successfully prevents ORT from registering its own resolver, leaving the assembly
/// free for the external application to register theirs LATER without throwing.
/// </summary>
[Fact(DisplayName = "TestDisableDllImportResolverWorks")]
public void TestDisableDllImportResolverWorks()
{
var asm = LoadIsolatedOnnxRuntimeAssembly(out var alc);
try
{
var ortEnvType = asm.GetType("Microsoft.ML.OnnxRuntime.OrtEnv");

// 1. Set OrtEnv.DisableDllImportResolver = true FIRST.
var disableProp = ortEnvType.GetProperty("DisableDllImportResolver", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
Assert.NotNull(disableProp);
disableProp.SetValue(null, true);

// 2. ORT initializes (triggers NativeMethods static constructor).
// It should respect the flag and SKIP calling NativeLibrary.SetDllImportResolver.
var instanceMethod = ortEnvType.GetMethod("Instance", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
var ortEnvInstance = instanceMethod.Invoke(null, null);
Assert.NotNull(ortEnvInstance);

// 3. External application registers its own resolver AFTER ORT initialized.
// If the flag works correctly, ORT skipped its own SetDllImportResolver call,
// so this registration should succeed without throwing InvalidOperationException.
// Returning IntPtr.Zero means "not handled" — falls back to default resolution.
var ex = Record.Exception(() =>
{
NativeLibrary.SetDllImportResolver(asm, (libraryName, a, searchPath) => IntPtr.Zero);
});

Assert.Null(ex); // No InvalidOperationException = ORT correctly skipped registration
}
finally
{
alc.Unload();
}
}
}
#endif
}
9 changes: 9 additions & 0 deletions include/onnxruntime/core/framework/int2.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <type_traits>
#include "core/common/common.h"
#include <gsl/gsl>
#include "onnxruntime_config.h"

Check warning on line 10 in include/onnxruntime/core/framework/int2.h

View workflow job for this annotation

GitHub Actions / Optional Lint C++

[cpplint] reported by reviewdog 🐶 Include the directory when naming header files [build/include_subdir] [4] Raw Output: include/onnxruntime/core/framework/int2.h:10: Include the directory when naming header files [build/include_subdir] [4]

namespace onnxruntime {

Expand Down Expand Up @@ -137,8 +138,16 @@
const size_t full_quads = src.size() / 4;

// Process complete groups of 4 elements

for (; dst_i < full_quads; dst_i++) {
#if defined(__GNUC__) && defined(HAS_ARRAY_BOUNDS)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
dst[dst_i] = Int2x4Base<Signed>(src[src_i], src[src_i + 1], src[src_i + 2], src[src_i + 3]);
#if defined(__GNUC__) && defined(HAS_ARRAY_BOUNDS)
#pragma GCC diagnostic pop
#endif
src_i += 4;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* The maximum length of the Config Key is 1024
*
* The string format of a SessionOptions Config Value is defined individually for each Config.
* The maximum length of the Config Value is 2048
* The maximum length of the Config Value is 8192
*/

// Key for disable PrePacking,
Expand Down Expand Up @@ -385,6 +385,11 @@ static const char* const kOrtSessionOptionsMlasLutGemm = "mlas.use_lut_gemm";
// If not provided, default is 4.
static const char* const kOrtSessionOptionsQDQMatMulNBitsAccuracyLevel = "session.qdq_matmulnbits_accuracy_level";

// Enable the DQ->MatMulNBits fusion graph transformer.
// "0": disabled (default). "1": enabled.
// This is typically set automatically by InferenceSession when the NvTensorRTRTX EP is registered.
static const char* const kOrtSessionOptionsEnableDQMatMulNBitsFusion = "session.enable_dq_matmulnbits_fusion";

// THIS OPTION IS NOT A REGULAR SESSION OPTION SINCE IT CAN BE MODIFIED AT ANY TIME
// Meant to be used with SetEpDynamicOptions
// Specify the type of workload for this session.
Expand Down
2 changes: 1 addition & 1 deletion onnxruntime/core/framework/config_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct ConfigOptions {
// Maximum key/value string lengths specified in
// core/session/onnxruntime_session_options_config_keys.h
static constexpr size_t kMaxKeyLength = 1024;
static constexpr size_t kMaxValueLength = 4096;
static constexpr size_t kMaxValueLength = 8192;

std::unordered_map<std::string, std::string> configurations;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1670,12 +1670,12 @@ MlasQ4Int8TileGemmKernelBlkLen32Avx2(
// .../onnxruntime/core/mlas/lib/sqnbitgemm_kernel_avx2_int8_blklen32.h:1531:13: note: array 'acc' declared here
// 1531 | __m256 acc[NCols4];
// | ^
#if defined(__clang__) && defined(HAS_ARRAY_BOUNDS)
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warray-bounds"
#endif
__m128 acc_1 = FoldAccumulators(acc[4], acc[5], acc[6], acc[7]);
#if defined(__clang__) && defined(HAS_ARRAY_BOUNDS)
#ifdef __clang__
#pragma clang diagnostic pop
#endif
if (BiasPtr != nullptr) {
Expand Down
Loading
Loading