From cbc6fc2353b6fc42d337cd8611c2e409acbba180 Mon Sep 17 00:00:00 2001 From: Martin Kroeker Date: Fri, 9 Oct 2026 11:51:33 +0200 Subject: [PATCH 1/3] Restore the Windows thread server callback code from PR 4577 --- driver/others/blas_server_win32.c | 230 ++++++++++++++++++------------ 1 file changed, 137 insertions(+), 93 deletions(-) diff --git a/driver/others/blas_server_win32.c b/driver/others/blas_server_win32.c index e827ceea0b..b4887f3971 100644 --- a/driver/others/blas_server_win32.c +++ b/driver/others/blas_server_win32.c @@ -64,6 +64,9 @@ typedef struct{ /* We need this global for checking if initialization is finished. */ int blas_server_avail = 0; int blas_omp_threads_local = 1; + +static void * blas_thread_buffer[MAX_CPU_NUMBER]; + /* Local Variables */ static BLASULONG server_lock = 0; @@ -71,7 +74,8 @@ static blas_pool_t pool; static HANDLE blas_threads [MAX_CPU_NUMBER]; static DWORD blas_threads_id[MAX_CPU_NUMBER]; - +static void exec_threads(int, blas_queue_t *, int); +static void adjust_thread_buffers(); static void legacy_exec(void *func, int mode, blas_arg_t *args, void *sb){ @@ -206,14 +210,10 @@ static DWORD WINAPI blas_thread_server(void *arg){ BLASLONG cpu = (BLASLONG)arg; #endif - void *buffer, *sa, *sb; blas_queue_t *queue; DWORD action; HANDLE handles[] = {pool.filled, pool.killed}; - /* Each server needs each buffer */ - buffer = blas_memory_alloc(2); - #ifdef SMP_DEBUG fprintf(STDERR, "Server[%2ld] Thread is started!\n", cpu); #endif @@ -243,91 +243,11 @@ static DWORD WINAPI blas_thread_server(void *arg){ LeaveCriticalSection(&pool.lock); - if (queue) { - int (*routine)(blas_arg_t *, void *, void *, void *, void *, BLASLONG) = queue -> routine; - - if (pool.queue) SetEvent(pool.filled); - - sa = queue -> sa; - sb = queue -> sb; - -#ifdef CONSISTENT_FPCSR - __asm__ __volatile__ ("ldmxcsr %0" : : "m" (queue -> sse_mode)); - __asm__ __volatile__ ("fldcw %0" : : "m" (queue -> x87_mode)); -#endif - -#ifdef SMP_DEBUG - fprintf(STDERR, "Server[%2ld] Started. Mode = 0x%03x M = %3ld N=%3ld K=%3ld\n", - cpu, queue->mode, queue-> args ->m, queue->args->n, queue->args->k); -#endif - - // fprintf(stderr, "queue start[%ld]!!!\n", cpu); - -#ifdef MONITOR - main_status[cpu] = MAIN_RUNNING1; -#endif - - if (sa == NULL) sa = (void *)((BLASLONG)buffer + GEMM_OFFSET_A); - - if (sb == NULL) { - if (!(queue -> mode & BLAS_COMPLEX)){ -#ifdef EXPRECISION - if ((queue -> mode & BLAS_PREC) == BLAS_XDOUBLE){ - sb = (void *)(((BLASLONG)sa + ((XGEMM_P * XGEMM_Q * sizeof(xdouble) - + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); - } else -#endif - if ((queue -> mode & BLAS_PREC) == BLAS_DOUBLE){ -#ifdef BUILD_DOUBLE - sb = (void *)(((BLASLONG)sa + ((DGEMM_P * DGEMM_Q * sizeof(double) - + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); -#endif - } else if ((queue -> mode & BLAS_PREC) == BLAS_SINGLE) { -#ifdef BUILD_SINGLE - sb = (void *)(((BLASLONG)sa + ((SGEMM_P * SGEMM_Q * sizeof(float) - + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); -#endif - } else { - /* Other types in future */ - } - } else { -#ifdef EXPRECISION - if ((queue -> mode & BLAS_PREC) == BLAS_XDOUBLE){ - sb = (void *)(((BLASLONG)sa + ((XGEMM_P * XGEMM_Q * 2 * sizeof(xdouble) - + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); - } else -#endif - if ((queue -> mode & BLAS_PREC) == BLAS_DOUBLE){ -#ifdef BUILD_COMPLEX16 - sb = (void *)(((BLASLONG)sa + ((ZGEMM_P * ZGEMM_Q * 2 * sizeof(double) - + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); -#endif - } else if ((queue -> mode & BLAS_PREC) == BLAS_SINGLE) { -#ifdef BUILD_COMPLEX - sb = (void *)(((BLASLONG)sa + ((CGEMM_P * CGEMM_Q * 2 * sizeof(float) - + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); -#endif - } else { - /* Other types in future */ - } - } - } - - queue->worker_sb = sb; - -#ifdef MONITOR - main_status[cpu] = MAIN_RUNNING2; -#endif - - if (!(queue -> mode & BLAS_LEGACY)) { - - (routine)(queue -> args, queue -> range_m, queue -> range_n, sa, sb, queue -> position); - } else { - legacy_exec(routine, queue -> mode, queue -> args, sb); - } - }else{ - continue; //if queue == NULL - } + if (queue) { + exec_threads(cpu, queue, 0); + } else { + continue; //if queue == NULL + } #ifdef SMP_DEBUG fprintf(STDERR, "Server[%2ld] Finished!\n", cpu); @@ -348,8 +268,6 @@ static DWORD WINAPI blas_thread_server(void *arg){ fprintf(STDERR, "Server[%2ld] Shutdown!\n", cpu); #endif - blas_memory_free(buffer); - return 0; } @@ -361,11 +279,13 @@ int blas_thread_init(void){ LOCK_COMMAND(&server_lock); + adjust_thread_buffers(); + #ifdef SMP_DEBUG fprintf(STDERR, "Initializing Thread(Num. threads = %d)\n", blas_cpu_number); #endif - + if (!blas_server_avail){ InitializeCriticalSection(&pool.lock); @@ -481,6 +401,17 @@ int exec_blas(BLASLONG num, blas_queue_t *queue){ if ((num <= 0) || (queue == NULL)) return 0; +// Redirect to caller's callback routine + if (openblas_threads_callback_) { + int buf_index = 0, i = 0; +#ifndef USE_SIMPLE_THREADED_LEVEL3 + for (i = 0; i < num; i ++) + queue[i].position = i; +#endif + openblas_threads_callback_(1, (openblas_dojob_callback) exec_threads, num, sizeof(blas_queue_t), (void*) queue, buf_index); + return 0; + } + if ((num > 1) && queue -> next) exec_blas_async(1, queue -> next); routine = queue -> routine; @@ -512,6 +443,14 @@ int BLASFUNC(blas_thread_shutdown)(void){ LOCK_COMMAND(&server_lock); + // Free buffers allocated for threads + for (i=0; i < MAX_CPU_NUMBER; i++) { + if (blas_thread_buffer[i] != NULL) { + blas_memory_free(blas_thread_buffer[i]); + blas_thread_buffer[i] = NULL; + } + } + if (blas_server_avail){ SetEvent(pool.killed); @@ -591,3 +530,108 @@ void openblas_set_num_threads(int num) { goto_set_num_threads(num); } + + +static void adjust_thread_buffers() { + + int i=0; + + //adjust buffer for each thread + for(i=0; i < blas_cpu_number; i++){ + if(blas_thread_buffer[i] == NULL){ + blas_thread_buffer[i] = blas_memory_alloc(2); + } + } + for(; i < MAX_CPU_NUMBER; i++){ + if(blas_thread_buffer[i] != NULL){ + blas_memory_free(blas_thread_buffer[i]); + blas_thread_buffer[i] = NULL; + } + } +} + +//Indivitual threads work executor, Helps in setting by synchronization environment and calling inner_threads routine +static void exec_threads(int cpu, blas_queue_t *queue, int buf_index) { + + void *buffer, *sa, *sb; + + buffer = blas_thread_buffer[cpu]; + sa = queue -> sa; + sb = queue -> sb; + + int (*routine)(blas_arg_t *, void *, void *, void *, void *, BLASLONG) = queue -> routine; + + #ifdef CONSISTENT_FPCSR + __asm__ __volatile__ ("ldmxcsr %0" : : "m" (queue -> sse_mode)); + __asm__ __volatile__ ("fldcw %0" : : "m" (queue -> x87_mode)); + #endif + + MT_TRACE("Server[%2ld] Started. Mode = 0x%03x M = %3ld N=%3ld K=%3ld\n", + cpu, queue->mode, queue-> args ->m, queue->args->n, queue->args->k); + + // fprintf(stderr, "queue start[%ld]!!!\n", cpu); + + #ifdef MONITOR + main_status[cpu] = MAIN_RUNNING1; + #endif + + if (sa == NULL) + sa = (void *)((BLASLONG)buffer + GEMM_OFFSET_A); + + if (sb == NULL) { + if (!(queue -> mode & BLAS_COMPLEX)) { +#ifdef EXPRECISION +if ((queue -> mode & BLAS_PREC) == BLAS_XDOUBLE) { + sb = (void *)(((BLASLONG)sa + ((XGEMM_P * XGEMM_Q * sizeof(xdouble) + + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); +} else +#endif + if ((queue -> mode & BLAS_PREC) == BLAS_DOUBLE) { +#ifdef BUILD_DOUBLE + sb = (void *)(((BLASLONG)sa + ((DGEMM_P * DGEMM_Q * sizeof(double) + + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); +#endif + } else if ((queue -> mode & BLAS_PREC) == BLAS_SINGLE) { +#ifdef BUILD_SINGLE + sb = (void *)(((BLASLONG)sa + ((SGEMM_P * SGEMM_Q * sizeof(float) + + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); +#endif + } else { + /* Other types in future */ + } +} else { +#ifdef EXPRECISION +if ((queue -> mode & BLAS_PREC) == BLAS_XDOUBLE){ + sb = (void *)(((BLASLONG)sa + ((XGEMM_P * XGEMM_Q * 2 * sizeof(xdouble) + + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); +} else +#endif + if ((queue -> mode & BLAS_PREC) == BLAS_DOUBLE){ +#ifdef BUILD_COMPLEX16 + sb = (void *)(((BLASLONG)sa + ((ZGEMM_P * ZGEMM_Q * 2 * sizeof(double) + + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); +#endif + } else if ((queue -> mode & BLAS_PREC) == BLAS_SINGLE) { +#ifdef BUILD_COMPLEX + sb = (void *)(((BLASLONG)sa + ((CGEMM_P * CGEMM_Q * 2 * sizeof(float) + + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B); +#endif + } else { + /* Other types in future */ + } +} + queue->sb=sb; + } + + #ifdef MONITOR + main_status[cpu] = MAIN_RUNNING2; + #endif + + if (!(queue -> mode & BLAS_LEGACY)) { + (routine)(queue -> args, queue -> range_m, queue -> range_n, sa, sb, queue -> position); + } else { + legacy_exec(routine, queue -> mode, queue -> args, sb); + } + +} + From 8dfcef9eb76bd8e1efc6f11dee07cb26b2de4a4a Mon Sep 17 00:00:00 2001 From: Martin Kroeker Date: Fri, 9 Oct 2026 16:43:07 +0200 Subject: [PATCH 2/3] fix missed edits --- driver/others/blas_server_win32.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/driver/others/blas_server_win32.c b/driver/others/blas_server_win32.c index b4887f3971..750c3482ec 100644 --- a/driver/others/blas_server_win32.c +++ b/driver/others/blas_server_win32.c @@ -206,9 +206,9 @@ static void legacy_exec(void *func, int mode, blas_arg_t *args, void *sb){ static DWORD WINAPI blas_thread_server(void *arg){ /* Thread identifier */ -#ifdef SMP_DEBUG + BLASLONG cpu = (BLASLONG)arg; -#endif + blas_queue_t *queue; DWORD action; @@ -566,8 +566,10 @@ static void exec_threads(int cpu, blas_queue_t *queue, int buf_index) { __asm__ __volatile__ ("fldcw %0" : : "m" (queue -> x87_mode)); #endif - MT_TRACE("Server[%2ld] Started. Mode = 0x%03x M = %3ld N=%3ld K=%3ld\n", +#ifdef DEBUG + fprintf(STDERR,"Server[%2ld] Started. Mode = 0x%03x M = %3ld N=%3ld K=%3ld\n", cpu, queue->mode, queue-> args ->m, queue->args->n, queue->args->k); +#endif // fprintf(stderr, "queue start[%ld]!!!\n", cpu); From 8721d19844db4d28ad976cce3870534f051088b4 Mon Sep 17 00:00:00 2001 From: Martin Kroeker Date: Sat, 10 Oct 2026 17:54:57 +0200 Subject: [PATCH 3/3] Update blas_server_win32.c --- driver/others/blas_server_win32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driver/others/blas_server_win32.c b/driver/others/blas_server_win32.c index 750c3482ec..4ae93f25fc 100644 --- a/driver/others/blas_server_win32.c +++ b/driver/others/blas_server_win32.c @@ -244,7 +244,8 @@ static DWORD WINAPI blas_thread_server(void *arg){ LeaveCriticalSection(&pool.lock); if (queue) { - exec_threads(cpu, queue, 0); + if (pool.queue) SetEvent(pool.filled); + exec_threads(cpu, queue, 0); } else { continue; //if queue == NULL }