13#ifndef __STDC_FORMAT_MACROS
14#define __STDC_FORMAT_MACROS
29#include <sys/resource.h>
31#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
152#define DECLARE_TSAN_FUNCTION(name, ...) \
153 static void (*name)(__VA_ARGS__) = __ompt_tsan_func<__VA_ARGS__>;
160 const volatile void *)
162 const volatile
void *)
166 const volatile
void *,
size_t)
171static
int (*RunningOnValgrind)(
void);
177#define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv)
180#define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv)
183#define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
186#define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
189#define TsanDeleteClock(cv)
192#define TsanNewMemory(addr, size) \
193 AnnotateNewMemory(__FILE__, __LINE__, addr, size)
194#define TsanFreeMemory(addr, size) \
195 AnnotateNewMemory(__FILE__, __LINE__, addr, size)
199#define TsanFuncEntry(pc) __tsan_func_entry(pc)
200#define TsanFuncExit() __tsan_func_exit()
209 static uint64_t
ID = 0;
210 uint64_t
ret = __sync_fetch_and_add(&
ID, 1);
219template <
typename T>
struct DataPool final {
220 static __thread DataPool<T> *ThreadDataPool;
221 std::mutex DPMutex{};
224 std::vector<T *> DataPointer{};
225 std::vector<T *> RemoteDataPointer{};
228 std::list<void *> memory;
231 std::atomic<int> remote{0};
239 int getRemote() {
return remoteReturn + remote; }
240 int getLocal() {
return localReturn; }
242 int getTotal() {
return total; }
244 return total - DataPointer.size() - RemoteDataPointer.size();
250 const std::lock_guard<std::mutex>
lock(DPMutex);
252 DataPointer.swap(RemoteDataPointer);
257 size_t elemSize =
sizeof(T);
258 size_t paddedSize = (((elemSize - 1) / 64) + 1) * 64;
261 char *datas = (
char *)malloc(ndatas * paddedSize);
262 memory.push_back(datas);
263 for (
int i = 0;
i < ndatas;
i++) {
264 DataPointer.push_back(
new (datas +
i * paddedSize) T(
this));
272 if (DataPointer.empty())
274 ret = DataPointer.back();
275 DataPointer.pop_back();
280 void returnOwnData(T *
data) {
281 DataPointer.emplace_back(
data);
288 void returnData(T *
data) {
289 const std::lock_guard<std::mutex>
lock(DPMutex);
290 RemoteDataPointer.emplace_back(
data);
300 if (
archer_flags->report_data_leak && getMissing() != 0) {
301 printf(
"ERROR: While freeing DataPool (%s) we are missing %i data "
303 __PRETTY_FUNCTION__, getMissing());
306 for (
auto i : DataPointer)
309 for (
auto i : RemoteDataPointer)
312 for (
auto i : memory)
318template <
typename T>
struct DataPoolEntry {
321 static T *New() {
return DataPool<T>::ThreadDataPool->getData(); }
324 static_cast<T *
>(
this)->Reset();
325 if (owner == DataPool<T>::ThreadDataPool)
326 owner->returnOwnData(
static_cast<T *
>(
this));
328 owner->returnData(
static_cast<T *
>(
this));
331 DataPoolEntry(DataPool<T> *dp) : owner(dp) {}
334struct DependencyData;
335typedef DataPool<DependencyData> DependencyDataPool;
337__thread DependencyDataPool *DependencyDataPool::ThreadDataPool =
nullptr;
340struct DependencyData final : DataPoolEntry<DependencyData> {
344 void *GetInPtr() {
return ∈ }
345 void *GetOutPtr() {
return &out; }
346 void *GetInoutsetPtr() {
return &inoutset; }
350 static DependencyData *New() {
return DataPoolEntry<DependencyData>::New(); }
352 DependencyData(DataPool<DependencyData> *dp)
353 : DataPoolEntry<DependencyData>(dp) {}
356struct TaskDependency {
360 ompt_dependence_type_t
type;
361 TaskDependency(DependencyData *depData, ompt_dependence_type_t type)
362 : inPtr(depData->GetInPtr()), outPtr(depData->GetOutPtr()),
363 inoutsetPtr(depData->GetInoutsetPtr()),
type(
type) {}
364 void AnnotateBegin() {
365 if (type == ompt_dependence_type_out ||
366 type == ompt_dependence_type_inout ||
367 type == ompt_dependence_type_mutexinoutset) {
371 }
else if (type == ompt_dependence_type_in) {
374 }
else if (type == ompt_dependence_type_inoutset) {
380 if (type == ompt_dependence_type_out ||
381 type == ompt_dependence_type_inout ||
382 type == ompt_dependence_type_mutexinoutset) {
384 }
else if (type == ompt_dependence_type_in) {
386 }
else if (type == ompt_dependence_type_inoutset) {
393typedef DataPool<ParallelData> ParallelDataPool;
395__thread ParallelDataPool *ParallelDataPool::ThreadDataPool =
nullptr;
398struct ParallelData final : DataPoolEntry<ParallelData> {
407 void *GetParallelPtr() {
return &(Barrier[1]); }
409 void *GetBarrierPtr(
unsigned Index) {
return &(Barrier[
Index]); }
411 ParallelData *Init(
const void *codeptr) {
418 static ParallelData *New(
const void *codeptr) {
419 return DataPoolEntry<ParallelData>::New()->Init(codeptr);
422 ParallelData(DataPool<ParallelData> *dp) : DataPoolEntry<ParallelData>(dp) {}
425static inline ParallelData *ToParallelData(ompt_data_t *parallel_data) {
426 return reinterpret_cast<ParallelData *
>(parallel_data->ptr);
430typedef DataPool<Taskgroup> TaskgroupPool;
431template <> __thread TaskgroupPool *TaskgroupPool::ThreadDataPool =
nullptr;
434struct Taskgroup final : DataPoolEntry<Taskgroup> {
441 void *GetPtr() {
return &Ptr; }
443 Taskgroup *Init(Taskgroup *
parent) {
450 static Taskgroup *New(Taskgroup *Parent) {
451 return DataPoolEntry<Taskgroup>::New()->Init(Parent);
454 Taskgroup(DataPool<Taskgroup> *dp) : DataPoolEntry<Taskgroup>(dp) {}
457enum ArcherTaskFlag { ArcherTaskFulfilled = 0x00010000 };
460typedef DataPool<TaskData> TaskDataPool;
461template <> __thread TaskDataPool *TaskDataPool::ThreadDataPool =
nullptr;
464struct TaskData final : DataPoolEntry<TaskData> {
476 char BarrierIndex{0};
479 bool InBarrier{
false};
488 std::atomic_int RefCount{1};
491 TaskData *Parent{
nullptr};
494 ParallelData *Team{
nullptr};
498 Taskgroup *TaskGroup{
nullptr};
501 TaskDependency *Dependencies{
nullptr};
504 unsigned DependencyCount{0};
510 std::unordered_map<void *, DependencyData *> *DependencyMap{
nullptr};
516 bool isIncluded() {
return TaskType & ompt_task_undeferred; }
517 bool isUntied() {
return TaskType & ompt_task_untied; }
518 bool isFinal() {
return TaskType & ompt_task_final; }
519 bool isMergable() {
return TaskType & ompt_task_mergeable; }
520 bool isMerged() {
return TaskType & ompt_task_merged; }
522 bool isExplicit() {
return TaskType & ompt_task_explicit; }
523 bool isImplicit() {
return TaskType & ompt_task_implicit; }
524 bool isInitial() {
return TaskType & ompt_task_initial; }
525 bool isTarget() {
return TaskType & ompt_task_target; }
527 bool isFulfilled() {
return TaskType & ArcherTaskFulfilled; }
528 void setFulfilled() { TaskType |= ArcherTaskFulfilled; }
530 void setAllMemoryDep() { AllMemory[0] = 1; }
531 bool hasAllMemoryDep() {
return AllMemory[0]; }
533 void *GetTaskPtr() {
return &Task; }
535 void *GetTaskwaitPtr() {
return &Taskwait; }
537 void *GetLastAllMemoryPtr() {
return AllMemory; }
538 void *GetNextAllMemoryPtr() {
return AllMemory + 1; }
540 TaskData *Init(TaskData *
parent,
int taskType) {
544 BarrierIndex = Parent->BarrierIndex;
545 if (Parent !=
nullptr) {
549 TaskGroup = Parent->TaskGroup;
554 TaskData *Init(ParallelData *team,
int taskType) {
571 for (
auto i : *DependencyMap)
573 delete DependencyMap;
575 DependencyMap =
nullptr;
578 Dependencies =
nullptr;
585 static TaskData *New(TaskData *
parent,
int taskType) {
586 return DataPoolEntry<TaskData>::New()->Init(
parent, taskType);
589 static TaskData *New(ParallelData *team,
int taskType) {
590 return DataPoolEntry<TaskData>::New()->Init(team, taskType);
593 TaskData(DataPool<TaskData> *dp) : DataPoolEntry<TaskData>(dp) {}
599 return reinterpret_cast<TaskData *
>(task_data->ptr);
604static std::unordered_map<ompt_wait_id_t, std::mutex>
Locks;
608 ompt_data_t *thread_data) {
609 ParallelDataPool::ThreadDataPool =
new ParallelDataPool;
611 sizeof(ParallelDataPool::ThreadDataPool));
612 TaskgroupPool::ThreadDataPool =
new TaskgroupPool;
614 sizeof(TaskgroupPool::ThreadDataPool));
615 TaskDataPool::ThreadDataPool =
new TaskDataPool;
617 sizeof(TaskDataPool::ThreadDataPool));
618 DependencyDataPool::ThreadDataPool =
new DependencyDataPool;
620 sizeof(DependencyDataPool::ThreadDataPool));
626 delete ParallelDataPool::ThreadDataPool;
627 delete TaskgroupPool::ThreadDataPool;
628 delete TaskDataPool::ThreadDataPool;
629 delete DependencyDataPool::ThreadDataPool;
636 const ompt_frame_t *parent_task_frame,
637 ompt_data_t *parallel_data,
638 uint32_t requested_team_size,
int flag,
639 const void *codeptr_ra) {
640 ParallelData *Data = ParallelData::New(codeptr_ra);
641 parallel_data->ptr = Data;
649 ompt_data_t *task_data,
int flag,
650 const void *codeptr_ra) {
653 ParallelData *Data = ToParallelData(parallel_data);
659#if (LLVM_VERSION >= 40)
660 if (&__archer_get_omp_status) {
661 if (__archer_get_omp_status() == 0 &&
archer_flags->flush_shadow)
662 __tsan_flush_memory();
668 ompt_data_t *parallel_data,
669 ompt_data_t *task_data,
670 unsigned int team_size,
671 unsigned int thread_num,
int type) {
673 case ompt_scope_begin:
674 if (
type & ompt_task_initial) {
675 parallel_data->ptr = ParallelData::New(
nullptr);
677 task_data->ptr = TaskData::New(ToParallelData(parallel_data),
type);
681 case ompt_scope_end: {
684 assert(Data->freed == 0 &&
"Implicit task end should only be called once!");
687 assert(Data->RefCount == 1 &&
688 "All tasks should have finished at the implicit barrier!");
689 if (
type & ompt_task_initial) {
690 Data->Team->Delete();
696 case ompt_scope_beginend:
704 ompt_scope_endpoint_t endpoint,
705 ompt_data_t *parallel_data,
706 ompt_data_t *task_data,
707 const void *codeptr_ra) {
710 case ompt_scope_begin:
711 case ompt_scope_beginend:
714 case ompt_sync_region_barrier_implementation:
715 case ompt_sync_region_barrier_implicit:
716 case ompt_sync_region_barrier_explicit:
717 case ompt_sync_region_barrier_implicit_parallel:
718 case ompt_sync_region_barrier_implicit_workshare:
719 case ompt_sync_region_barrier_teams:
720 case ompt_sync_region_barrier: {
721 char BarrierIndex = Data->BarrierIndex;
730 Data->InBarrier =
true;
737 case ompt_sync_region_taskwait:
740 case ompt_sync_region_taskgroup:
741 Data->TaskGroup = Taskgroup::New(Data->TaskGroup);
744 case ompt_sync_region_reduction:
748 if (endpoint == ompt_scope_begin)
754 case ompt_sync_region_barrier_implementation:
755 case ompt_sync_region_barrier_implicit:
756 case ompt_sync_region_barrier_explicit:
757 case ompt_sync_region_barrier_implicit_parallel:
758 case ompt_sync_region_barrier_implicit_workshare:
759 case ompt_sync_region_barrier_teams:
760 case ompt_sync_region_barrier: {
763 Data->InBarrier =
false;
767 char BarrierIndex = Data->BarrierIndex;
777 Data->BarrierIndex = (BarrierIndex + 1) % 2;
781 case ompt_sync_region_taskwait: {
782 if (Data->execution > 1)
787 case ompt_sync_region_taskgroup: {
788 assert(Data->TaskGroup !=
nullptr &&
789 "Should have at least one taskgroup!");
795 Taskgroup *Parent = Data->TaskGroup->Parent;
796 Data->TaskGroup->Delete();
797 Data->TaskGroup = Parent;
801 case ompt_sync_region_reduction:
811 ompt_scope_endpoint_t endpoint,
812 ompt_data_t *parallel_data,
813 ompt_data_t *task_data,
814 const void *codeptr_ra) {
816 case ompt_scope_begin:
818 case ompt_sync_region_reduction:
827 case ompt_sync_region_reduction:
834 case ompt_scope_beginend:
845 ompt_data_t *parent_task_data,
846 const ompt_frame_t *parent_frame,
847 ompt_data_t *new_task_data,
848 int type,
int has_dependences,
849 const void *codeptr_ra)
852 assert(new_task_data->ptr == NULL &&
853 "Task data should be initialized to NULL");
854 if (
type & ompt_task_initial) {
855 ompt_data_t *parallel_data;
858 ParallelData *PData = ParallelData::New(
nullptr);
859 parallel_data->ptr = PData;
861 Data = TaskData::New(PData,
type);
862 new_task_data->ptr = Data;
863 }
else if (
type & ompt_task_undeferred) {
865 new_task_data->ptr = Data;
866 }
else if (
type & ompt_task_explicit ||
type & ompt_task_target) {
868 new_task_data->ptr = Data;
879 while (
task !=
nullptr && --
task->RefCount == 0) {
880 TaskData *Parent =
task->Parent;
892 if (
task->hasAllMemoryDep()) {
895 }
else if (
task->DependencyCount)
898 for (
unsigned i = 0;
i <
task->DependencyCount;
i++) {
899 task->Dependencies[
i].AnnotateEnd();
905 if (
task->hasAllMemoryDep())
907 else if (
task->DependencyCount)
910 for (
unsigned i = 0;
i <
task->DependencyCount;
i++) {
911 task->Dependencies[
i].AnnotateBegin();
919 if (FromTask->isFulfilled())
923 if (!FromTask->isIncluded()) {
926 ParallelData *PData = FromTask->Team;
932 if (FromTask->TaskGroup !=
nullptr) {
952 if (FromTask && FromTask->InBarrier) {
957 if (ToTask && ToTask->InBarrier) {
979 if (ToTask->execution == 0) {
989 ompt_task_status_t prior_task_status,
990 ompt_data_t *second_task_data) {
1014 TaskData *FromTask =
ToTaskData(first_task_data);
1015 TaskData *ToTask =
ToTaskData(second_task_data);
1017 switch (prior_task_status) {
1018 case ompt_task_early_fulfill:
1020 FromTask->setFulfilled();
1022 case ompt_task_late_fulfill:
1027 case ompt_taskwait_complete:
1031 case ompt_task_complete:
1037 case ompt_task_cancel:
1044 case ompt_task_detach:
1050 case ompt_task_yield:
1055 case ompt_task_switch:
1064 const ompt_dependence_t *deps,
int ndeps) {
1068 if (!Data->Parent) {
1072 if (!Data->Parent->DependencyMap)
1073 Data->Parent->DependencyMap =
1074 new std::unordered_map<void *, DependencyData *>();
1075 Data->Dependencies =
1076 (TaskDependency *)malloc(
sizeof(TaskDependency) * ndeps);
1077 Data->DependencyCount = ndeps;
1078 for (
int i = 0,
d = 0;
i < ndeps;
i++,
d++) {
1079 if (deps[
i].dependence_type == ompt_dependence_type_out_all_memory ||
1080 deps[
i].dependence_type == ompt_dependence_type_inout_all_memory) {
1081 Data->setAllMemoryDep();
1082 Data->DependencyCount--;
1084 printf(
"The application uses omp_all_memory, but Archer was\n"
1085 "started to not consider omp_all_memory. This can lead\n"
1086 "to false data race alerts.\n"
1087 "Include all_memory=1 in ARCHER_OPTIONS to consider\n"
1088 "omp_all_memory from the beginning.\n");
1094 auto ret = Data->Parent->DependencyMap->insert(
1095 std::make_pair(deps[
i].variable.ptr,
nullptr));
1097 ret.first->second = DependencyData::New();
1099 new ((
void *)(Data->Dependencies +
d))
1100 TaskDependency(
ret.first->second, deps[
i].dependence_type);
1110 const void *codeptr_ra) {
1116 std::mutex &Lock =
Locks[wait_id];
1124 const void *codeptr_ra) {
1126 std::mutex &Lock =
Locks[wait_id];
1134#define SET_OPTIONAL_CALLBACK_T(event, type, result, level) \
1136 ompt_callback_##type##_t tsan_##event = &ompt_tsan_##event; \
1137 result = ompt_set_callback(ompt_callback_##event, \
1138 (ompt_callback_t)tsan_##event); \
1139 if (result < level) \
1140 printf("Registered callback '" #event "' is not supported at " #level \
1145#define SET_CALLBACK_T(event, type) \
1148 SET_OPTIONAL_CALLBACK_T(event, type, res, ompt_set_always); \
1151#define SET_CALLBACK(event) SET_CALLBACK_T(event, event)
1153#define findTsanFunction(f, fSig) \
1155 void *fp = dlsym(RTLD_DEFAULT, #f); \
1159 printf("Unable to find TSan function " #f ".\n"); \
1162#define findTsanFunctionSilent(f, fSig) f = fSig dlsym(RTLD_DEFAULT, #f)
1165 ompt_data_t *tool_data) {
1166 const char *options = getenv(
"TSAN_OPTIONS");
1167 TsanFlags tsan_flags(options);
1170 (ompt_set_callback_t)lookup(
"ompt_set_callback");
1172 std::cerr <<
"Could not set callback, exiting..." << std::endl;
1176 (ompt_get_parallel_info_t)lookup(
"ompt_get_parallel_info");
1180 fprintf(stderr,
"Could not get inquiry function 'ompt_get_parallel_info', "
1186 (
void (*)(
const char *,
int,
const volatile void *)));
1188 (
void (*)(
const char *,
int,
const volatile void *)));
1189 findTsanFunction(AnnotateIgnoreWritesBegin, (
void (*)(
const char *,
int)));
1193 (
void (*)(
const char *,
int,
const volatile void *,
size_t)));
1213 if (!tsan_flags.ignore_noninstrumented_modules)
1215 "Warning: please export "
1216 "TSAN_OPTIONS='ignore_noninstrumented_modules=1' "
1217 "to avoid false positive reports from the OpenMP runtime!\n");
1229 getrusage(RUSAGE_SELF, &
end);
1230 printf(
"MAX RSS[KBytes] during execution: %ld\n",
end.ru_maxrss);
1239 const char *options = getenv(
"ARCHER_OPTIONS");
1243 std::cout <<
"Archer disabled, stopping operation" << std::endl;
1260 if (!RunningOnValgrind)
1264 std::cout <<
"Archer detected OpenMP application without TSan; "
1265 "stopping operation"
1272 std::cout <<
"Archer detected OpenMP application with TSan, supplying "
1273 "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 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 __ompt_tsan_func(Args...)
#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()
#define DECLARE_TSAN_FUNCTION(name,...)
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 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 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.
#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 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)
#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 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)