Enable SymbolicSgdLogisticRegression (SymSgdNative) on arm64 - #7671
Enable SymbolicSgdLogisticRegression (SymSgdNative) on arm64#7671vladimir-aubrecht wants to merge 4 commits into
Conversation
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. Fixes dotnet#5798 Co-authored-by: Anna Maresova <anicka@anicka.net> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@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.
…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>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7671 +/- ##
==========================================
+ Coverage 69.59% 69.76% +0.16%
==========================================
Files 1484 1486 +2
Lines 273606 275796 +2190
Branches 27949 28200 +251
==========================================
+ Hits 190410 192401 +1991
- Misses 75832 75936 +104
- Partials 7364 7459 +95
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
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>
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.