Enable SymbolicSgdLogisticRegression (SymSgdNative) on arm64 - #7671
Enable SymbolicSgdLogisticRegression (SymSgdNative) on arm64#7671vladimir-aubrecht wants to merge 5 commits into
Conversation
|
@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.
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 193045 +26
+ Misses 75708 75692 -16
+ Partials 7487 7486 -1
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. Fixes dotnet#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
42b5728
Compare
|
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>
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.