Skip to content

Commit e84756e

Browse files
committed
tsan, asan
1 parent d0ad3da commit e84756e

File tree

5 files changed

+27
-77
lines changed

5 files changed

+27
-77
lines changed

.bazelrc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
build:asan --strip=never
22
build:asan --copt -fsanitize=address
3-
build:asan --copt -daddress_sanitizer
43
build:asan --copt -O1
54
build:asan --copt -g
65
build:asan --copt -fno-omit-frame-pointer

.github/workflows/sanitizers-bazel.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
run: bazel build -c dbg --config=tsan //...
2222

2323
- name: Bazel test
24-
run: bazel test -c dbg --config=tsan //...
24+
run: bazel test -c dbg --config=tsan --runs_per_test 100 //...
2525

2626
- name: Upload bazel-testlogs
2727
uses: actions/upload-artifact@v4

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: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ class HighsSplitDeque {
156156

157157
void publishWork(HighsSplitDeque* localDeque) {
158158
HighsSplitDeque* sleeper = popSleeper(localDeque);
159-
160-
// TSAN_ANNOTATE_HAPPENS_BEFORE(sleeper);
161-
162159
while (sleeper) {
163160
uint32_t t = localDeque->selfStealAndGetTail();
164161
if (t == localDeque->ownerData.splitCopy) {
@@ -168,7 +165,6 @@ class HighsSplitDeque {
168165
std::memory_order_relaxed);
169166
haveJobs.fetch_add(-1, std::memory_order_release);
170167
}
171-
// TSAN_ANNOTATE_HAPPENS_AFTER(sleeper);
172168
pushSleeper(sleeper);
173169
return;
174170
} else {
@@ -185,23 +181,20 @@ class HighsSplitDeque {
185181
return;
186182
}
187183

188-
// TSAN_ANNOTATE_HAPPENS_AFTER(sleeper);
189184
sleeper = popSleeper(localDeque);
190185
}
191186
}
192187

193188
HighsTask* waitForNewTask(HighsSplitDeque* localDeque) {
194189
pushSleeper(localDeque);
195190
localDeque->stealerData.semaphore.acquire();
196-
// std::cout << " return injected task read " << &localDeque->stealerData.injectedTask << std::endl;
191+
192+
TSAN_ANNOTATE_HAPPENS_AFTER(&localDeque->stealerData.injectedTask);
193+
197194
return localDeque->stealerData.injectedTask;
198195
}
199196
};
200197

201-
// const HighsTask * getInjectedTask() {
202-
// return stealerData.injectedTask;
203-
// }
204-
205198
private:
206199
static_assert(sizeof(OwnerData) <= 64,
207200
"sizeof(OwnerData) exceeds cache line size");
@@ -472,11 +465,7 @@ class HighsSplitDeque {
472465
void injectTaskAndNotify(HighsTask* t) {
473466
stealerData.injectedTask = t;
474467

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);
468+
TSAN_ANNOTATE_HAPPENS_BEFORE(&stealerData.injectedTask);
480469

481470
stealerData.semaphore.release();
482471
}

highs/parallel/HighsTaskExecutor.h

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,12 @@
2020
#include <thread>
2121
#include <vector>
2222

23-
#include <iostream>
24-
2523
#include "parallel/HighsCacheAlign.h"
2624
#include "parallel/HighsSchedulerConstants.h"
2725
#include "parallel/HighsSplitDeque.h"
2826
#include "util/HighsInt.h"
2927
#include "util/HighsRandom.h"
3028

