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  !=  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  !=  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