| //===- InternalEvent.cpp - Internal event implementation --------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// Implements internal event representation methods and helper functions. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #include "InternalEvent.h" |
| |
| #include <iomanip> |
| #include <sstream> |
| |
| using namespace omptest; |
| using namespace util; |
| |
| std::string util::makeHexString(uint64_t Data, bool IsPointer, size_t MinBytes, |
| bool ShowHexBase) { |
| if (Data == 0 && IsPointer) |
| return "(nil)"; |
| |
| thread_local std::ostringstream os; |
| // Clear the content of the stream |
| os.str(std::string()); |
| |
| // Manually prefixing "0x" will make the use of std::setfill more easy |
| if (ShowHexBase) |
| os << "0x"; |
| |
| // Default to 32bit (8 hex digits) width, if exceeding 64bit or zero value |
| size_t NumDigits = (MinBytes > 0 && MinBytes < 9) ? (MinBytes << 1) : 8; |
| |
| if (MinBytes > 0) |
| os << std::setfill('0') << std::setw(NumDigits); |
| |
| os << std::hex << Data; |
| return os.str(); |
| } |
| |
| std::string internal::AssertionSyncPoint::toString() const { |
| std::string S{"Assertion SyncPoint: '"}; |
| S.append(Name).append(1, '\''); |
| return S; |
| } |
| |
| std::string internal::ThreadBegin::toString() const { |
| std::string S{"OMPT Callback ThreadBegin: "}; |
| S.append("ThreadType=").append(std::to_string(ThreadType)); |
| return S; |
| } |
| |
| std::string internal::ThreadEnd::toString() const { |
| std::string S{"OMPT Callback ThreadEnd"}; |
| return S; |
| } |
| |
| std::string internal::ParallelBegin::toString() const { |
| std::string S{"OMPT Callback ParallelBegin: "}; |
| S.append("NumThreads=").append(std::to_string(NumThreads)); |
| return S; |
| } |
| |
| std::string internal::ParallelEnd::toString() const { |
| // TODO: Should we expose more detailed info here? |
| std::string S{"OMPT Callback ParallelEnd"}; |
| return S; |
| } |
| |
| std::string internal::Work::toString() const { |
| std::string S{"OMPT Callback Work: "}; |
| S.append("work_type=").append(std::to_string(WorkType)); |
| S.append(" endpoint=").append(std::to_string(Endpoint)); |
| S.append(" parallel_data=").append(makeHexString((uint64_t)ParallelData)); |
| S.append(" task_data=").append(makeHexString((uint64_t)TaskData)); |
| S.append(" count=").append(std::to_string(Count)); |
| S.append(" codeptr=").append(makeHexString((uint64_t)CodeptrRA)); |
| return S; |
| } |
| |
| std::string internal::Dispatch::toString() const { |
| std::string S{"OMPT Callback Dispatch: "}; |
| S.append("parallel_data=").append(makeHexString((uint64_t)ParallelData)); |
| S.append(" task_data=").append(makeHexString((uint64_t)TaskData)); |
| S.append(" kind=").append(std::to_string(Kind)); |
| // TODO Check what to print for instance in all different cases |
| if (Kind == ompt_dispatch_iteration) { |
| S.append(" instance=[it=") |
| .append(std::to_string(Instance.value)) |
| .append(1, ']'); |
| } else if (Kind == ompt_dispatch_section) { |
| S.append(" instance=[ptr=") |
| .append(makeHexString((uint64_t)Instance.ptr)) |
| .append(1, ']'); |
| } else if ((Kind == ompt_dispatch_ws_loop_chunk || |
| Kind == ompt_dispatch_taskloop_chunk || |
| Kind == ompt_dispatch_distribute_chunk) && |
| Instance.ptr != nullptr) { |
| auto Chunk = static_cast<ompt_dispatch_chunk_t *>(Instance.ptr); |
| S.append(" instance=[chunk=(start=") |
| .append(std::to_string(Chunk->start)) |
| .append(", iterations=") |
| .append(std::to_string(Chunk->iterations)) |
| .append(")]"); |
| } |
| return S; |
| } |
| |
| std::string internal::TaskCreate::toString() const { |
| std::string S{"OMPT Callback TaskCreate: "}; |
| S.append("encountering_task_data=") |
| .append(makeHexString((uint64_t)EncounteringTaskData)); |
| S.append(" encountering_task_frame=") |
| .append(makeHexString((uint64_t)EncounteringTaskFrame)); |
| S.append(" new_task_data=").append(makeHexString((uint64_t)NewTaskData)); |
| S.append(" flags=").append(std::to_string(Flags)); |
| S.append(" has_dependences=").append(std::to_string(HasDependences)); |
| S.append(" codeptr=").append(makeHexString((uint64_t)CodeptrRA)); |
| return S; |
| } |
| |
| std::string internal::ImplicitTask::toString() const { |
| std::string S{"OMPT Callback ImplicitTask: "}; |
| S.append("endpoint=").append(std::to_string(Endpoint)); |
| S.append(" parallel_data=").append(makeHexString((uint64_t)ParallelData)); |
| S.append(" task_data=").append(makeHexString((uint64_t)TaskData)); |
| S.append(" actual_parallelism=").append(std::to_string(ActualParallelism)); |
| S.append(" index=").append(std::to_string(Index)); |
| S.append(" flags=").append(std::to_string(Flags)); |
| return S; |
| } |
| |
| std::string internal::SyncRegion::toString() const { |
| std::string S{"OMPT Callback SyncRegion: "}; |
| S.append("kind=").append(std::to_string(Kind)); |
| S.append(" endpoint=").append(std::to_string(Endpoint)); |
| S.append(" parallel_data=").append(makeHexString((uint64_t)ParallelData)); |
| S.append(" task_data=").append(makeHexString((uint64_t)TaskData)); |
| S.append(" codeptr=").append(makeHexString((uint64_t)CodeptrRA)); |
| return S; |
| } |
| |
| std::string internal::Target::toString() const { |
| // TODO Should we canonicalize the string prefix (use "OMPT ..." everywhere)? |
| std::string S{"Callback Target: target_id="}; |
| S.append(std::to_string(TargetId)); |
| S.append(" kind=").append(std::to_string(Kind)); |
| S.append(" endpoint=").append(std::to_string(Endpoint)); |
| S.append(" device_num=").append(std::to_string(DeviceNum)); |
| S.append(" code=").append(makeHexString((uint64_t)CodeptrRA)); |
| return S; |
| } |
| |
| std::string internal::TargetEmi::toString() const { |
| // TODO Should we canonicalize the string prefix (use "OMPT ..." everywhere)? |
| std::string S{"Callback Target EMI: kind="}; |
| S.append(std::to_string(Kind)); |
| S.append(" endpoint=").append(std::to_string(Endpoint)); |
| S.append(" device_num=").append(std::to_string(DeviceNum)); |
| S.append(" task_data=").append(makeHexString((uint64_t)TaskData)); |
| S.append(" (") |
| .append(makeHexString((uint64_t)(TaskData) ? TaskData->value : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| S.append(" target_task_data=") |
| .append(makeHexString((uint64_t)TargetTaskData)); |
| S.append(" (") |
| .append( |
| makeHexString((uint64_t)(TargetTaskData) ? TargetTaskData->value : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| S.append(" target_data=").append(makeHexString((uint64_t)TargetData)); |
| S.append(" (") |
| .append(makeHexString((uint64_t)(TargetData) ? TargetData->value : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| S.append(" code=").append(makeHexString((uint64_t)CodeptrRA)); |
| return S; |
| } |
| |
| std::string internal::TargetDataOp::toString() const { |
| std::string S{" Callback DataOp: target_id="}; |
| S.append(std::to_string(TargetId)); |
| S.append(" host_op_id=").append(std::to_string(HostOpId)); |
| S.append(" optype=").append(std::to_string(OpType)); |
| S.append(" src=").append(makeHexString((uint64_t)SrcAddr)); |
| S.append(" src_device_num=").append(std::to_string(SrcDeviceNum)); |
| S.append(" dest=").append(makeHexString((uint64_t)DstAddr)); |
| S.append(" dest_device_num=").append(std::to_string(DstDeviceNum)); |
| S.append(" bytes=").append(std::to_string(Bytes)); |
| S.append(" code=").append(makeHexString((uint64_t)CodeptrRA)); |
| return S; |
| } |
| |
| std::string internal::TargetDataOpEmi::toString() const { |
| std::string S{" Callback DataOp EMI: endpoint="}; |
| S.append(std::to_string(Endpoint)); |
| S.append(" optype=").append(std::to_string(OpType)); |
| S.append(" target_task_data=") |
| .append(makeHexString((uint64_t)TargetTaskData)); |
| S.append(" (") |
| .append( |
| makeHexString((uint64_t)(TargetTaskData) ? TargetTaskData->value : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| S.append(" target_data=").append(makeHexString((uint64_t)TargetData)); |
| S.append(" (") |
| .append(makeHexString((uint64_t)(TargetData) ? TargetData->value : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| S.append(" host_op_id=").append(makeHexString((uint64_t)HostOpId)); |
| S.append(" (") |
| .append(makeHexString((uint64_t)(HostOpId) ? (*HostOpId) : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| S.append(" src=").append(makeHexString((uint64_t)SrcAddr)); |
| S.append(" src_device_num=").append(std::to_string(SrcDeviceNum)); |
| S.append(" dest=").append(makeHexString((uint64_t)DstAddr)); |
| S.append(" dest_device_num=").append(std::to_string(DstDeviceNum)); |
| S.append(" bytes=").append(std::to_string(Bytes)); |
| S.append(" code=").append(makeHexString((uint64_t)CodeptrRA)); |
| return S; |
| } |
| |
| std::string internal::TargetSubmit::toString() const { |
| std::string S{" Callback Submit: target_id="}; |
| S.append(std::to_string(TargetId)); |
| S.append(" host_op_id=").append(std::to_string(HostOpId)); |
| S.append(" req_num_teams=").append(std::to_string(RequestedNumTeams)); |
| return S; |
| } |
| |
| std::string internal::TargetSubmitEmi::toString() const { |
| std::string S{" Callback Submit EMI: endpoint="}; |
| S.append(std::to_string(Endpoint)); |
| S.append(" req_num_teams=").append(std::to_string(RequestedNumTeams)); |
| S.append(" target_data=").append(makeHexString((uint64_t)TargetData)); |
| S.append(" (") |
| .append(makeHexString((uint64_t)(TargetData) ? TargetData->value : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| S.append(" host_op_id=").append(makeHexString((uint64_t)HostOpId)); |
| S.append(" (") |
| .append(makeHexString((uint64_t)(HostOpId) ? (*HostOpId) : 0, |
| /*IsPointer=*/false)) |
| .append(1, ')'); |
| return S; |
| } |
| |
| std::string internal::DeviceInitialize::toString() const { |
| std::string S{"Callback Init: device_num="}; |
| S.append(std::to_string(DeviceNum)); |
| S.append(" type=").append((Type) ? Type : "(null)"); |
| S.append(" device=").append(makeHexString((uint64_t)Device)); |
| S.append(" lookup=").append(makeHexString((uint64_t)LookupFn)); |
| S.append(" doc=").append(makeHexString((uint64_t)DocStr)); |
| return S; |
| } |
| |
| std::string internal::DeviceFinalize::toString() const { |
| std::string S{"Callback Fini: device_num="}; |
| S.append(std::to_string(DeviceNum)); |
| return S; |
| } |
| |
| std::string internal::DeviceLoad::toString() const { |
| std::string S{"Callback Load: device_num:"}; |
| S.append(std::to_string(DeviceNum)); |
| S.append(" module_id:").append(std::to_string(ModuleId)); |
| S.append(" filename:").append((Filename == nullptr) ? "(null)" : Filename); |
| S.append(" host_addr:").append(makeHexString((uint64_t)HostAddr)); |
| S.append(" device_addr:").append(makeHexString((uint64_t)DeviceAddr)); |
| S.append(" bytes:").append(std::to_string(Bytes)); |
| return S; |
| } |
| |
| std::string internal::BufferRequest::toString() const { |
| std::string S{"Allocated "}; |
| S.append(std::to_string((Bytes != nullptr) ? *Bytes : 0)) |
| .append(" bytes at "); |
| S.append(makeHexString((Buffer != nullptr) ? (uint64_t)*Buffer : 0)); |
| S.append(" in buffer request callback"); |
| return S; |
| } |
| |
| std::string internal::BufferComplete::toString() const { |
| std::string S{"Executing buffer complete callback: "}; |
| S.append(std::to_string(DeviceNum)).append(1, ' '); |
| S.append(makeHexString((uint64_t)Buffer)).append(1, ' '); |
| S.append(std::to_string(Bytes)).append(1, ' '); |
| S.append(makeHexString((uint64_t)Begin)).append(1, ' '); |
| S.append(std::to_string(BufferOwned)); |
| return S; |
| } |
| |
| std::string internal::BufferRecord::toString() const { |
| std::string S{""}; |
| std::string T{""}; |
| S.append("rec=").append(makeHexString((uint64_t)RecordPtr)); |
| S.append(" type=").append(std::to_string(Record.type)); |
| |
| T.append("time=").append(std::to_string(Record.time)); |
| T.append(" thread_id=").append(std::to_string(Record.thread_id)); |
| T.append(" target_id=").append(std::to_string(Record.target_id)); |
| |
| switch (Record.type) { |
| case ompt_callback_target: |
| case ompt_callback_target_emi: { |
| // Handle Target Record |
| ompt_record_target_t TR = Record.record.target; |
| S.append(" (Target task) ").append(T); |
| S.append(" kind=").append(std::to_string(TR.kind)); |
| S.append(" endpoint=").append(std::to_string(TR.endpoint)); |
| S.append(" device=").append(std::to_string(TR.device_num)); |
| S.append(" task_id=").append(std::to_string(TR.task_id)); |
| S.append(" codeptr=").append(makeHexString((uint64_t)TR.codeptr_ra)); |
| break; |
| } |
| case ompt_callback_target_data_op: |
| case ompt_callback_target_data_op_emi: { |
| // Handle Target DataOp Record |
| ompt_record_target_data_op_t TDR = Record.record.target_data_op; |
| S.append(" (Target data op) ").append(T); |
| S.append(" host_op_id=").append(std::to_string(TDR.host_op_id)); |
| S.append(" optype=").append(std::to_string(TDR.optype)); |
| S.append(" src_addr=").append(makeHexString((uint64_t)TDR.src_addr)); |
| S.append(" src_device=").append(std::to_string(TDR.src_device_num)); |
| S.append(" dest_addr=").append(makeHexString((uint64_t)TDR.dest_addr)); |
| S.append(" dest_device=").append(std::to_string(TDR.dest_device_num)); |
| S.append(" bytes=").append(std::to_string(TDR.bytes)); |
| S.append(" end_time=").append(std::to_string(TDR.end_time)); |
| S.append(" duration=").append(std::to_string(TDR.end_time - Record.time)); |
| S.append(" ns codeptr=").append(makeHexString((uint64_t)TDR.codeptr_ra)); |
| break; |
| } |
| case ompt_callback_target_submit: |
| case ompt_callback_target_submit_emi: { |
| // Handle Target Kernel Record |
| ompt_record_target_kernel_t TKR = Record.record.target_kernel; |
| S.append(" (Target kernel) ").append(T); |
| S.append(" host_op_id=").append(std::to_string(TKR.host_op_id)); |
| S.append(" requested_num_teams=") |
| .append(std::to_string(TKR.requested_num_teams)); |
| S.append(" granted_num_teams=") |
| .append(std::to_string(TKR.granted_num_teams)); |
| S.append(" end_time=").append(std::to_string(TKR.end_time)); |
| S.append(" duration=").append(std::to_string(TKR.end_time - Record.time)); |
| S.append(" ns"); |
| break; |
| } |
| default: |
| S.append(" (unsupported record type)"); |
| break; |
| } |
| |
| return S; |
| } |
| |
| std::string internal::BufferRecordDeallocation::toString() const { |
| std::string S{"Deallocated "}; |
| S.append(makeHexString((uint64_t)Buffer)); |
| return S; |
| } |