Allow optimization for small m, large n only if it can be made threadsafe
authorMartin Kroeker <martin@ruby.chemie.uni-freiburg.de>
Sat, 10 Nov 2018 14:45:54 +0000 (15:45 +0100)
committerGitHub <noreply@github.com>
Sat, 10 Nov 2018 14:45:54 +0000 (15:45 +0100)
otherwise the introduction of a static array in 8e5a108 to improve #532 breaks concurrent calls from multiple threads as seen in #1844

driver/level2/gemv_thread.c

index 0614548..fc4e4f7 100644 (file)
 #endif
 #endif
 
-#ifndef TRANSA
+#ifndef thread_local
+# if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__
+#  define thread_local _Thread_local
+# elif defined _WIN32 && ( \
+       defined _MSC_VER || \
+       defined __ICL || \
+       defined __DMC__ || \
+       defined __BORLANDC__ )
+#  define thread_local __declspec(thread) 
+/* note that ICC (linux) and Clang are covered by __GNUC__ */
+# elif defined __GNUC__ || \
+       defined __SUNPRO_C || \
+       defined __xlC__
+#  define thread_local __thread
+# else
+# define UNSAFE
+#endif
+#endif
+#if defined USE_OPENMP
+#undef UNSAFE
+#endif
+
+#if !defined(TRANSA) && !defined(UNSAFE)
 #define Y_DUMMY_NUM 1024
+#if defined(USE_OPENMP)
 static FLOAT y_dummy[Y_DUMMY_NUM];
+#pragma omp threadprivate(y_dummy)
+# else
+static thread_local FLOAT y_dummy[Y_DUMMY_NUM];
+# endif
 #endif
 
 static int gemv_kernel(blas_arg_t *args, BLASLONG *range_m, BLASLONG *range_n, FLOAT *dummy1, FLOAT *buffer, BLASLONG pos){
@@ -105,10 +132,12 @@ static int gemv_kernel(blas_arg_t *args, BLASLONG *range_m, BLASLONG *range_n, F
 #ifdef TRANSA
     y += n_from * incy * COMPSIZE;
 #else
+# ifndef UNSAFE
     //for split matrix row (n) direction and vector x of gemv_n
     x += n_from * incx * COMPSIZE;
     //store partial result for every thread
     y += (m_to - m_from) * 1 * COMPSIZE * pos;
+# endif
 #endif
   }
 
@@ -136,7 +165,7 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT *alpha, FLOAT *a, BLASLONG lda, FLOAT *x
 
   BLASLONG width, i, num_cpu;
 
-#ifndef TRANSA
+#if !defined(TRANSA) && !defined(iUNSAFE)
   int split_x=0;
 #endif
 
@@ -212,7 +241,7 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT *alpha, FLOAT *a, BLASLONG lda, FLOAT *x
     i -= width;
   }
 
-#ifndef TRANSA
+#if !defined(TRANSA) && !defined(UNSAFE) 
   //try to split matrix on row direction and x.
   //Then, reduction.
   if (num_cpu < nthreads) {
@@ -272,7 +301,7 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT *alpha, FLOAT *a, BLASLONG lda, FLOAT *x
     exec_blas(num_cpu, queue);
   }
 
-#ifndef TRANSA
+#if !defined(TRANSA) && !defined(UNSAFE)
   if(split_x==1){
     //reduction
     for(i=0; i<num_cpu; i++){