cxx11_tensor_thread_local.cpp File Reference
#include <iostream>
#include <unordered_set>
#include "main.h"
#include <Eigen/ThreadPool>

Classes

struct  Counter
 
struct  InitCounter
 

Macros

#define EIGEN_USE_THREADS
 

Functions

void test_simple_thread_local ()
 
void test_zero_sized_thread_local ()
 
void test_large_number_of_tasks_no_spill ()
 
void test_large_number_of_tasks_with_spill ()
 
 EIGEN_DECLARE_TEST (cxx11_tensor_thread_local)
 

Macro Definition Documentation

◆ EIGEN_USE_THREADS

#define EIGEN_USE_THREADS

Function Documentation

◆ EIGEN_DECLARE_TEST()

EIGEN_DECLARE_TEST ( cxx11_tensor_thread_local  )
139  {
144 }
void test_large_number_of_tasks_with_spill()
Definition: cxx11_tensor_thread_local.cpp:107
void test_zero_sized_thread_local()
Definition: cxx11_tensor_thread_local.cpp:57
void test_large_number_of_tasks_no_spill()
Definition: cxx11_tensor_thread_local.cpp:73
void test_simple_thread_local()
Definition: cxx11_tensor_thread_local.cpp:34
#define CALL_SUBTEST(FUNC)
Definition: main.h:382

References CALL_SUBTEST, test_large_number_of_tasks_no_spill(), test_large_number_of_tasks_with_spill(), test_simple_thread_local(), and test_zero_sized_thread_local().

◆ test_large_number_of_tasks_no_spill()

void test_large_number_of_tasks_no_spill ( )
73  {
74  int num_threads = internal::random<int>(4, 32);
75  Eigen::ThreadPool thread_pool(num_threads);
77 
78  int num_tasks = 10000;
79  Eigen::Barrier barrier(num_tasks);
80 
81  for (int i = 0; i < num_tasks; ++i) {
82  thread_pool.Schedule([&counter, &barrier]() {
83  Counter& local = counter.local();
84  local.inc();
85  barrier.Notify();
86  });
87  }
88 
89  barrier.Wait();
90 
91  int total = 0;
92  std::unordered_set<std::thread::id> unique_threads;
93 
94  counter.ForEach([&](std::thread::id id, Counter& cnt) {
95  total += cnt.value();
96  unique_threads.insert(id);
97  });
98 
99  VERIFY_IS_EQUAL(total, num_tasks);
100  // Not all threads in a pool might be woken up to execute submitted tasks.
101  // Also thread_pool.Schedule() might use current thread if queue is full.
102  VERIFY_IS_EQUAL(unique_threads.size() <= (static_cast<size_t>(num_threads + 1)), true);
103 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Definition: Barrier.h:21
Definition: ThreadLocal.h:112
Definition: NonBlockingThreadPool.h:19
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:367
Definition: cxx11_tensor_thread_local.cpp:16
int value()
Definition: cxx11_tensor_thread_local.cpp:24
Definition: cxx11_tensor_thread_local.cpp:30

References Eigen::ThreadLocal< T, Initialize, Release >::ForEach(), i, Eigen::ThreadLocal< T, Initialize, Release >::local(), Eigen::Barrier::Notify(), Eigen::ThreadPoolTempl< Environment >::Schedule(), Counter::value(), VERIFY_IS_EQUAL, and Eigen::Barrier::Wait().

Referenced by EIGEN_DECLARE_TEST().

◆ test_large_number_of_tasks_with_spill()

void test_large_number_of_tasks_with_spill ( )
107  {
108  int num_threads = internal::random<int>(4, 32);
109  Eigen::ThreadPool thread_pool(num_threads);
111 
112  int num_tasks = 10000;
113  Eigen::Barrier barrier(num_tasks);
114 
115  for (int i = 0; i < num_tasks; ++i) {
116  thread_pool.Schedule([&counter, &barrier]() {
117  Counter& local = counter.local();
118  local.inc();
119  barrier.Notify();
120  });
121  }
122 
123  barrier.Wait();
124 
125  int total = 0;
126  std::unordered_set<std::thread::id> unique_threads;
127 
128  counter.ForEach([&](std::thread::id id, Counter& cnt) {
129  total += cnt.value();
130  unique_threads.insert(id);
131  });
132 
133  VERIFY_IS_EQUAL(total, num_tasks);
134  // Not all threads in a pool might be woken up to execute submitted tasks.
135  // Also thread_pool.Schedule() might use current thread if queue is full.
136  VERIFY_IS_EQUAL(unique_threads.size() <= (static_cast<size_t>(num_threads + 1)), true);
137 }

References Eigen::ThreadLocal< T, Initialize, Release >::ForEach(), i, Eigen::ThreadLocal< T, Initialize, Release >::local(), Eigen::Barrier::Notify(), Eigen::ThreadPoolTempl< Environment >::Schedule(), Counter::value(), VERIFY_IS_EQUAL, and Eigen::Barrier::Wait().

Referenced by EIGEN_DECLARE_TEST().

◆ test_simple_thread_local()

void test_simple_thread_local ( )
34  {
35  int num_threads = internal::random<int>(4, 32);
36  Eigen::ThreadPool thread_pool(num_threads);
38 
39  int num_tasks = 3 * num_threads;
40  Eigen::Barrier barrier(num_tasks);
41 
42  for (int i = 0; i < num_tasks; ++i) {
43  thread_pool.Schedule([&counter, &barrier]() {
44  Counter& local = counter.local();
45  local.inc();
46 
47  std::this_thread::sleep_for(std::chrono::milliseconds(100));
48  barrier.Notify();
49  });
50  }
51 
52  barrier.Wait();
53 
54  counter.ForEach([](std::thread::id, Counter& cnt) { VERIFY_IS_EQUAL(cnt.value(), 3); });
55 }

References Eigen::ThreadLocal< T, Initialize, Release >::ForEach(), i, Eigen::ThreadLocal< T, Initialize, Release >::local(), Eigen::Barrier::Notify(), Eigen::ThreadPoolTempl< Environment >::Schedule(), Counter::value(), VERIFY_IS_EQUAL, and Eigen::Barrier::Wait().

Referenced by EIGEN_DECLARE_TEST().

◆ test_zero_sized_thread_local()

void test_zero_sized_thread_local ( )
57  {
59 
60  Counter& local = counter.local();
61  local.inc();
62 
63  int total = 0;
64  counter.ForEach([&total](std::thread::id, Counter& cnt) {
65  total += cnt.value();
66  VERIFY_IS_EQUAL(cnt.value(), 1);
67  });
68 
69  VERIFY_IS_EQUAL(total, 1);
70 }

References Eigen::ThreadLocal< T, Initialize, Release >::ForEach(), Eigen::ThreadLocal< T, Initialize, Release >::local(), Counter::value(), and VERIFY_IS_EQUAL.

Referenced by EIGEN_DECLARE_TEST().