13#ifndef __STDC_FORMAT_MACROS
14#define __STDC_FORMAT_MACROS
28#include <sys/resource.h>
30#include <unordered_map>
40#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
41#define KMP_FALLTHROUGH() [[fallthrough]]
43#elif defined(__INTEL_COMPILER)
44#define KMP_FALLTHROUGH() ((void)0)
45#elif __has_cpp_attribute(clang::fallthrough)
46#define KMP_FALLTHROUGH() [[clang::fallthrough]]
47#elif __has_attribute(fallthrough) || __GNUC__ >= 7
48#define KMP_FALLTHROUGH() __attribute__((__fallthrough__))
50#define KMP_FALLTHROUGH() ((void)0)
58#if (LLVM_VERSION) >= 40
64 int report_data_leak{0};
66 std::atomic<int> all_memory{0};
68 ArcherFlags(
const char *env) {
70 std::vector<std::string> tokens;
73 std::istringstream iss(str);
75 while (std::getline(iss, token,
' '))
76 tokens.push_back(token);
78 for (std::vector<std::string>::iterator it = tokens.begin();
79 it != tokens.end(); ++it) {
80#if (LLVM_VERSION) >= 40
81 if (sscanf(it->c_str(),
"flush_shadow=%d", &flush_shadow))
84 if (sscanf(it->c_str(),
"print_max_rss=%d", &print_max_rss))
86 if (sscanf(it->c_str(),
"verbose=%d", &verbose))
88 if (sscanf(it->c_str(),
"report_data_leak=%d", &report_data_leak))
90 if (sscanf(it->c_str(),
"enable=%d", &enabled))
92 if (sscanf(it->c_str(),
"ignore_serial=%d", &ignore_serial))
94 if (sscanf(it->c_str(),
"all_memory=%d", &tmp_int)) {
98 std::cerr <<
"Illegal values for ARCHER_OPTIONS variable: " << token
107 int ignore_noninstrumented_modules;
109 TsanFlags(
const char *env) : ignore_noninstrumented_modules(0) {
111 std::vector<std::string> tokens;
112 std::string str(env);
113 auto end = str.end();
114 auto it = str.begin();
115 auto is_sep = [](
char c) {
116 return c ==
' ' || c ==
',' || c ==
':' || c ==
'\n' || c ==
'\t' ||
120 auto next_it = std::find_if(it,
end, is_sep);
121 tokens.emplace_back(it, next_it);
128 for (
const auto &token : tokens) {
131 if (sscanf(token.c_str(),
"ignore_noninstrumented_modules=%d",
132 &ignore_noninstrumented_modules))
140#if (LLVM_VERSION) >= 40
148#ifndef TsanHappensBefore
167#define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv)
170#define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv)
173#define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
176#define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
179#define TsanDeleteClock(cv)
182#define TsanNewMemory(addr, size) \
183 AnnotateNewMemory(__FILE__, __LINE__, addr, size)
184#define TsanFreeMemory(addr, size) \
185 AnnotateNewMemory(__FILE__, __LINE__, addr, size)
189#define TsanFuncEntry(pc) __tsan_func_entry(pc)
190#define TsanFuncExit() __tsan_func_exit()
199 static uint64_t
ID = 0;
200 uint64_t
ret = __sync_fetch_and_add(&
ID, 1);
209template <
typename T>
struct DataPool final {
210 static __thread DataPool<T> *ThreadDataPool;
211 std::mutex DPMutex{};
214 std::vector<T *> DataPointer{};
215 std::vector<T *> RemoteDataPointer{};
218 std::list<void *> memory;
221 std::atomic<int> remote{0};
229 int getRemote() {
return remoteReturn + remote; }
230 int getLocal() {
return localReturn; }
232 int getTotal() {
return total; }
234 return total - DataPointer.size() - RemoteDataPointer.size();
240 const std::lock_guard<std::mutex>
lock(DPMutex);
242 DataPointer.swap(RemoteDataPointer);
247 size_t elemSize =
sizeof(T);
248 size_t paddedSize = (((elemSize - 1) / 64) + 1) * 64;
251 char *datas = (
char *)malloc(ndatas * paddedSize);
252 memory.push_back(datas);
253 for (
int i = 0;
i < ndatas;
i++) {
254 DataPointer.push_back(
new (datas +
i * paddedSize) T(
this));
262 if (DataPointer.empty())
264 ret = DataPointer.back();
265 DataPointer.pop_back();
270 void returnOwnData(T *
data) {
271 DataPointer.emplace_back(
data);
278 void returnData(T *
data) {
279 const std::lock_guard<std::mutex>
lock(DPMutex);
280 RemoteDataPointer.emplace_back(
data);
290 if (
archer_flags->report_data_leak && getMissing() != 0) {
291 printf(
"ERROR: While freeing DataPool (%s) we are missing %i data "
293 __PRETTY_FUNCTION__, getMissing());
296 for (
auto i : DataPointer)
299 for (
auto i : RemoteDataPointer)
302 for (
auto i : memory)
308template <
typename T>
struct DataPoolEntry {
311 static T *New() {
return DataPool<T>::ThreadDataPool->getData(); }
314 static_cast<T *
>(
this)->Reset();
315 if (owner == DataPool<T>::ThreadDataPool)
316 owner->returnOwnData(
static_cast<T *
>(
this));
318 owner->returnData(
static_cast<T *
>(
this));
321 DataPoolEntry(DataPool<T> *dp) : owner(dp) {}
324struct DependencyData;
325typedef DataPool<DependencyData> DependencyDataPool;
327__thread DependencyDataPool *DependencyDataPool::ThreadDataPool =
nullptr;
330struct DependencyData final : DataPoolEntry<DependencyData> {
334 void *GetInPtr() {
return ∈ }
335 void *GetOutPtr() {
return &out; }
336 void *GetInoutsetPtr() {
return &inoutset; }
340 static DependencyData *New() {
return DataPoolEntry<DependencyData>::New(); }
342 DependencyData(DataPool<DependencyData> *dp)
343 : DataPoolEntry<DependencyData>(dp) {}
346struct TaskDependency {
350 ompt_dependence_type_t
type;
351 TaskDependency(DependencyData *depData, ompt_dependence_type_t type)
352 : inPtr(depData->GetInPtr()), outPtr(depData->GetOutPtr()),
353 inoutsetPtr(depData->GetInoutsetPtr()),
type(
type) {}
354 void AnnotateBegin() {
355 if (type == ompt_dependence_type_out ||
356 type == ompt_dependence_type_inout ||
357 type == ompt_dependence_type_mutexinoutset) {
361 }
else if (type == ompt_dependence_type_in) {
364 }
else if (type == ompt_dependence_type_inoutset) {
370 if (type == ompt_dependence_type_out ||
371 type == ompt_dependence_type_inout ||
372 type == ompt_dependence_type_mutexinoutset) {
374 }
else if (type == ompt_dependence_type_in) {
376 }
else if (type == ompt_dependence_type_inoutset) {
383typedef DataPool<ParallelData> ParallelDataPool;
385__thread ParallelDataPool *ParallelDataPool::ThreadDataPool =
nullptr;
388struct ParallelData final : DataPoolEntry<ParallelData> {
397 void *GetParallelPtr() {
return &(Barrier[1]); }
399 void *GetBarrierPtr(
unsigned Index) {
return &(Barrier[
Index]); }
401 ParallelData *Init(
const void *codeptr) {
408 static ParallelData *New(
const void *codeptr) {
409 return DataPoolEntry<ParallelData>::New()->Init(codeptr);
412 ParallelData(DataPool<ParallelData> *dp) : DataPoolEntry<ParallelData>(dp) {}
415static inline ParallelData *ToParallelData(ompt_data_t *parallel_data) {
416 return reinterpret_cast<ParallelData *
>(parallel_data->ptr);
420typedef DataPool<Taskgroup> TaskgroupPool;
421template <> __thread TaskgroupPool *TaskgroupPool::ThreadDataPool =
nullptr;
424struct Taskgroup final : DataPoolEntry<Taskgroup> {
431 void *GetPtr() {
return &Ptr; }
433 Taskgroup *Init(Taskgroup *
parent) {
440 static Taskgroup *New(Taskgroup *Parent) {
441 return DataPoolEntry<Taskgroup>::New()->Init(Parent);
444 Taskgroup(DataPool<Taskgroup> *dp) : DataPoolEntry<Taskgroup>(dp) {}
447enum ArcherTaskFlag { ArcherTaskFulfilled = 0x00010000 };
450typedef DataPool<TaskData> TaskDataPool;
451template <> __thread TaskDataPool *TaskDataPool::ThreadDataPool =
nullptr;
454struct TaskData final : DataPoolEntry<TaskData> {
466 char BarrierIndex{0};
469 bool InBarrier{
false};
478 std::atomic_int RefCount{1};
481 TaskData *Parent{
nullptr};
484 ParallelData *Team{
nullptr};
488 Taskgroup *TaskGroup{
nullptr};
491 TaskDependency *Dependencies{
nullptr};
494 unsigned DependencyCount{0};
500 std::unordered_map<void *, DependencyData *> *DependencyMap{
nullptr};
506 bool isIncluded() {
return TaskType & ompt_task_undeferred; }
507 bool isUntied() {
return TaskType & ompt_task_untied; }
508 bool isFinal() {
return TaskType & ompt_task_final; }
509 bool isMergable() {
return TaskType & ompt_task_mergeable; }
510 bool isMerged() {
return TaskType & ompt_task_merged; }
512 bool isExplicit() {
return TaskType & ompt_task_explicit; }
513 bool isImplicit() {
return TaskType & ompt_task_implicit; }
514 bool isInitial() {
return TaskType & ompt_task_initial; }
515 bool isTarget() {
return TaskType & ompt_task_target; }
517 bool isFulfilled() {
return TaskType & ArcherTaskFulfilled; }
518 void setFulfilled() { TaskType |= ArcherTaskFulfilled; }
520 void setAllMemoryDep() { AllMemory[0] = 1; }
521 bool hasAllMemoryDep() {
return AllMemory[0]; }
523 void *GetTaskPtr() {
return &Task; }
525 void *GetTaskwaitPtr() {
return &Taskwait; }
527 void *GetLastAllMemoryPtr() {
return AllMemory; }
528 void *GetNextAllMemoryPtr() {
return AllMemory + 1; }
530 TaskData *Init(TaskData *
parent,
int taskType) {
534 BarrierIndex = Parent->BarrierIndex;
535 if (Parent !=
nullptr) {
539 TaskGroup = Parent->TaskGroup;
544 TaskData *Init(ParallelData *team,
int taskType) {
561 for (
auto i : *DependencyMap)
563 delete DependencyMap;
565 DependencyMap =
nullptr;
568 Dependencies =
nullptr;
575 static TaskData *New(TaskData *
parent,
int taskType) {
576 return DataPoolEntry<TaskData>::New()->Init(
parent, taskType);
579 static TaskData *New(ParallelData *team,
int taskType) {
580 return DataPoolEntry<TaskData>::New()->Init(team, taskType);
583 TaskData(DataPool<TaskData> *dp) : DataPoolEntry<TaskData>(dp) {}
589 return reinterpret_cast<TaskData *
>(task_data->ptr);
594static std::unordered_map<ompt_wait_id_t, std::mutex>
Locks;
598 ompt_data_t *thread_data) {
599 ParallelDataPool::ThreadDataPool =
new ParallelDataPool;
601 sizeof(ParallelDataPool::ThreadDataPool));
602 TaskgroupPool::ThreadDataPool =
new TaskgroupPool;
604 sizeof(TaskgroupPool::ThreadDataPool));
605 TaskDataPool::ThreadDataPool =
new TaskDataPool;
607 sizeof(TaskDataPool::ThreadDataPool));
608 DependencyDataPool::ThreadDataPool =
new DependencyDataPool;
610 sizeof(DependencyDataPool::ThreadDataPool));
616 delete ParallelDataPool::ThreadDataPool;
617 delete TaskgroupPool::ThreadDataPool;
618 delete TaskDataPool::ThreadDataPool;
619 delete DependencyDataPool::ThreadDataPool;
626 const ompt_frame_t *parent_task_frame,
627 ompt_data_t *parallel_data,
628 uint32_t requested_team_size,
int flag,
629 const void *codeptr_ra) {
630 ParallelData *Data = ParallelData::New(codeptr_ra);
631 parallel_data->ptr = Data;
639 ompt_data_t *task_data,
int flag,
640 const void *codeptr_ra) {
643 ParallelData *Data = ToParallelData(parallel_data);
649#if (LLVM_VERSION >= 40)
650 if (&__archer_get_omp_status) {
651 if (__archer_get_omp_status() == 0 &&
archer_flags->flush_shadow)
652 __tsan_flush_memory();
658 ompt_data_t *parallel_data,
659 ompt_data_t *task_data,
660 unsigned int team_size,
661 unsigned int thread_num,
int type) {
663 case ompt_scope_begin:
664 if (
type & ompt_task_initial) {
665 parallel_data->ptr = ParallelData::New(
nullptr);
667 task_data->ptr = TaskData::New(ToParallelData(parallel_data),
type);
671 case ompt_scope_end: {
674 assert(Data->freed == 0 &&
"Implicit task end should only be called once!");
677 assert(Data->RefCount == 1 &&
678 "All tasks should have finished at the implicit barrier!");
679 if (
type & ompt_task_initial) {
680 Data->Team->Delete();
686 case ompt_scope_beginend:
694 ompt_scope_endpoint_t endpoint,
695 ompt_data_t *parallel_data,
696 ompt_data_t *task_data,
697 const void *codeptr_ra) {
700 case ompt_scope_begin:
701 case ompt_scope_beginend:
704 case ompt_sync_region_barrier_implementation:
705 case ompt_sync_region_barrier_implicit:
706 case ompt_sync_region_barrier_explicit:
707 case ompt_sync_region_barrier_implicit_parallel:
708 case ompt_sync_region_barrier_implicit_workshare:
709 case ompt_sync_region_barrier_teams:
710 case ompt_sync_region_barrier: {
711 char BarrierIndex = Data->BarrierIndex;
720 Data->InBarrier =
true;
727 case ompt_sync_region_taskwait:
730 case ompt_sync_region_taskgroup:
731 Data->TaskGroup = Taskgroup::New(Data->TaskGroup);
734 case ompt_sync_region_reduction:
738 if (endpoint == ompt_scope_begin)
744 case ompt_sync_region_barrier_implementation:
745 case ompt_sync_region_barrier_implicit:
746 case ompt_sync_region_barrier_explicit:
747 case ompt_sync_region_barrier_implicit_parallel:
748 case ompt_sync_region_barrier_implicit_workshare:
749 case ompt_sync_region_barrier_teams:
750 case ompt_sync_region_barrier: {
753 Data->InBarrier =
false;
757 char BarrierIndex = Data->BarrierIndex;
767 Data->BarrierIndex = (BarrierIndex + 1) % 2;
771 case ompt_sync_region_taskwait: {
772 if (Data->execution > 1)
777 case ompt_sync_region_taskgroup: {
778 assert(Data->TaskGroup !=
nullptr &&
779 "Should have at least one taskgroup!");
785 Taskgroup *Parent = Data->TaskGroup->Parent;
786 Data->TaskGroup->Delete();
787 Data->TaskGroup = Parent;
791 case ompt_sync_region_reduction:
801 ompt_scope_endpoint_t endpoint,
802 ompt_data_t *parallel_data,
803 ompt_data_t *task_data,
804 const void *codeptr_ra) {
806 case ompt_scope_begin:
808 case ompt_sync_region_reduction:
817 case ompt_sync_region_reduction:
824 case ompt_scope_beginend:
835 ompt_data_t *parent_task_data,
836 const ompt_frame_t *parent_frame,
837 ompt_data_t *new_task_data,
838 int type,
int has_dependences,
839 const void *codeptr_ra)
842 assert(new_task_data->ptr == NULL &&
843 "Task data should be initialized to NULL");
844 if (
type & ompt_task_initial) {
845 ompt_data_t *parallel_data;
848 ParallelData *PData = ParallelData::New(
nullptr);
849 parallel_data->ptr = PData;
851 Data = TaskData::New(PData,
type);
852 new_task_data->ptr = Data;
853 }
else if (
type & ompt_task_undeferred) {
855 new_task_data->ptr = Data;
856 }
else if (
type & ompt_task_explicit ||
type & ompt_task_target) {
858 new_task_data->ptr = Data;
869 while (
task !=
nullptr && --
task->RefCount == 0) {
870 TaskData *Parent =
task->Parent;
882 if (
task->hasAllMemoryDep()) {
885 }
else if (
task->DependencyCount)
888 for (
unsigned i = 0;
i <
task->DependencyCount;
i++) {
889 task->Dependencies[
i].AnnotateEnd();
895 if (
task->hasAllMemoryDep())
897 else if (
task->DependencyCount)
900 for (
unsigned i = 0;
i <
task->DependencyCount;
i++) {
901 task->Dependencies[
i].AnnotateBegin();
909 if (FromTask->isFulfilled())
913 if (!FromTask->isIncluded()) {
916 ParallelData *PData = FromTask->Team;
922 if (FromTask->TaskGroup !=
nullptr) {
942 if (FromTask && FromTask->InBarrier) {
947 if (ToTask && ToTask->InBarrier) {
969 if (ToTask->execution == 0) {
979 ompt_task_status_t prior_task_status,
980 ompt_data_t *second_task_data) {
1004 TaskData *FromTask =
ToTaskData(first_task_data);
1005 TaskData *ToTask =
ToTaskData(second_task_data);
1007 switch (prior_task_status) {
1008 case ompt_task_early_fulfill:
1010 FromTask->setFulfilled();
1012 case ompt_task_late_fulfill:
1017 case ompt_taskwait_complete:
1021 case ompt_task_complete:
1027 case ompt_task_cancel:
1034 case ompt_task_detach:
1040 case ompt_task_yield:
1045 case ompt_task_switch:
1054 const ompt_dependence_t *deps,
int ndeps) {
1058 if (!Data->Parent) {
1062 if (!Data->Parent->DependencyMap)
1063 Data->Parent->DependencyMap =
1064 new std::unordered_map<void *, DependencyData *>();
1065 Data->Dependencies =
1066 (TaskDependency *)malloc(
sizeof(TaskDependency) * ndeps);
1067 Data->DependencyCount = ndeps;
1068 for (
int i = 0,
d = 0;
i < ndeps;
i++,
d++) {
1069 if (deps[
i].dependence_type == ompt_dependence_type_out_all_memory ||
1070 deps[
i].dependence_type == ompt_dependence_type_inout_all_memory) {
1071 Data->setAllMemoryDep();
1072 Data->DependencyCount--;
1074 printf(
"The application uses omp_all_memory, but Archer was\n"
1075 "started to not consider omp_all_memory. This can lead\n"
1076 "to false data race alerts.\n"
1077 "Include all_memory=1 in ARCHER_OPTIONS to consider\n"
1078 "omp_all_memory from the beginning.\n");
1084 auto ret = Data->Parent->DependencyMap->insert(
1085 std::make_pair(deps[
i].variable.ptr,
nullptr));
1087 ret.first->second = DependencyData::New();
1089 new ((
void *)(Data->Dependencies +
d))
1090 TaskDependency(
ret.first->second, deps[
i].dependence_type);
1100 const void *codeptr_ra) {
1106 std::mutex &Lock =
Locks[wait_id];
1114 const void *codeptr_ra) {
1116 std::mutex &Lock =
Locks[wait_id];
1124#define SET_OPTIONAL_CALLBACK_T(event, type, result, level) \
1126 ompt_callback_##type##_t tsan_##event = &ompt_tsan_##event; \
1127 result = ompt_set_callback(ompt_callback_##event, \
1128 (ompt_callback_t)tsan_##event); \
1129 if (result < level) \
1130 printf("Registered callback '" #event "' is not supported at " #level \
1135#define SET_CALLBACK_T(event, type) \
1138 SET_OPTIONAL_CALLBACK_T(event, type, res, ompt_set_always); \
1141#define SET_CALLBACK(event) SET_CALLBACK_T(event, event)
1143#define findTsanFunction(f, fSig) \
1145 if (NULL == (f = fSig dlsym(RTLD_DEFAULT, #f))) \
1146 printf("Unable to find TSan function " #f ".\n"); \
1149#define findTsanFunctionSilent(f, fSig) f = fSig dlsym(RTLD_DEFAULT, #f)
1152 ompt_data_t *tool_data) {
1153 const char *options = getenv(
"TSAN_OPTIONS");
1154 TsanFlags tsan_flags(options);
1157 (ompt_set_callback_t)lookup(
"ompt_set_callback");
1159 std::cerr <<
"Could not set callback, exiting..." << std::endl;
1163 (ompt_get_parallel_info_t)lookup(
"ompt_get_parallel_info");
1167 fprintf(stderr,
"Could not get inquiry function 'ompt_get_parallel_info', "
1173 (
void (*)(
const char *,
int,
const volatile void *)));
1175 (
void (*)(
const char *,
int,
const volatile void *)));
1180 (
void (*)(
const char *,
int,
const volatile void *,
size_t)));
1200 if (!tsan_flags.ignore_noninstrumented_modules)
1202 "Warning: please export "
1203 "TSAN_OPTIONS='ignore_noninstrumented_modules=1' "
1204 "to avoid false positive reports from the OpenMP runtime!\n");
1216 getrusage(RUSAGE_SELF, &
end);
1217 printf(
"MAX RSS[KBytes] during execution: %ld\n",
end.ru_maxrss);
1226 const char *options = getenv(
"ARCHER_OPTIONS");
1230 std::cout <<
"Archer disabled, stopping operation" << std::endl;
1251 std::cout <<
"Archer detected OpenMP application without TSan; "
1252 "stopping operation"
1259 std::cout <<
"Archer detected OpenMP application with TSan, supplying "
1260 "OpenMP synchronization semantics"
static ompt_set_callback_t ompt_set_callback
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void * data
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp end
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id parent
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
static kmp_bootstrap_lock_t lock
struct ompt_start_tool_result_t ompt_start_tool_result_t
__attribute__((noinline))
unsigned * Index(unsigned *p, unsigned i, unsigned j, unsigned bound2)
static ompt_start_tool_result_t * ompt_start_tool_result
static void(* AnnotateIgnoreWritesEnd)(const char *, int)
#define TsanHappensBefore(cv)
#define TsanFuncEntry(pc)
static void ompt_tsan_parallel_begin(ompt_data_t *parent_task_data, const ompt_frame_t *parent_task_frame, ompt_data_t *parallel_data, uint32_t requested_team_size, int flag, const void *codeptr_ra)
OMPT event callbacks for handling parallel regions.
static TaskData * ToTaskData(ompt_data_t *task_data)
#define findTsanFunctionSilent(f, fSig)
static uint64_t my_next_id()
static void ompt_tsan_sync_region(ompt_sync_region_t kind, ompt_scope_endpoint_t endpoint, ompt_data_t *parallel_data, ompt_data_t *task_data, const void *codeptr_ra)
static void freeTask(TaskData *task)
static void switchTasks(TaskData *FromTask, TaskData *ToTask)
#define TsanHappensAfter(cv)
static void(* __tsan_func_exit)(void)
static void endTask(TaskData *FromTask)
static ArcherFlags * archer_flags
static void ompt_tsan_dependences(ompt_data_t *task_data, const ompt_dependence_t *deps, int ndeps)
static void ompt_tsan_thread_end(ompt_data_t *thread_data)
#define SET_CALLBACK_T(event, type)
static void(* AnnotateHappensAfter)(const char *, int, const volatile void *)
static void ompt_tsan_task_create(ompt_data_t *parent_task_data, const ompt_frame_t *parent_frame, ompt_data_t *new_task_data, int type, int has_dependences, const void *codeptr_ra)
OMPT event callbacks for handling tasks.
static int(* RunningOnValgrind)(void)
#define TsanIgnoreWritesEnd()
static std::unordered_map< ompt_wait_id_t, std::mutex > Locks
Store a mutex for each wait_id to resolve race condition with callbacks.
static void ompt_tsan_task_schedule(ompt_data_t *first_task_data, ompt_task_status_t prior_task_status, ompt_data_t *second_task_data)
static void acquireDependencies(TaskData *task)
#define SET_CALLBACK(event)
static void completeTask(TaskData *FromTask)
static void ompt_tsan_mutex_acquired(ompt_mutex_t kind, ompt_wait_id_t wait_id, const void *codeptr_ra)
OMPT event callbacks for handling locking.
static void suspendTask(TaskData *FromTask)
static std::mutex LocksMutex
#define SET_OPTIONAL_CALLBACK_T(event, type, result, level)
static void ompt_tsan_parallel_end(ompt_data_t *parallel_data, ompt_data_t *task_data, int flag, const void *codeptr_ra)
static void(* AnnotateHappensBefore)(const char *, int, const volatile void *)
static void ompt_tsan_mutex_released(ompt_mutex_t kind, ompt_wait_id_t wait_id, const void *codeptr_ra)
static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num, ompt_data_t *tool_data)
static void(* __tsan_func_entry)(const void *)
#define TsanNewMemory(addr, size)
#define KMP_FALLTHROUGH()
static void ompt_tsan_finalize(ompt_data_t *tool_data)
static int hasReductionCallback
static void ompt_tsan_implicit_task(ompt_scope_endpoint_t endpoint, ompt_data_t *parallel_data, ompt_data_t *task_data, unsigned int team_size, unsigned int thread_num, int type)
#define findTsanFunction(f, fSig)
static void ompt_tsan_reduction(ompt_sync_region_t kind, ompt_scope_endpoint_t endpoint, ompt_data_t *parallel_data, ompt_data_t *task_data, const void *codeptr_ra)
#define TsanIgnoreWritesBegin()
static void ompt_tsan_thread_begin(ompt_thread_t thread_type, ompt_data_t *thread_data)
static void(* AnnotateNewMemory)(const char *, int, const volatile void *, size_t)
static void(* AnnotateIgnoreWritesBegin)(const char *, int)
static void startTask(TaskData *ToTask)
static ompt_get_parallel_info_t ompt_get_parallel_info
Required OMPT inquiry functions.
static ompt_get_thread_data_t ompt_get_thread_data
static void releaseDependencies(TaskData *task)