Skip to content

Commit d0ad3da

Browse files
committed
WIP
1 parent ad9ccc5 commit d0ad3da

File tree

4 files changed

+71
-43
lines changed

4 files changed

+71
-43
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,9 @@ elseif (DEBUG_MEMORY STREQUAL "Thread")
556556
set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=thread,undefined \
557557
-fno-omit-frame-pointer")
558558

559-
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=thread,undefined \
559+
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=thread \
560560
-fno-omit-frame-pointer ")
561-
set (CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=thread,undefined \
561+
set (CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=thread \
562562
-fno-omit-frame-pointer ")
563563

564564
elseif (DEBUG_MEMORY STREQUAL "Leak")

check/TestHighsParallel.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -218,26 +218,26 @@ TEST_CASE("MatrixMultHighs", "[parallel]") {
218218
matrix_multiplication("highs", parallel::num_threads(), 1);
219219
}
220220

221-
TEST_CASE("FibonacciTasksHighs", "[parallel]") {
222-
HighsTaskExecutor::shutdown();
223-
auto beg = std::chrono::high_resolution_clock::now();
224-
parallel::initialize_scheduler(numThreads);
225-
int64_t result = fib(41);
226-
auto end = std::chrono::high_resolution_clock::now();
227-
228-
if (dev_run)
229-
std::cout << "time elapsed for fib(41) with HiGHS work stealing: "
230-
<< (std::chrono::duration_cast<std::chrono::microseconds>(end -
231-
beg)
232-
.count() /
233-
1e3)
234-
<< "ms" << std::endl;
235-
236-
// REQUIRE(result == 4807526976);
237-
// REQUIRE(result == 20365011074);
238-
// fib 41
239-
REQUIRE(result == 267914296);
240-
}
221+
// TEST_CASE("FibonacciTasksHighs", "[parallel]") {
222+
// HighsTaskExecutor::shutdown();
223+
// auto beg = std::chrono::high_resolution_clock::now();
224+
// parallel::initialize_scheduler(numThreads);
225+
// int64_t result = fib(41);
226+
// auto end = std::chrono::high_resolution_clock::now();
227+
228+
// if (dev_run)
229+
// std::cout << "time elapsed for fib(41) with HiGHS work stealing: "
230+
// << (std::chrono::duration_cast<std::chrono::microseconds>(end -
231+
// beg)
232+
// .count() /
233+
// 1e3)
234+
// << "ms" << std::endl;
235+
236+
// // REQUIRE(result == 4807526976);
237+
// // REQUIRE(result == 20365011074);
238+
// // fib 41
239+
// REQUIRE(result == 267914296);
240+
// }
241241

242242
#if 0
243243
TEST_CASE("MatrixMultOmp", "[parallel]") {

highs/parallel/HighsSplitDeque.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,28 @@
2929
#include "util/HighsInt.h"
3030
#include "util/HighsRandom.h"
3131

32+
#ifdef __has_feature
33+
#if __has_feature(thread_sanitizer)
34+
#define TSAN_ENABLED
35+
#endif
36+
#endif
37+
38+
#ifdef __SANITIZE_THREAD__
39+
#define TSAN_ENABLED
40+
#endif
41+
42+
#ifdef TSAN_ENABLED
43+
#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \
44+
AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))
45+
#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \
46+
AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr))
47+
extern "C" void AnnotateHappensBefore(const char* f, int l, void* addr);
48+
extern "C" void AnnotateHappensAfter(const char* f, int l, void* addr);
49+
#else
50+
#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
51+
#define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
52+
#endif
53+
3254
class HighsSplitDeque {
3355
using cache_aligned = highs::cache_aligned;
3456

@@ -134,6 +156,9 @@ class HighsSplitDeque {
134156

135157
void publishWork(HighsSplitDeque* localDeque) {
136158
HighsSplitDeque* sleeper = popSleeper(localDeque);
159+
160+
// TSAN_ANNOTATE_HAPPENS_BEFORE(sleeper);
161+
137162
while (sleeper) {
138163
uint32_t t = localDeque->selfStealAndGetTail();
139164
if (t == localDeque->ownerData.splitCopy) {
@@ -143,6 +168,7 @@ class HighsSplitDeque {
143168
std::memory_order_relaxed);
144169
haveJobs.fetch_add(-1, std::memory_order_release);
145170
}
171+
// TSAN_ANNOTATE_HAPPENS_AFTER(sleeper);
146172
pushSleeper(sleeper);
147173
return;
148174
} else {
@@ -159,17 +185,23 @@ class HighsSplitDeque {
159185
return;
160186
}
161187

188+
// TSAN_ANNOTATE_HAPPENS_AFTER(sleeper);
162189
sleeper = popSleeper(localDeque);
163190
}
164191
}
165192

166193
HighsTask* waitForNewTask(HighsSplitDeque* localDeque) {
167194
pushSleeper(localDeque);
168195
localDeque->stealerData.semaphore.acquire();
196+
// std::cout << " return injected task read " << &localDeque->stealerData.injectedTask << std::endl;
169197
return localDeque->stealerData.injectedTask;
170198
}
171199
};
172200

201+
// const HighsTask * getInjectedTask() {
202+
// return stealerData.injectedTask;
203+
// }
204+
173205
private:
174206
static_assert(sizeof(OwnerData) <= 64,
175207
"sizeof(OwnerData) exceeds cache line size");
@@ -439,6 +471,13 @@ class HighsSplitDeque {
439471

440472
void injectTaskAndNotify(HighsTask* t) {
441473
stealerData.injectedTask = t;
474+
475+
// std::cout << " injected task write " << &stealerData.injectedTask << std::endl;
476+
477+
478+
// TSAN_ANNOTATE_HAPPENS_BEFORE(&stealerData.injectedTask);
479+
// TSAN_ANNOTATE_HAPPENS_AFTER(&stealerData);
480+
442481
stealerData.semaphore.release();
443482
}
444483

highs/parallel/HighsTaskExecutor.h

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,6 @@
2828
#include "util/HighsInt.h"
2929
#include "util/HighsRandom.h"
3030

31-
#ifdef __has_feature
32-
#if __has_feature(thread_sanitizer)
33-
#define TSAN_ENABLED
34-
#endif
35-
#endif
36-
37-
#ifdef __SANITIZE_THREAD__
38-
#define TSAN_ENABLED
39-
#endif
40-
41-
#ifdef TSAN_ENABLED
42-
#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \
43-
AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))
44-
#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \
45-
AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr))
46-
extern "C" void AnnotateHappensBefore(const char* f, int l, void* addr);
47-
extern "C" void AnnotateHappensAfter(const char* f, int l, void* addr);
48-
#else
49-
#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
50-
#define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
51-
#endif
5231

