Skip to content

Use Apple Accelerate as BLAS/LAPACK backend on macOS #89

Description

@Ionizing

Summary

Apple shipps Accelerate Framework with macOS, which provides BLAS/LAPACK interface to accelerate related routines. I tested it and saw at least 1x improvement compared to OpenBLAS on my MacBook Air 2025 with M4 10cores.

So I wonder if there can be some improvements on the CMake configuration files, so that it can utilize Apple Accelerate for better performance on nda on macOS.

Motivation

Use Apple Accelerate to gain higher performance.

CMake commands build libnda_c and libh5

Use OpenBLAS as backend

cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/apps/nda_openblas \
    -DCMAKE_BUILD_TYPE="Release" \
    -DCMAKE_C_COMPILER="gcc-14" \
    -DCMAKE_CXX_COMPILER="g++-14"

make -j4 && make install

There should be some message reads "Can't build with Accelerate Framework on OSX, trying to find OpenBLAS instead" in the log:

-- -------- Lapack detection -------------
-- Can't build with Accelerate Framework on OSX, trying to find OpenBLAS instead...
-- Looking for sgemm_
-- Looking for sgemm_ - found
-- Found BLAS: /opt/homebrew/opt/openblas/lib/libopenblas.dylib
-- Looking for cheev_
-- Looking for cheev_ - found
-- Found LAPACK: /opt/homebrew/opt/openblas/lib/libopenblas.dylib;/opt/homebrew/opt/openblas/lib/libopenblas.dylib

Use Apple Accelerate as backend

cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/apps/nda_accelerate \
    -DCMAKE_BUILD_TYPE="Release" \
    -DCMAKE_C_COMPILER="gcc-14" \
    -DCMAKE_CXX_COMPILER="g++-14" \
    -DBLAS_LIBRARIES="/Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk/System/Library/Frameworks/Accelerate.framework" \
    -DLAPACK_LIBRARIES="/Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk/System/Library/Frameworks/Accelerate.framework"

make -j4 && make install

Then cmake should be able to find BLAS and LAPACK inside Accelerate Framework, and the log reads

-- -------- Lapack detection -------------
-- Can't build with Accelerate Framework on OSX, trying to find OpenBLAS instead...
-- Found BLAS: /Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk/System/Library/Frameworks/Accelerate.framework
-- Found LAPACK: /Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk/System/Library/Frameworks/Accelerate.framework

Test code

Here is the test source code main.cpp

#include <iostream>
#include <chrono>
#include <nda/nda.hpp>
#include <nda/h5.hpp>

using namespace nda;
using namespace std::literals;

const int N = 100;

int main() {
    array<double, 2> A = rand(1000, 1000);
    array<double, 2> B = rand(1000, 1000);

    auto t0 = std::chrono::steady_clock::now();
    for (int i=0; i!=N; ++i) {
        array<double, 2> C = matmul(A, B);
    }
    auto t1 = std::chrono::steady_clock::now();
    auto dt = (t1 - t0) * 1.0 / N;

    std::cout << "dt = " << dt/1.0ms << "ms" << std::endl;

    return 0;
}

The CMakeLists.txt:

cmake_minimum_required(VERSION 3.20)
project(nda_test CXX)

# set required standard
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# find nda
find_package(nda REQUIRED CONFIG)

# build the example
add_executable(ex main.cpp)
target_link_libraries(ex nda::nda_c)

Build and test commands:

#!/bin/bash

source ~/apps/nda_openblas/share/nda/ndavars.sh
# source ~/apps/nda_accelerate/share/nda/ndavars.sh

cmake .. \
    -DCMAKE_BUILD_TYPE="Release" \
    -DCMAKE_CXX_COMPILER="g++-14"

make && ./ex

Result

I only performed the matrix multiplication with two 1000x1000 random matrices, so the benchmark is not that sufficient.

BLAS Vendor Time used (ms)
OpenBLAS 12.488
Apple Accelerate 5.16634

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions