diff --git a/plugin/att/att.py b/plugin/att/att.py index 725f9845d2..618fa3dab0 100755 --- a/plugin/att/att.py +++ b/plugin/att/att.py @@ -19,7 +19,7 @@ import gc from collections import defaultdict from service import CodeobjService -ATT_VERSION = 2 +ATT_VERSION = 3 class TraceData(ctypes.Structure): _fields_ = [ @@ -83,36 +83,42 @@ class ReturnAssemblyInfo(ctypes.Structure): class Wave(ctypes.Structure): _fields_ = [ - ("simd", ctypes.c_uint64), - ("wave_id", ctypes.c_uint64), - ("begin_time", ctypes.c_uint64), # Begin and end cycle - ("end_time", ctypes.c_uint64), - ("traceid", ctypes.c_int64), + ("simd", ctypes.c_uint8), + ("wave_id", ctypes.c_uint8), + ("trap_status", ctypes.c_uint8), + ("reserved", ctypes.c_uint8), + # total VMEM/FLAT/LDS/SMEM instructions issued + # VMEM Pipeline: instrs and stalls + ("num_vmem_instrs", ctypes.c_uint32), + ("num_vmem_stalls", ctypes.c_uint32), + # FLAT instrs and stalls + ("num_flat_instrs", ctypes.c_uint32), + ("num_flat_stalls", ctypes.c_uint32), + # LDS instr and stalls + ("num_lds_instrs", ctypes.c_uint32), + ("num_lds_stalls", ctypes.c_uint32), + # SCA instrs stalls + ("num_salu_instrs", ctypes.c_uint32), + ("num_smem_instrs", ctypes.c_uint32), + ("num_salu_stalls", ctypes.c_uint32), + ("num_smem_stalls", ctypes.c_uint32), + # Branch + ("num_branch_instrs", ctypes.c_uint32), + ("num_branch_taken_instrs", ctypes.c_uint32), + ("num_branch_stalls", ctypes.c_uint32), + # total issued memory instructions - ("num_mem_instrs", ctypes.c_uint64), + ("num_mem_instrs", ctypes.c_uint32), + # total valus insts and stalls + ("num_valu_stalls", ctypes.c_uint32), + ("num_valu_instrs", ctypes.c_uint64), # total issued instructions (compute + memory) ("num_issued_instrs", ctypes.c_uint64), - ("num_valu_instrs", ctypes.c_uint64), - ("num_valu_stalls", ctypes.c_uint64), - # VMEM Pipeline: instrs and stalls - ("num_vmem_instrs", ctypes.c_uint64), - ("num_vmem_stalls", ctypes.c_uint64), - # FLAT instrs and stalls - ("num_flat_instrs", ctypes.c_uint64), - ("num_flat_stalls", ctypes.c_uint64), - # LDS instr and stalls - ("num_lds_instrs", ctypes.c_uint64), - ("num_lds_stalls", ctypes.c_uint64), - # SCA instrs stalls - ("num_salu_instrs", ctypes.c_uint64), - ("num_smem_instrs", ctypes.c_uint64), - ("num_salu_stalls", ctypes.c_uint64), - ("num_smem_stalls", ctypes.c_uint64), - # Branch - ("num_branch_instrs", ctypes.c_uint64), - ("num_branch_taken_instrs", ctypes.c_uint64), - ("num_branch_stalls", ctypes.c_uint64), + # Begin and end cycle + ("begin_time", ctypes.c_uint64), + ("end_time", ctypes.c_uint64), + ("traceid", ctypes.c_int64), ("timeline_size", ctypes.c_uint64), ("instructions_size", ctypes.c_uint64), diff --git a/plugin/att/stitch.py b/plugin/att/stitch.py index acaa1e096f..4bf77f1c87 100644 --- a/plugin/att/stitch.py +++ b/plugin/att/stitch.py @@ -535,7 +535,7 @@ def stitch(insts, raw_code, jumps, gfxv, bIsAuto, codeservice): matched = True skipped_immed -= 1 elif 'scratch_' not in as_line[0]: - print('Parsing terminated at:', as_line) + print('WARNING: Parsing terminated at:', as_line) break if matched: @@ -558,7 +558,7 @@ def stitch(insts, raw_code, jumps, gfxv, bIsAuto, codeservice): N = max(N, 1) if i != N: - print('Warning - Stitching rate: '+str(i * 100 / N)+'% matched') + print('Warning - Stitching rate: '+str(i * 100 / N)+'% matched', i, ' of ', N) print('Leftovers:', [WaveInstCategory[insts[i+k].type] for k in range(20) if i+k < len(insts)]) try: print(line, code[line]) diff --git a/src/core/session/att/att.h b/src/core/session/att/att.h index 05edd98051..027aea034d 100644 --- a/src/core/session/att/att.h +++ b/src/core/session/att/att.h @@ -79,6 +79,21 @@ public: rocprofiler_kernel_properties_t kernel_properties, uint32_t thread_id, uint64_t queue_index); + bool InsertPacketStart( + std::vector& transformed_packets, + queue::Queue& queue_info, + size_t writer_id, + rocprofiler_buffer_id_t buffer_id, + size_t stop_location + ); + + void InsertPacketStop( + std::vector& transformed, + const ATTRecordSignal& rsignal, + queue::Queue& queue, + uint64_t agent_handle + ); + const std::vector& GetPendingSignals(uint32_t writer_id); bool ATTWriteInterceptor( @@ -130,6 +145,10 @@ public: void* data ); + bool HasActiveTracerATT(uint64_t agent_handle) const { + return pending_stop_packets.find(agent_handle) != pending_stop_packets.end(); + } + protected: using packet_t = hsa_ext_amd_aql_pm4_packet_t; static std::unordered_map pending_stop_packets; diff --git a/src/core/session/att/continuous.cpp b/src/core/session/att/continuous.cpp index f99e3890c8..020650d671 100644 --- a/src/core/session/att/continuous.cpp +++ b/src/core/session/att/continuous.cpp @@ -103,55 +103,24 @@ std::optional> AttTracer::RequiresStartPacket(size_t r return {}; } -bool AttTracer::ATTContiguousWriteInterceptor( - const void* packets, - uint64_t pkt_count, - queue::Queue& queue_info, - hsa_amd_queue_intercept_packet_writer writer, - rocprofiler_buffer_id_t buffer_id +bool AttTracer::InsertPacketStart( + std::vector& transformed_packets, + queue::Queue& queue, + size_t writer_id, + rocprofiler_buffer_id_t buffer_id, + size_t stop_id ) { - const packet_t* packets_arr = reinterpret_cast(packets); - std::vector transformed_packets; - - // att start - // Getting Queue Data and Information - auto agent_handle = queue_info.GetGPUAgent().handle; - rocprofiler::HSAAgentInfo& agentInfo = rocprofiler::HSASupport_Singleton::GetInstance() - .GetHSAAgentInfo(agent_handle); - - auto dispatchPackets = Packet::ExtractDispatchPackets(packets, pkt_count); - if (dispatchPackets.size() == 0) return false; - - size_t writer_id = WRITER_ID.fetch_add(dispatchPackets.size(), std::memory_order_relaxed); - uint32_t new_load_cnt = codeobj_capture_instance::GetEventCount(); - - auto bInsertStart = RequiresStartPacket(writer_id, dispatchPackets.size()); - { - std::lock_guard lk(att_enable_disable_mutex); - // If att_start already exists, don't start again - auto agent_pending_packets = pending_stop_packets.find(agent_handle); - if (agent_pending_packets != pending_stop_packets.end()) - bInsertStart = {}; - - // If nothing will be added or removed, return - if (!bInsertStart && codeobj_event_cnt == new_load_cnt) - { - if ( - agent_pending_packets == pending_stop_packets.end() || - agent_pending_packets->second.last_kernel_exec > writer_id + dispatchPackets.size() - ) - return false; - } - } - - if (bInsertStart) - { - // Preparing att Packets + // Preparing att Packets packet_t start_packet{}; packet_t stop_packet{}; hsa_ven_amd_aqlprofile_profile_t* profile = nullptr; rocprofiler_codeobj_capture_mode_t capturem = ROCPROFILER_CAPTURE_SYMBOLS_ONLY; - std::tie(profile, capturem) = ProcessATTParams(start_packet, stop_packet, queue_info, agentInfo); + + auto agent_handle = queue.GetGPUAgent().handle; + rocprofiler::HSAAgentInfo& agentInfo = rocprofiler::HSASupport_Singleton::GetInstance() + .GetHSAAgentInfo(agent_handle); + + std::tie(profile, capturem) = ProcessATTParams(start_packet, stop_packet, queue, agentInfo); if (!profile) { @@ -159,11 +128,9 @@ bool AttTracer::ATTContiguousWriteInterceptor( return false; } - uint64_t IsGFX9 = HSASupport_Singleton::GetInstance() - .GetHSAAgentInfo(agent_handle) - .GetDeviceInfo() - .getName() - .find("gfx9") != std::string::npos; + uint64_t IsGFX9 = agentInfo.GetDeviceInfo() + .getName() + .find("gfx9") != std::string::npos; hsa_signal_t dummy_signal{}; dummy_signal.handle = 0; @@ -192,9 +159,85 @@ bool AttTracer::ATTContiguousWriteInterceptor( codeobj_record::start_capture(this->capture_id); stop_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE; + pending_stop_packets[agent_handle] = {record_id, writer_id, stop_id, session_id_, stop_packet}; + + return true; +} + +void AttTracer::InsertPacketStop( + std::vector& transformed, + const ATTRecordSignal& rsignal, + queue::Queue& queue, + uint64_t agent_handle +) { + // Adding a barrier packet with the original packet's completion signal. + hsa_signal_t interrupt_signal; + CreateSignal(0, &interrupt_signal); + + // Adding Stop PM4 Packets + Packet::AddVendorSpecificPacket(&rsignal.stop_packet, &transformed, interrupt_signal); + + // Added Interrupt Signal with barrier and provided handler for it + Packet::CreateBarrierPacket(&transformed, &interrupt_signal, nullptr); + + // Creating Async Handler to be called every time the interrupt signal is marked complete + signalAsyncHandlerATT(interrupt_signal, new queue::queue_info_session_t{ + queue.GetGPUAgent(), + rsignal.session_id_snapshot, + queue.GetQueueID(), + rsignal.writer_id, + interrupt_signal + }); + + //codeobj_record::stop_capture(rocprofiler_record_id_t{rsignal.record_id}); + codeobj_record::stop_capture(this->capture_id); + active_capture_event_ids.clear(); + pending_stop_packets.erase(agent_handle); +} + +bool AttTracer::ATTContiguousWriteInterceptor( + const void* packets, + uint64_t pkt_count, + queue::Queue& queue_info, + hsa_amd_queue_intercept_packet_writer writer, + rocprofiler_buffer_id_t buffer_id +) { + const packet_t* packets_arr = reinterpret_cast(packets); + std::vector transformed; + + // att start + // Getting Queue Data and Information + const auto agent_handle = queue_info.GetGPUAgent().handle; + + auto dispatchPackets = Packet::ExtractDispatchPackets(packets, pkt_count); + if (dispatchPackets.size() == 0) return false; + + const size_t writer_id = WRITER_ID.fetch_add(dispatchPackets.size(), std::memory_order_relaxed); + const size_t writer_end_id = writer_id + dispatchPackets.size(); + const uint32_t new_load_cnt = codeobj_capture_instance::GetEventCount(); + + auto insertStart = RequiresStartPacket(writer_id, dispatchPackets.size()); + { std::lock_guard lk(att_enable_disable_mutex); - pending_stop_packets[agent_handle] - = {record_id, writer_id, bInsertStart->second, session_id_, stop_packet}; + // If att_start already exists, don't start again + bool bIsActive = this->HasActiveTracerATT(agent_handle); + auto agent_pending_packets = pending_stop_packets.find(agent_handle); + if (bIsActive) + insertStart = {}; + + // If nothing will be added or removed, return + if (!insertStart && codeobj_event_cnt == new_load_cnt) + { + if (!bIsActive || pending_stop_packets.at(agent_handle).last_kernel_exec > writer_end_id) + return false; + } + } + + if (insertStart) + { + std::lock_guard lk(att_enable_disable_mutex); + bool b = InsertPacketStart(transformed, queue_info, writer_id, buffer_id, insertStart->second); + if (!b) return false; } bool bHasPending = false; @@ -203,7 +246,7 @@ bool AttTracer::ATTContiguousWriteInterceptor( bHasPending = pending_stop_packets.find(agent_handle) != pending_stop_packets.end(); } - if (bHasPending && (bInsertStart || codeobj_event_cnt != new_load_cnt)) + if (bHasPending && (insertStart || codeobj_event_cnt != new_load_cnt)) { codeobj_event_cnt = new_load_cnt; @@ -215,13 +258,13 @@ bool AttTracer::ATTContiguousWriteInterceptor( for (uint32_t prev_id : active_capture_event_ids) if (current_ids.find(prev_id) == current_ids.end()) - InsertUnloadMarker(transformed_packets, queue_info.GetGPUAgent(), prev_id); + InsertUnloadMarker(transformed, queue_info.GetGPUAgent(), prev_id); for (size_t s=0; s lk(att_enable_disable_mutex); auto agent_pending_packets = pending_stop_packets.at(agent_handle); - if (agent_pending_packets.last_kernel_exec <= writer_id + dispatchPackets.size()) + if (agent_pending_packets.last_kernel_exec <= writer_end_id) { - const ATTRecordSignal& rsignal = agent_pending_packets; - // Adding a barrier packet with the original packet's completion signal. - hsa_signal_t interrupt_signal; - CreateSignal(0, &interrupt_signal); - - // Adding Stop PM4 Packets - Packet::AddVendorSpecificPacket(&rsignal.stop_packet, &transformed_packets, interrupt_signal); - - // Added Interrupt Signal with barrier and provided handler for it - Packet::CreateBarrierPacket(&transformed_packets, &interrupt_signal, nullptr); - - // Creating Async Handler to be called every time the interrupt signal is marked complete - signalAsyncHandlerATT(interrupt_signal, new queue::queue_info_session_t{ - queue_info.GetGPUAgent(), - rsignal.session_id_snapshot, - queue_info.GetQueueID(), - rsignal.writer_id, - interrupt_signal - }); - - //codeobj_record::stop_capture(rocprofiler_record_id_t{rsignal.record_id}); - codeobj_record::stop_capture(this->capture_id); - active_capture_event_ids.clear(); - pending_stop_packets.erase(agent_handle); + for (uint32_t id : active_capture_event_ids) + InsertUnloadMarker(transformed, queue_info.GetGPUAgent(), id); + InsertPacketStop(transformed, agent_pending_packets, queue_info, agent_handle); + active_capture_event_ids = {}; } } /* Write the transformed packets to the hardware queue. */ - writer(&transformed_packets[0], transformed_packets.size()); + writer(transformed.data(), transformed.size()); return true; }