1 /* test_thread_safe_arrays.cpp - Tests that Adept arrays are thread-safe
2 
3   Copyright (C) 2017 ECMWF
4 
5   Copying and distribution of this file, with or without modification,
6   are permitted in any medium without royalty provided the copyright
7   notice and this notice are preserved.  This file is offered as-is,
8   without any warranty.
9 
10 */
11 
12 #ifdef _OPENMP
13 #include <omp.h>
14 #endif
15 
16 //#define ADEPT_STORAGE_THREAD_SAFE 1
17 
18 #include <adept_arrays.h>
19 
main(int argc,const char ** argv)20 int main(int argc, const char** argv)
21 {
22   using namespace adept;
23 
24   int N = 2;
25   Matrix A(N,N);
26   SymmMatrix S(N);
27 
28   Matrix B;
29   SymmMatrix T;
30 #ifdef ADEPT_STORAGE_THREAD_SAFE
31   std::cout << "Storage should be thread safe\n";
32   // B shares the data and increases the reference counter of the
33   // shared Storage object. If A goes out of scope, B will "steal" the
34   // data.
35   B >>= A;
36   T >>= S;
37 #else
38   std::cout << "Storage is not thread safe: using soft_link()\n";
39   // B points to the data but does not have access to the Storage
40   // object. If A goes out of scope, B will most likely point to an
41   // inaccessible memory location.
42   B >>= A.soft_link();
43   T >>= S.soft_link();
44 #endif
45 
46   A = 1.0; // Also seen by B
47   S = 2.0; // Also seen by S
48 
49   int nthreads = 1;
50 
51 #ifdef _OPENMP
52   nthreads = omp_get_max_threads();
53   std::cout << omp_get_num_procs() << " processors available running maximum of "
54 	    << nthreads << " threads\n";
55 #else
56   std::cout << "Compiled without OpenMP support: 1 thread\n";
57 #endif
58 
59   // The following almost always causes a crash if the code is not
60   // properly thread safe
61 #pragma omp parallel for
62   for (int i = 0; i < N*1000; ++i) {
63 
64     for (int j = 0; j < N*1000; ++j) {
65       B[j % N] = noalias(B(__,j)) + T.diag_vector();
66     }
67 
68   }
69 
70   if (nthreads > 1) {
71     std::cout << "Parallel subsetting of array zillions of times was successful\n";
72   }
73   else {
74     std::cout << "Serial subsetting of array zillions of times was successful (unsurprisingly)\n";
75   }
76 
77   return 0;
78 
79 }
80