3131 } MKLVersion ;
3232
3333
34+ /* Apple Accelerate doesn't allow setting the number of threads directly, it only has an
35+ * option to do single-threaded or multi-threaded. That is controlled via the BLASSetThreading
36+ * API introduced in macOS 15.
37+ *
38+ * These constants are from the vecLib.framework/Headers/thread_api.h file
39+ */
40+ #define ACCELERATE_BLAS_THREADING_MULTI_THREADED 0
41+ #define ACCELERATE_BLAS_THREADING_SINGLE_THREADED 1
42+
3443/*
3544 * We provide a flexible thread getter/setter interface here; by calling `lbt_set_num_threads()`
3645 * libblastrampoline will propagate the call through to its loaded libraries as long as the
@@ -50,6 +59,7 @@ static char * getter_names[MAX_THREADING_NAMES] = {
5059 "nvpl_lapack_get_max_threads" ,
5160 // We special-case MKL in the lookup loop below
5261 //"MKL_Domain_Get_Max_Threads",
62+ // We special-case Apple Accelerate below
5363 NULL
5464};
5565
@@ -60,6 +70,7 @@ static char * setter_names[MAX_THREADING_NAMES] = {
6070 "nvpl_lapack_set_num_threads" ,
6171 // We special-case MKL in the lookup loop below
6272 //"MKL_Domain_Set_Num_Threads",
73+ // We special-case Apple Accelerate below
6374 NULL
6475};
6576
@@ -129,6 +140,22 @@ LBT_DLLEXPORT int32_t lbt_get_num_threads() {
129140 }
130141 }
131142 }
143+
144+ // Special case Apple Accelerate because we have to determine if we are single-threaded or multi-threaded
145+ // This API only exists on macOS 15+.
146+ int (* fptr_acc )(void ) = lookup_symbol (lib -> handle , "BLASGetThreading" );
147+ if (fptr_acc != NULL ) {
148+ int nthreads = fptr_acc ();
149+
150+ if (nthreads == ACCELERATE_BLAS_THREADING_MULTI_THREADED ) {
151+ // This number is arbitrary right now, but greater than 1 to mean multi-threaded.
152+ // TODO: Can we guestimate the number of threads from the APPLE_NTHREADS symbol in accelerate?
153+ max_threads = 2 ;
154+ } else {
155+ // Single-threaded
156+ max_threads = max (max_threads , 1 );
157+ }
158+ }
132159 }
133160 return max_threads ;
134161}
@@ -157,5 +184,16 @@ LBT_DLLEXPORT void lbt_set_num_threads(int32_t nthreads) {
157184 fptr (nthreads , MKL_DOMAIN_BLAS );
158185 fptr (nthreads , MKL_DOMAIN_LAPACK );
159186 }
187+
188+ // Special case Apple Accelerate because we have to determine if we must set multi-threaded or single-threaded
189+ // This API only exists on macOS 15+.
190+ int (* fptr_acc )(int ) = lookup_symbol (lib -> handle , "BLASSetThreading" );
191+ if (fptr_acc != NULL ) {
192+ if (nthreads > 1 ) {
193+ fptr_acc (ACCELERATE_BLAS_THREADING_MULTI_THREADED );
194+ } else {
195+ fptr_acc (ACCELERATE_BLAS_THREADING_SINGLE_THREADED );
196+ }
197+ }
160198 }
161199}
0 commit comments