31-
3229
class HighsTaskExecutor {
3330
public:
3431
using cache_aligned = highs::cache_aligned;
@@ -37,11 +34,7 @@ class HighsTaskExecutor {
3734
bool isMain{false};
3835

3936
void dispose();
40-
~ExecutorHandle() {
41-
42-
// TSAN_ANNOTATE_HAPPENS_AFTER(&workerBunk)
43-
// dispose();
44-
}
37+
~ExecutorHandle() { dispose(); }
4538
};
4639

4740
private:
@@ -106,16 +99,8 @@ class HighsTaskExecutor {
10699
threadLocalWorkerDeque() = localDeque;
107100

108101
HighsTask* currentTask = ptr->workerBunk->waitForNewTask(localDeque);
109-
110-
// auto ptr = localDeque->getInjectedTask();
111-
// TSAN_ANNOTATE_HAPPENS_BEFORE(localDeque->getInjectedTask());
112-
113102
while (currentTask != nullptr) {
114103
localDeque->runStolenTask(currentTask);
115-
// TSAN_ANNOTATE_HAPPENS_BEFORE(currentTask);
116-
117-
// TSAN_ANNOTATE_HAPPENS_AFTER(currentTask);
118-
119104

120105
currentTask = ptr->random_steal_loop(localDeque);
121106
if (currentTask != nullptr) continue;
@@ -133,35 +118,18 @@ class HighsTaskExecutor {
133118

134119
workerDeques.resize(numThreads);
135120
workerBunk = cache_aligned::make_shared<HighsSplitDeque::WorkerBunk>();
136-
#ifdef __has_feature
137-
std::cout << "__has_feature is ON" << std::endl;
138-
#else
139-
std::cout << "__has_feature is OFF" << std::endl;
140-
#endif
141-
#ifdef TSAN_ENABLED
142-
std::cout << "TSAN is ON" << std::endl;
143-
#else
144-
std::cout << "TSAN is OFF" << std::endl;
145-
#endif
146-
for (int i = 0; i < numThreads; ++i) {
121+
for (int i = 0; i < numThreads; ++i)
147122
workerDeques[i] = cache_aligned::make_unique<HighsSplitDeque>(
148123
workerBunk, workerDeques.data(), i, numThreads);
149124

150-
151-
// TSAN_ANNOTATE_HAPPENS_AFTER(&workerBunk);
152-
}
153-
154125
threadLocalWorkerDeque() = workerDeques[0].get();
155126
workerThreads.reserve(numThreads - 1);
156127
referenceCount.store(numThreads);
157128

158129
for (int i = 1, numThreads = static_cast<int>(workerDeques.size());
159130
i < numThreads; ++i) {
160131
workerThreads.emplace_back(&HighsTaskExecutor::run_worker, i, this);
161-
// TSAN_ANNOTATE_HAPPENS_BEFORE(&workerThreads[i]);
162-
// std::cout <<"happens before thread " << i << ": " << &workerThreads[i] << std::endl;
163132
}
164-
165133
}
166134

167135
void stopWorkerThreads(bool blocking = false) {
@@ -172,21 +140,15 @@ std::cout << "TSAN is OFF" << std::endl;
172140
// now inject the null task as termination signal to every worker
173141
for (auto& workerDeque : workerDeques) {
174142
workerDeque->injectTaskAndNotify(nullptr);
175-
// TSAN_ANNOTATE_HAPPENS_AFTER(workerDeque->getInjectedTask());
176143
}
177144

178145
// only block if called on main thread, otherwise deadlock may occur
179146
if (blocking && executorHandle.isMain) {
180147
for (auto& workerThread : workerThreads) {
181-
// TSAN_ANNOTATE_HAPPENS_AFTER(&workerThread);
182-
// std::cout <<"happens after thread blocking and isMain" << ": " << &workerThread << std::endl;
183148
workerThread.join();
184-
// std::cout <<"happens after join" << std::endl;
185149
}
186150
} else {
187151
for (auto& workerThread : workerThreads) {
188-
// TSAN_ANNOTATE_HAPPENS_AFTER(&workerThread);
189-
// std::cout <<"happens after thread " << ": " << &workerThread << std::endl;
190152
workerThread.detach();
191153
}
192154
}

0 commit comments

Comments
 (0)