5332
class HighsTaskExecutor {
5433
public:
@@ -127,8 +106,16 @@ class HighsTaskExecutor {
127106
threadLocalWorkerDeque() = localDeque;
128107

129108
HighsTask* currentTask = ptr->workerBunk->waitForNewTask(localDeque);
109+
110+
// auto ptr = localDeque->getInjectedTask();
111+
// TSAN_ANNOTATE_HAPPENS_BEFORE(localDeque->getInjectedTask());
112+
130113
while (currentTask != nullptr) {
131114
localDeque->runStolenTask(currentTask);
115+
// TSAN_ANNOTATE_HAPPENS_BEFORE(currentTask);
116+
117+
// TSAN_ANNOTATE_HAPPENS_AFTER(currentTask);
118+
132119

133120
currentTask = ptr->random_steal_loop(localDeque);
134121
if (currentTask != nullptr) continue;
@@ -185,6 +172,7 @@ std::cout << "TSAN is OFF" << std::endl;
185172
// now inject the null task as termination signal to every worker
186173
for (auto& workerDeque : workerDeques) {
187174
workerDeque->injectTaskAndNotify(nullptr);
175+
// TSAN_ANNOTATE_HAPPENS_AFTER(workerDeque->getInjectedTask());
188176
}
189177

190178
// only block if called on main thread, otherwise deadlock may occur
@@ -193,6 +181,7 @@ std::cout << "TSAN is OFF" << std::endl;
193181
// TSAN_ANNOTATE_HAPPENS_AFTER(&workerThread);
194182
// std::cout <<"happens after thread blocking and isMain" << ": " << &workerThread << std::endl;
195183
workerThread.join();
184+
// std::cout <<"happens after join" << std::endl;
196185
}
197186
} else {
198187
for (auto& workerThread : workerThreads) {

0 commit comments

Comments
 (0)