Skip to content

Commit 61cdd1c

Browse files
authored
Add macOS support with Apple Accelerate framework (#32)
This commit adds native support for macOS, enabling hardware-accelerated BLAS and LAPACK operations via Apple's Accelerate framework. Changes: - Updated generator.py to support platform-specific default library names via new darwin_libname parameter - Regenerated JNI C code (blas, lapack, arpack) with `#ifdef __APPLE__` conditionals for macOS library defaults - Modified Java JNI loaders to normalize "Mac OS X" to "macos" and use `.dylib` extension on macOS instead of `.so` - Restructured pom.xml with OS-activated Maven profiles: - linux-native: builds Linux `.so` files (x86_64, aarch64, riscv64) - macos-native: builds macOS `.dylib` files (aarch64, x86_64) using clang - Updated CI workflows to build natives on both Linux and macOS runners, then merge artifacts into a single fat JAR containing all platforms - Updated README with macOS installation instructions and Accelerate documentation The resulting JAR now contains native binaries for 5 platforms: Linux (x86_64, aarch64, riscv64) and macOS (aarch64, x86_64). On macOS, BLAS and LAPACK automatically use Accelerate with no additional installation required. ARPACK requires Homebrew installation. Fixes #6
1 parent 1379442 commit 61cdd1c

File tree

16 files changed

+1450
-973
lines changed

16 files changed

+1450
-973
lines changed

.github/workflows/build-and-test.yml

Lines changed: 109 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,39 @@ on:
1010
branches: [ master ]
1111

1212
jobs:
13-
build:
14-
name: JDK ${{ matrix.jdk }}
13+
build-macos-natives:
14+
name: Build macOS Natives
15+
runs-on: macos-26
16+
steps:
17+
- uses: actions/checkout@v4
18+
- name: Cache M2 local repository
19+
uses: actions/cache@v4
20+
with:
21+
path: ~/.m2/repository
22+
key: m2
23+
- name: Set up JDK 25
24+
uses: actions/setup-java@v4
25+
with:
26+
java-version: 25
27+
distribution: temurin
28+
- name: Build
29+
run: mvn --batch-mode compile
30+
- name: Upload macOS natives
31+
uses: actions/upload-artifact@v4
32+
with:
33+
name: macos-natives
34+
path: |
35+
blas/target/native/macos-*/
36+
lapack/target/native/macos-*/
37+
arpack/target/native/macos-*/
38+
if-no-files-found: error
39+
40+
build-jar:
41+
name: Build JARs
1542
runs-on: ubuntu-latest
16-
env:
17-
LD_LIBRARY_PATH: "/usr/lib/x86_64-linux-gnu"
18-
strategy:
19-
matrix:
20-
jdk: [8, 11, 17, 21, 25]
43+
needs: [build-macos-natives]
2144
steps:
22-
- uses: actions/checkout@v2
45+
- uses: actions/checkout@v4
2346
- name: Cache M2 local repository
2447
uses: actions/cache@v4
2548
with:
@@ -28,20 +51,93 @@ jobs:
2851
- name: Install dependencies
2952
run: |
3053
sudo apt-get -y update
31-
sudo apt-get -y install libopenblas-dev libarpack2-dev gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu gcc-x86-64-linux-gnu
32-
# Build with JDK 25
54+
sudo apt-get -y install gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu gcc-x86-64-linux-gnu
3355
- name: Set up JDK 25
3456
uses: actions/setup-java@v4
3557
with:
3658
java-version: 25
3759
distribution: temurin
60+
- name: Download macOS natives
61+
uses: actions/download-artifact@v4
62+
with:
63+
name: macos-natives
64+
path: .
3865
- name: Build
39-
run: mvn --batch-mode compile test-compile
40-
# Test with JDK ${{ matrix.jdk }}
66+
run: mvn --batch-mode compile test-compile process-classes jar:jar
67+
- name: Log content of jar files
68+
run: |
69+
for module in blas lapack arpack; do
70+
echo "=== Contents of ${module}/target/${module}-*.jar:"
71+
jar tf ${module}/target/${module}-*.jar
72+
done
73+
- name: Upload target folder
74+
uses: actions/upload-artifact@v4
75+
with:
76+
name: target-dir
77+
path: |
78+
blas/target/
79+
lapack/target/
80+
arpack/target/
81+
if-no-files-found: error
82+
83+
test-linux:
84+
name: Test ${{ matrix.runs-on }} JDK ${{ matrix.jdk }}
85+
runs-on: ${{ matrix.runs-on }}
86+
needs: [build-jar]
87+
strategy:
88+
matrix:
89+
jdk: [8, 11, 17, 21, 25]
90+
runs-on: [ubuntu-24.04, ubuntu-24.04-arm]
91+
steps:
92+
- uses: actions/checkout@v4
93+
- name: Cache M2 local repository
94+
uses: actions/cache@v4
95+
with:
96+
path: ~/.m2/repository
97+
key: m2
98+
- name: Install dependencies
99+
run: |
100+
sudo apt-get -y update
101+
sudo apt-get -y install libopenblas-dev libarpack2-dev
102+
- name: Download target folder
103+
uses: actions/download-artifact@v4
104+
with:
105+
name: target-dir
106+
path: .
107+
- name: Set up JDK ${{ matrix.jdk }}
108+
uses: actions/setup-java@v4
109+
with:
110+
java-version: ${{ matrix.jdk }}
111+
distribution: temurin
112+
- name: Test
113+
run: mvn --batch-mode --projects blas,lapack,arpack surefire:test --fail-at-end
114+
115+
test-macos:
116+
name: Test ${{ matrix.runs-on }} JDK ${{ matrix.jdk }}
117+
runs-on: ${{ matrix.runs-on }}
118+
needs: [build-jar]
119+
strategy:
120+
matrix:
121+
jdk: [11, 17, 21, 25]
122+
runs-on: [macos-15-intel, macos-26]
123+
steps:
124+
- uses: actions/checkout@v4
125+
- name: Cache M2 local repository
126+
uses: actions/cache@v4
127+
with:
128+
path: ~/.m2/repository
129+
key: m2
130+
- name: Install dependencies
131+
run: brew install arpack
132+
- name: Download target folder
133+
uses: actions/download-artifact@v4
134+
with:
135+
name: target-dir
136+
path: .
41137
- name: Set up JDK ${{ matrix.jdk }}
42138
uses: actions/setup-java@v4
43139
with:
44140
java-version: ${{ matrix.jdk }}
45141
distribution: temurin
46142
- name: Test
47-
run: mvn --batch-mode --projects blas,lapack,arpack surefire:test
143+
run: mvn --batch-mode --projects blas,lapack,arpack surefire:test --fail-at-end

.github/workflows/release.yml

Lines changed: 125 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,86 @@ on:
1010
name: Release
1111

1212
jobs:
13-
build:
14-
name: Build & Test
13+
build-macos-natives:
14+
name: Build macOS Natives
15+
runs-on: macos-26
16+
steps:
17+
- uses: actions/checkout@v4
18+
- name: Cache M2 local repository
19+
uses: actions/cache@v4
20+
with:
21+
path: ~/.m2/repository
22+
key: m2
23+
- name: Set up JDK 25
24+
uses: actions/setup-java@v4
25+
with:
26+
java-version: 25
27+
distribution: temurin
28+
- name: Build
29+
run: mvn --batch-mode compile
30+
- name: Upload macOS natives
31+
uses: actions/upload-artifact@v4
32+
with:
33+
name: macos-natives
34+
path: |
35+
blas/target/native/macos-*/
36+
lapack/target/native/macos-*/
37+
arpack/target/native/macos-*/
38+
if-no-files-found: error
39+
40+
build-jar:
41+
name: Build JARs
1542
runs-on: ubuntu-latest
16-
env:
17-
LD_LIBRARY_PATH: "/usr/lib/x86_64-linux-gnu"
43+
needs: [build-macos-natives]
44+
steps:
45+
- uses: actions/checkout@v4
46+
- name: Cache M2 local repository
47+
uses: actions/cache@v4
48+
with:
49+
path: ~/.m2/repository
50+
key: m2
51+
- name: Install dependencies
52+
run: |
53+
sudo apt-get -y update
54+
sudo apt-get -y install gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu gcc-x86-64-linux-gnu
55+
- name: Set up JDK 25
56+
uses: actions/setup-java@v4
57+
with:
58+
java-version: 25
59+
distribution: temurin
60+
- name: Download macOS natives
61+
uses: actions/download-artifact@v4
62+
with:
63+
name: macos-natives
64+
path: .
65+
- name: Build
66+
run: mvn --batch-mode compile test-compile process-classes jar:jar
67+
- name: Log content of jar files
68+
run: |
69+
for module in blas lapack arpack; do
70+
echo "=== Contents of ${module}/target/${module}-*.jar:"
71+
jar tf ${module}/target/${module}-*.jar
72+
done
73+
- name: Upload target folder
74+
uses: actions/upload-artifact@v4
75+
with:
76+
name: target-dir
77+
path: |
78+
blas/target/
79+
lapack/target/
80+
arpack/target/
81+
if-no-files-found: error
82+
83+
test-linux:
84+
name: Test ${{ matrix.runs-on }} JDK ${{ matrix.jdk }}
85+
runs-on: ${{ matrix.runs-on }}
86+
needs: [build-jar]
1887
strategy:
1988
matrix:
2089
jdk: [8, 11, 17, 21, 25]
90+
runs-on: [ubuntu-24.04, ubuntu-24.04-arm]
2191
steps:
22-
- uses: actions/checkout@v2
92+
- uses: actions/checkout@v4
2393
- name: Cache M2 local repository
2494
uses: actions/cache@v4
2595
with:
@@ -28,62 +98,89 @@ jobs:
2898
- name: Install dependencies
2999
run: |
30100
sudo apt-get -y update
31-
sudo apt-get -y install libopenblas-dev libarpack2-dev gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu gcc-x86-64-linux-gnu
32-
# Build with JDK 17
33-
- name: Set up JDK 17
101+
sudo apt-get -y install libopenblas-dev libarpack2-dev
102+
- name: Download target folder
103+
uses: actions/download-artifact@v4
104+
with:
105+
name: target-dir
106+
path: .
107+
- name: Set up JDK ${{ matrix.jdk }}
34108
uses: actions/setup-java@v4
35109
with:
36-
java-version: 17
110+
java-version: ${{ matrix.jdk }}
37111
distribution: temurin
38-
- name: Build
39-
run: mvn --batch-mode compile test-compile
40-
# Test with JDK ${{ matrix.jdk }}
112+
- name: Test
113+
run: mvn --batch-mode --projects blas,lapack,arpack surefire:test --fail-at-end
114+
115+
test-macos:
116+
name: Test ${{ matrix.runs-on }} JDK ${{ matrix.jdk }}
117+
runs-on: ${{ matrix.runs-on }}
118+
needs: [build-jar]
119+
strategy:
120+
matrix:
121+
jdk: [11, 17, 21, 25]
122+
runs-on: [macos-15-intel, macos-26]
123+
steps:
124+
- uses: actions/checkout@v4
125+
- name: Cache M2 local repository
126+
uses: actions/cache@v4
127+
with:
128+
path: ~/.m2/repository
129+
key: m2
130+
- name: Install dependencies
131+
run: brew install arpack
132+
- name: Download target folder
133+
uses: actions/download-artifact@v4
134+
with:
135+
name: target-dir
136+
path: .
41137
- name: Set up JDK ${{ matrix.jdk }}
42138
uses: actions/setup-java@v4
43139
with:
44140
java-version: ${{ matrix.jdk }}
45141
distribution: temurin
46142
- name: Test
47-
run: mvn --batch-mode --projects blas,lapack,arpack surefire:test
143+
run: mvn --batch-mode --projects blas,lapack,arpack surefire:test --fail-at-end
48144

49145
release:
50146
name: Release
51147
runs-on: ubuntu-latest
52-
needs: [build]
148+
needs: [build-jar, test-linux, test-macos]
53149
# Map step output to job output
54150
outputs:
55151
release_upload_url: ${{ steps.create_release.outputs.upload_url }}
56152
steps:
57-
- uses: actions/checkout@v2
153+
- uses: actions/checkout@v4
58154
- name: Cache M2 local repository
59155
uses: actions/cache@v4
60156
with:
61157
path: ~/.m2/repository
62158
key: m2
63-
- name: Install dependencies
159+
- name: Download JARs
160+
uses: actions/download-artifact@v4
161+
with:
162+
name: jars
163+
path: .
164+
- name: Log content of jar files
64165
run: |
65-
sudo apt-get -y update
66-
sudo apt-get -y install gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu gcc-x86-64-linux-gnu
67-
- name: Set up JDK 17
166+
for module in blas lapack arpack; do
167+
echo "=== Contents of ${module}/target/${module}-*.jar:"
168+
jar tf ${module}/target/${module}-*.jar
169+
done
170+
- name: Set up JDK 25
68171
uses: actions/setup-java@v4
69172
with: # running setup-java again overwrites the settings.xml
70-
java-version: 17
173+
java-version: 25
71174
distribution: temurin
72175
server-id: central
73176
server-username: MAVEN_USERNAME
74177
server-password: MAVEN_PASSWORD
75178
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
76179
- name: Publish to Sonatype OSSRH
77-
run: mvn --batch-mode -DskipTests=true deploy
180+
run: mvn --batch-mode -DskipTests deploy
78181
env:
79182
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
80183
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
81-
- name: Upload Benchmarks
82-
uses: actions/upload-artifact@v4
83-
with:
84-
name: benchmarks
85-
path: benchmarks/target/netlib-benchmarks.jar
86-
if-no-files-found: error
87184
- name: Create Release
88185
id: create_release
89186
uses: actions/create-release@v1
@@ -97,7 +194,7 @@ jobs:
97194
benchmark:
98195
name: Run benchmarks
99196
runs-on: [self-hosted, linux, x64]
100-
needs: [release]
197+
needs: [release, build-jar]
101198
strategy:
102199
matrix:
103200
jdk: [8, 11, 17]

0 commit comments

Comments
 (0)