Uh oh!
There was an error while loading. Please reload this page.
Enable SymbolicSgdLogisticRegression (SymSgdNative) on arm64 - #7671
Enable SymbolicSgdLogisticRegression (SymSgdNative) on arm64#7671vladimir-aubrecht wants to merge 7 commits into
Conversation
vladimir-aubrecht
commented
Aug 11, 2026
@dotnet-policy-service agree company="Microsoft" |
There was a problem hiding this comment.
Pull request overview
Enables SymbolicSgdLogisticRegression / SymSgdNative on arm/arm64 by adding an ARM-specific MklImports shim (implementing the small subset of CBLAS APIs SymSGD needs), wiring it into the native build, and fixing managed P/Invoke marshalling that can crash on arm64.
Changes:
- Add
src/Native/MklImportsArm/to build a self-containedMklImportsshim on arm/arm64 and linkSymSgdNativeagainst it. - Update native build gating so
SymSgdNativeis built on arm/arm64 and shipped next to managed assemblies. - Fix
LearnAllP/Invokeboolmarshalling to avoid stack corruption / SIGSEGV on arm64.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Native/SymSgdNative/SparseBLAS.h | Makes CBLAS calling convention portable across Windows vs non-Windows builds. |
| src/Native/SymSgdNative/CMakeLists.txt | Adjusts how MklImports is resolved/linked on arm platforms. |
| src/Native/MklImportsArm/MklImportsArm.c | Implements the minimal CBLAS subset + DFTI stubs for arm/arm64 as a self-contained shim. |
| src/Native/MklImportsArm/CMakeLists.txt | Adds CMake target to build/install the ARM MklImports shim. |
| src/Native/CMakeLists.txt | Enables building SymSgdNative on arm/arm64 and adds MklImportsArm to the build graph. |
| src/Microsoft.ML.Mkl.Components/SymSgdClassificationTrainer.cs | Fixes P/Invoke bool marshalling for LearnAll to prevent arm64 crashes. |
| Directory.Build.targets | Ensures MklImports and SymSgdNative are copied for arm/arm64 outputs (no longer removed). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@## main #7671 +/- ##
=======================================
Coverage 69.88% 69.88% =======================================
Files 1487 1487 Lines 276214 276223 +9 Branches 28287 28289 +2 =======================================
+ Hits 193019 193040 +21 + Misses 75708 75691 -17 - Partials 7487 7492 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Build SymSgdNative and a small self-contained libMklImports shim on arm/arm64 so the SymbolicSgdLogisticRegression trainer works there without Intel MKL. - MklImportsArm: implement the four CBLAS routines SymSGD needs (sdot, saxpy, sdoti, saxpyi) as portable C with no external BLAS dependency, plus DFTI stubs. Drop find_package(BLAS) so it configures in the CI cross-compilation sysroots (which ship no BLAS). Export the symbols explicitly since the native build uses -fvisibility=hidden. - CMake: build MklImportsArm + SymSgdNative on arm, link SymSgdNative against the shim, and make the CBLAS calling convention portable. - Directory.Build.targets: ship libMklImports and libSymSgdNative next to the managed assemblies on arm. - SymSgdClassificationTrainer: marshal the native bool parameters of LearnAll as I1. The default 4-byte bool marshalling corrupts later stack arguments and segfaults on arm64. Fixesdotnet#5798 Co-authored-by: Anna Maresova <anicka@anicka.net> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Descriptor, fix misleading comment Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rts off arm
Two CI failures on this PR:
1. macOS arm64 build: SymSgdNative linked OpenMP via the hardcoded Intel Homebrew
path /usr/local/opt/libomp, which holds an x86_64 libomp on Apple Silicon, so
linking failed with undefined __kmpc_*/omp_* symbols. Use `brew --prefix libomp`
like MatrixFactorizationNative already does, so it resolves on Intel and arm Macs.
2. Windows/macOS arm64 tests: shipping the arm MklImports shim as libMklImports made
NativeDependencyFact("MklImports") stop skipping every MKL-gated test. The shim only
implements the 4 CBLAS routines SymSGD needs, so OLS/PCA-whitening/TimeSeries tests
ran and failed with EntryPointNotFound (LAPACKE_dsytrd) / DllNotFound (MklProxyNative).
Fix by making SymSgd self-contained on arm and not shipping a separate libMklImports:
- SymSgdNative compiles the MklImportsArm CBLAS shim directly (no separate library),
and the arm MklImportsArm target / its CMakeLists are removed.
- Directory.Build.targets keeps MklImports removed on arm (only SymSgdNative is copied).
- SymSgdClassificationTrainer skips the ErrorMessage(0) MKL-preload on arm (there is no
MklImports to preload there).
- SymSgd tests are gated on NativeDependencyFact("SymSgdNative") instead of "MklImports"
so they still run on arm; the other MKL tests skip as they did before this PR.
Verified on arm64 macOS: SymSgdNative links and is self-contained (cblas_* internal,
no MklImports dependency), SymSgd tests run and pass, and OLS/whitening tests skip.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Follow-up to the arm64 SymSgd enablement: - macOS arm64: the cross-compilation runner only has an x86_64 libomp, and SymSGD needs OpenMP, so SymSgdNative cannot link there. Build it on Windows/Linux arm only and don't copy it on macOS arm, so its dependent tests skip there (they already skip the full-MKL tests). SymSgd remains enabled on Windows and Linux arm64. - BinaryClassifierSymSgdTest is a strict baseline comparison against the win-x64 baseline; SymSGD produces slightly different numbers on arm, so skip it on arm (it already skips on Linux). The trainer itself stays covered on arm by the SymSgdClassificationTests estimators. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
d0c9948 to
42b5728Comparematouskozak
commented
Aug 27, 2026
Should we remove this exclusion with this PR or not yet? https://github.com/vladimir-aubrecht/machinelearning/blob/42b57288a40ca7097cc09ec4e8d26316769c169a/src/Native/Native.proj#L192-L195 |
Good catch — right now the PR builds and tests SymSgdNative on Windows/Linux arm64 but this packaging exclusion means it wouldn't ship in the arm64 NuGet, so consumers wouldn't actually get it. I think we should remove the exclusion here so the feature is delivered, but scoped to the platforms where we actually build it: include SymSgdNative for win-arm64 and linux-arm64, and keep it excluded for osx-arm64 (where it isn't built, since the macOS cross-compilation runner has no arm64 libomp). Done in bde8e6c — the packaging condition now includes SymSgdNative for win-arm64 and linux-arm64 and excludes only osx-arm64. |
The packaging exclusion kept SymSgdNative out of all arm NuGet packages, so even though this PR builds and tests it on Windows/Linux arm64, consumers wouldn't get it. Include it for arm64/arm except on macOS, where SymSgdNative isn't built (the macOS cross-compilation runner has no arm64 libomp). Replaces the stale TODO. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Run macOS arm64 CI and native asset builds on an Apple Silicon image so Homebrew provides a matching OpenMP runtime. Build and package SymSgdNative for osx-arm64, prepare libomp dynamically for Helix, and document the dependency. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
matouskozak
left a comment
There was a problem hiding this comment.
Overall looking good, I left a couple of comments to clarify my understanding of the PR.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Apply MSVC mitigations to the ARM C shim, add macOS ARM64 SymSGD baselines with an appropriate numeric tolerance, rename the native macOS ARM64 CI job, and clarify the native assembly removal comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Enables the
SymbolicSgdLogisticRegressiontrainer (backed bySymSgdNative) on arm/arm64, where Intel MKL is unavailable. Fixes#5798.SymSGD uses only four CBLAS routines (
sdot,saxpy,sdoti,saxpyi). This PR provides them via a tiny, self-containedlibMklImportsshim built from portable C — with no external BLAS dependency — so it configures and links in the CI cross-compilation sysroots (which ship no OpenBLAS/BLAS).Changes
src/Native/MklImportsArm/(new): implements the four CBLAS routines as plain C loops (-O3autovectorizes the dense paths to NEON) plus MKL DFTI stubs. Nofind_package(BLAS)— zero external deps. Symbols are exported explicitly because the native build uses-fvisibility=hidden.src/Native/CMakeLists.txt: buildMklImportsArm+SymSgdNativeon arm.src/Native/SymSgdNative/CMakeLists.txt: linkSymSgdNativeagainst the shim on arm.src/Native/SymSgdNative/SparseBLAS.h: make the CBLAS calling convention portable (__cdeclonly on_WIN32).Directory.Build.targets: shiplibMklImportsandlibSymSgdNativenext to the managed assemblies on arm.SymSgdClassificationTrainer.cs: marshalLearnAll's nativeboolparameters asUnmanagedType.I1. The default 4-byteboolmarshalling corrupts later stack arguments and segfaults on arm64 (works on x64 by luck).Testing
Built native (Release + Debug) and ran the SymSGD trainer tests on Apple Silicon (arm64):
TestEstimatorSymSgdClassificationTrainerTestEstimatorSymSgdInitPredictorSimpleTrainAndPredictSymSGD3 passed, 0 failed. Without the
boolmarshalling fix, these crash the test host with a SIGSEGV insideLearnAll.Notes
SparseBLAS.hcalling-convention guard) is based on prior work by @anicka-net (credited as co-author).Microsoft.ML.Mkl.Components(OLS,VectorWhitening) andMicrosoft.ML.TimeSeriesstill require a real BLAS/LAPACK and are out of scope here.