Enable SymSgdNative on ARM64 including macOS - #7678
Closed
matouskozak wants to merge 6 commits into
Closed
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 #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>
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>
Build macOS ARM64 assets on Apple Silicon agents and package the native OpenMP runtime beside SymSgdNative using loader-relative linkage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f6486565-2c30-46ac-b951-6e6468408258
Contributor
There was a problem hiding this comment.
Pull request overview
Extends ML.NET’s SymSGD native enablement to macOS ARM64 by building SymSgdNative on Apple Silicon agents, packaging required native dependencies (notably libomp.dylib), and updating tests/packaging to run SymSGD scenarios on ARM64.
Changes:
- Build
SymSgdNativeon ARM/ARM64 by compiling the ARM CBLAS shim into the library and updating CMake gating accordingly. - Enable macOS ARM64 native builds/packaging by using Apple Silicon agents and shipping
libomp.dylibbesidelibSymSgdNative.dylibwith@loader_pathlinkage. - Update test gating to depend on
SymSgdNativeand remove macOS ARM64 exclusions so SymSGD tests run on ARM64 Helix.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| THIRD-PARTY-NOTICES.TXT | Adds LLVM OpenMP runtime redistribution notice. |
| test/Microsoft.ML.Tests/TrainerEstimators/SymSgdClassificationTests.cs | Switches native dependency gating from MklImports to SymSgdNative. |
| test/Microsoft.ML.Tests/Scenarios/Api/Estimators/SimpleTrainAndPredict.cs | Switches SymSGD scenario test gating to SymSgdNative. |
| test/Microsoft.ML.Predictor.Tests/TestPredictors.cs | Gates SymSGD baseline test on SymSgdNative and skips strict baseline compare on ARM/ARM64. |
| src/Native/SymSgdNative/SparseBLAS.h | Makes CBLAS calling convention portable and fixes const-correctness for dense vector usage. |
| src/Native/SymSgdNative/CMakeLists.txt | Adds ARM shim compilation path and macOS ARM64 libomp packaging / @loader_path install-name handling. |
| src/Native/Native.proj | Packages SymSgdNative broadly and adds macOS ARM64 libomp.dylib asset; refines symbols packaging conditions. |
| src/Native/MklImportsArm/MklImportsArm.c | Introduces ARM CBLAS shim implementation (and DFTI stubs) used to enable SymSGD without MKL on ARM. |
| src/Native/CMakeLists.txt | Builds SymSgdNative on ARM and documents why a separate MklImports isn’t built there. |
| src/Microsoft.ML.Mkl.Components/SymSgdClassificationTrainer.cs | Skips MKL load trigger on ARM and fixes P/Invoke bool marshalling for LearnAll. |
| eng/helix.proj | Copies the correct libomp.dylib for macOS ARM64 Helix runs and removes SymSgd install-name patching from Helix step. |
| Directory.Build.targets | Ensures libomp.dylib is copied next to managed assemblies on macOS ARM64 when SymSgdNative is referenced. |
| build/vsts-ci.yml | Uses macOS ARM64 agents for Apple Silicon native asset generation. |
| .vsts-dotnet-ci.yml | Renames/retargets macOS ARM64 job to macOS-15-arm64 pool image. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+17
to
+24
| execute_process( | ||
| COMMAND brew --prefix libomp | ||
| RESULT_VARIABLE BREW_LIBOMP | ||
| OUTPUT_VARIABLE BREW_LIBOMP_PREFIX | ||
| OUTPUT_STRIP_TRAILING_WHITESPACE | ||
| ) | ||
| SET(OPENMP_LIBRARY "${BREW_LIBOMP_PREFIX}/lib/libomp.dylib") | ||
| include_directories("${BREW_LIBOMP_PREFIX}/include") |
Comment on lines
+5
to
+10
| // ARM replacement for Intel MKL (libMklImports.so). | ||
| // | ||
| // This provides a small, self-contained libMklImports for arm/arm64 that | ||
| // covers exactly the symbols SymSGD needs, with no external BLAS dependency. | ||
| // That is important because the cross-compilation sysroots used in CI do not | ||
| // ship OpenBLAS (or any system BLAS), so linking against one is not an option. |
Comment on lines
+18
to
+24
| // MKL DFTI (FFT) functions are stubbed — they are referenced by the managed | ||
| // MKL Components initializer but not used by SymSGD. The stubs return error | ||
| // codes so any actual FFT call fails cleanly rather than crashing. | ||
|
|
||
| // The native build is compiled with -fvisibility=hidden, so every symbol that | ||
| // must be visible to SymSgdNative (the CBLAS routines) or to the managed | ||
| // P/Invoke layer (DftiErrorMessage) has to be exported explicitly. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the ARM64 SymSgd work from #7671 to macOS by building native assets on Apple Silicon agents.
SymSgdNativefor ARM/ARM64 with the self-contained CBLAS shimmacOS-15-arm64Azure Pipelines agents for native macOS ARM64 buildslibomp.dylibbesidelibSymSgdNative.dylib@loader_path/libomp.dylibValidation
runtimes/osx-arm64/native/libSymSgdNative.dylibandlibomp.dylibotoolconfirms@loader_path/libomp.dylibRelated to #5798 and #7671.