From 8a2b4685fde869c46ad4ebb19cbfefc4adc2a654 Mon Sep 17 00:00:00 2001 From: Finn Williams Date: Wed, 26 Feb 2020 10:25:26 +0000 Subject: IVGCVSW-4160 Make the ARM Developer Studio code a self contained build entity !armnn:2773 Signed-off-by: Finn Williams Change-Id: I246cf0de04a1d29dd135cb0fc7e55bc5f0d4b854 --- src/timelineDecoder/CMakeLists.txt | 21 ++ .../TimelineCaptureCommandHandler.cpp | 124 +++++++++ .../TimelineCaptureCommandHandler.hpp | 57 ++++ src/timelineDecoder/TimelineDecoder.cpp | 287 +++++++++++++++++++++ src/timelineDecoder/TimelineDecoder.hpp | 68 +++++ .../TimelineDirectoryCaptureCommandHandler.cpp | 115 +++++++++ .../TimelineDirectoryCaptureCommandHandler.hpp | 48 ++++ src/timelineDecoder/tests/TimelineTests.cpp | 253 ++++++++++++++++++ 8 files changed, 973 insertions(+) create mode 100644 src/timelineDecoder/CMakeLists.txt create mode 100644 src/timelineDecoder/TimelineCaptureCommandHandler.cpp create mode 100644 src/timelineDecoder/TimelineCaptureCommandHandler.hpp create mode 100644 src/timelineDecoder/TimelineDecoder.cpp create mode 100644 src/timelineDecoder/TimelineDecoder.hpp create mode 100644 src/timelineDecoder/TimelineDirectoryCaptureCommandHandler.cpp create mode 100644 src/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp create mode 100644 src/timelineDecoder/tests/TimelineTests.cpp (limited to 'src') diff --git a/src/timelineDecoder/CMakeLists.txt b/src/timelineDecoder/CMakeLists.txt new file mode 100644 index 0000000000..6b8517acbc --- /dev/null +++ b/src/timelineDecoder/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Copyright © 2020 Arm Ltd. All rights reserved. +# SPDX-License-Identifier: MIT +# + +set(timelineDecoder_sources) +list(APPEND timelineDecoder_sources + ../../include/armnn/profiling/ITimelineDecoder.hpp + TimelineCaptureCommandHandler.cpp + TimelineCaptureCommandHandler.hpp + TimelineDecoder.cpp + TimelineDecoder.hpp + TimelineDirectoryCaptureCommandHandler.cpp + TimelineDirectoryCaptureCommandHandler.hpp + ) + +include_directories(../timelineDecoder ../profiling) + +add_library_ex(timelineDecoder SHARED ${timelineDecoder_sources}) + +set_target_properties(timelineDecoder PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) \ No newline at end of file diff --git a/src/timelineDecoder/TimelineCaptureCommandHandler.cpp b/src/timelineDecoder/TimelineCaptureCommandHandler.cpp new file mode 100644 index 0000000000..01f55bd6d9 --- /dev/null +++ b/src/timelineDecoder/TimelineCaptureCommandHandler.cpp @@ -0,0 +1,124 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "TimelineCaptureCommandHandler.hpp" + +#include + +namespace armnn +{ + +namespace timelinedecoder +{ + +//Array of member functions, the array index matches the decl_id +const TimelineCaptureCommandHandler::ReadFunction TimelineCaptureCommandHandler::m_ReadFunctions[] +{ + &TimelineCaptureCommandHandler::ReadLabel, // Label decl_id = 0 + &TimelineCaptureCommandHandler::ReadEntity, // Entity decl_id = 1 + &TimelineCaptureCommandHandler::ReadEventClass, // EventClass decl_id = 2 + &TimelineCaptureCommandHandler::ReadRelationship, // Relationship decl_id = 3 + &TimelineCaptureCommandHandler::ReadEvent // Event decl_id = 4 +}; + +void TimelineCaptureCommandHandler::ParseData(const armnn::profiling::Packet& packet) +{ + uint32_t offset = 0; + + if (packet.GetLength() < 8) + { + return; + } + + const unsigned char* data = reinterpret_cast(packet.GetData()); + + uint32_t declId = 0; + + declId = profiling::ReadUint32(data, offset); + offset += uint32_t_size; + + (this->*m_ReadFunctions[declId])(data, offset); +} + +void TimelineCaptureCommandHandler::ReadLabel(const unsigned char* data, uint32_t offset) +{ + ITimelineDecoder::Label label; + label.m_Guid = profiling::ReadUint64(data, offset); + offset += uint64_t_size; + + uint32_t nameLength = profiling::ReadUint32(data, offset); + offset += uint32_t_size; + + for (uint32_t i = 0; i < nameLength-1; ++i) + { + label.m_Name += static_cast(profiling::ReadUint8(data, offset + i)); + } + m_TimelineDecoder.CreateLabel(label); +} + +void TimelineCaptureCommandHandler::ReadEntity(const unsigned char* data, uint32_t offset) +{ + ITimelineDecoder::Entity entity; + entity.m_Guid = profiling::ReadUint64(data, offset); + + m_TimelineDecoder.CreateEntity(entity); +} + +void TimelineCaptureCommandHandler::ReadEventClass(const unsigned char* data, uint32_t offset) +{ + ITimelineDecoder::EventClass eventClass; + eventClass.m_Guid = profiling::ReadUint64(data, offset); + + m_TimelineDecoder.CreateEventClass(eventClass); +} + +void TimelineCaptureCommandHandler::ReadRelationship(const unsigned char* data, uint32_t offset) +{ + ITimelineDecoder::Relationship relationship; + relationship.m_RelationshipType = + static_cast(profiling::ReadUint32(data, offset)); + offset += uint32_t_size; + + relationship.m_Guid = profiling::ReadUint64(data, offset); + offset += uint64_t_size; + + relationship.m_HeadGuid = profiling::ReadUint64(data, offset); + offset += uint64_t_size; + + relationship.m_TailGuid = profiling::ReadUint64(data, offset); + + m_TimelineDecoder.CreateRelationship(relationship); +} + +void TimelineCaptureCommandHandler::ReadEvent(const unsigned char* data, uint32_t offset) +{ + ITimelineDecoder::Event event; + event.m_TimeStamp = profiling::ReadUint64(data, offset); + offset += uint64_t_size; + + if (m_ThreadIdSize == 4) + { + event.m_ThreadId = profiling::ReadUint32(data, offset); + } + else if (m_ThreadIdSize == 8) + { + event.m_ThreadId = profiling::ReadUint64(data, offset); + } + + offset += m_ThreadIdSize; + + event.m_Guid = profiling::ReadUint64(data, offset); + + m_TimelineDecoder.CreateEvent(event); +} + +void TimelineCaptureCommandHandler::operator()(const profiling::Packet& packet) +{ + ParseData(packet); +} + +} //namespace gatordmock + +} //namespace armnn diff --git a/src/timelineDecoder/TimelineCaptureCommandHandler.hpp b/src/timelineDecoder/TimelineCaptureCommandHandler.hpp new file mode 100644 index 0000000000..d95adc0321 --- /dev/null +++ b/src/timelineDecoder/TimelineCaptureCommandHandler.hpp @@ -0,0 +1,57 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include "armnn/profiling/ITimelineDecoder.hpp" + +#include +#include + +namespace armnn +{ + +namespace timelinedecoder +{ + +class TimelineCaptureCommandHandler : public profiling::CommandHandlerFunctor +{ + // Utils + uint32_t uint32_t_size = sizeof(uint32_t); + uint32_t uint64_t_size = sizeof(uint64_t); + + using ReadFunction = void (TimelineCaptureCommandHandler::*)(const unsigned char*, uint32_t); + +public: + TimelineCaptureCommandHandler(uint32_t familyId, + uint32_t packetId, + uint32_t version, + ITimelineDecoder& timelineDecoder, + uint32_t threadId_size) + : CommandHandlerFunctor(familyId, packetId, version) + , m_TimelineDecoder(timelineDecoder) + , m_ThreadIdSize(threadId_size) + {} + + void operator()(const armnn::profiling::Packet& packet) override; + + void ReadLabel(const unsigned char* data, uint32_t offset); + void ReadEntity(const unsigned char* data, uint32_t offset); + void ReadEventClass(const unsigned char* data, uint32_t offset); + void ReadRelationship(const unsigned char* data, uint32_t offset); + void ReadEvent(const unsigned char* data, uint32_t offset); + +private: + void ParseData(const armnn::profiling::Packet& packet); + + ITimelineDecoder& m_TimelineDecoder; + const uint32_t m_ThreadIdSize; + static const ReadFunction m_ReadFunctions[]; +}; + +} //namespace gatordmock + +} //namespace armnn diff --git a/src/timelineDecoder/TimelineDecoder.cpp b/src/timelineDecoder/TimelineDecoder.cpp new file mode 100644 index 0000000000..fcf40b4522 --- /dev/null +++ b/src/timelineDecoder/TimelineDecoder.cpp @@ -0,0 +1,287 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "TimelineDecoder.hpp" +#include "../profiling/ProfilingUtils.hpp" + +#include +namespace armnn +{ +namespace timelinedecoder +{ +TimelineDecoder::ErrorCode TimelineDecoder::CreateEntity(const Entity &entity) +{ + if (m_OnNewEntityCallback == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewEntityCallback(m_Model, entity); + + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::CreateEventClass(const EventClass &eventClass) +{ + if (m_OnNewEventClassCallback == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewEventClassCallback(m_Model, eventClass); + + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::CreateEvent(const Event &event) +{ + if (m_OnNewEventCallback == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewEventCallback(m_Model, event); + + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::CreateLabel(const Label &label) +{ + if (m_OnNewLabelCallback == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewLabelCallback(m_Model, label); + + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::CreateRelationship(const Relationship &relationship) +{ + if (m_OnNewRelationshipCallback == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewRelationshipCallback(m_Model, relationship); + return ErrorCode::ErrorCode_Success; +} + +const TimelineDecoder::Model &TimelineDecoder::GetModel() +{ + return m_Model; +} + +TimelineDecoder::ErrorCode TimelineDecoder::SetEntityCallback(OnNewEntityCallback cb) +{ + if (cb == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewEntityCallback = cb; + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::SetEventClassCallback(OnNewEventClassCallback cb) +{ + if (cb == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewEventClassCallback = cb; + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::SetEventCallback(OnNewEventCallback cb) +{ + if (cb == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewEventCallback = cb; + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::SetLabelCallback(OnNewLabelCallback cb) +{ + if (cb == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewLabelCallback = cb; + return ErrorCode::ErrorCode_Success; +} + +TimelineDecoder::ErrorCode TimelineDecoder::SetRelationshipCallback(OnNewRelationshipCallback cb) +{ + if (cb == nullptr) + { + return ErrorCode::ErrorCode_Fail; + } + m_OnNewRelationshipCallback = cb; + return ErrorCode::ErrorCode_Success; +} + +void TimelineDecoder::print() +{ + printLabels(); + printEntities(); + printEventClasses(); + printEvents(); + printRelationships(); +} + +void TimelineDecoder::printLabels() +{ + std::string header; + + header.append(profiling::CentreAlignFormatting("guid", 12)); + header.append(" | "); + header.append(profiling::CentreAlignFormatting("value", 30)); + header.append("\n"); + + std::cout << "\n" << "\n"; + std::cout << profiling::CentreAlignFormatting("LABELS", static_cast(header.size())); + std::cout << "\n"; + std::cout << std::string(header.size(), '=') << "\n"; + std::cout << header; + + for (uint32_t i = 0; i < m_Model.m_Labels.size(); ++i) + { + std::string body; + + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_Labels[i].m_Guid), 12)); + body.append(" | "); + body.append(profiling::CentreAlignFormatting(m_Model.m_Labels[i].m_Name, 30)); + body.append("\n"); + + std::cout << std::string(body.size(), '-') << "\n"; + std::cout << body; + } +} + +void TimelineDecoder::printEntities() +{ + std::string header; + header.append(profiling::CentreAlignFormatting("guid", 12)); + header.append("\n"); + + std::cout << "\n" << "\n"; + std::cout << profiling::CentreAlignFormatting("ENTITIES", static_cast(header.size())); + std::cout << "\n"; + std::cout << std::string(header.size(), '=') << "\n"; + std::cout << header; + + for (uint32_t i = 0; i < m_Model.m_Entities.size(); ++i) + { + std::string body; + + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_Entities[i].m_Guid), 12)); + body.append("\n"); + + std::cout << std::string(body.size(), '-') << "\n"; + std::cout << body; + } +} + +void TimelineDecoder::printEventClasses() +{ + std::string header; + header.append(profiling::CentreAlignFormatting("guid", 12)); + header.append("\n"); + + std::cout << "\n" << "\n"; + std::cout << profiling::CentreAlignFormatting("EVENT CLASSES", static_cast(header.size())); + std::cout << "\n"; + std::cout << std::string(header.size(), '=') << "\n"; + std::cout << header; + + for (uint32_t i = 0; i < m_Model.m_EventClasses.size(); ++i) + { + std::string body; + + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_EventClasses[i].m_Guid), 12)); + body.append("\n"); + + std::cout << std::string(body.size(), '-') << "\n"; + std::cout << body; + } +} + +void TimelineDecoder::printEvents() +{ + std::string header; + + header.append(profiling::CentreAlignFormatting("timestamp", 12)); + header.append(" | "); + header.append(profiling::CentreAlignFormatting("threadId", 12)); + header.append(" | "); + header.append(profiling::CentreAlignFormatting("eventGuid", 12)); + header.append("\n"); + + std::cout << "\n" << "\n"; + std::cout << profiling::CentreAlignFormatting("EVENTS", static_cast(header.size())); + std::cout << "\n"; + std::cout << std::string(header.size(), '=') << "\n"; + std::cout << header; + + for (uint32_t i = 0; i < m_Model.m_Events.size(); ++i) + { + std::string body; + + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_Events[i].m_TimeStamp), 12)); + body.append(" | "); + + std::stringstream ss; + ss << m_Model.m_Events[i].m_ThreadId; + std::string threadId = ss.str();; + + body.append(profiling::CentreAlignFormatting(threadId, 12)); + body.append(" | "); + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_Events[i].m_Guid), 12)); + body.append("\n"); + + std::cout << std::string(body.size(), '-') << "\n"; + std::cout << body; + } +} + +void TimelineDecoder::printRelationships() +{ + std::string header; + header.append(profiling::CentreAlignFormatting("relationshipType", 20)); + header.append(" | "); + header.append(profiling::CentreAlignFormatting("relationshipGuid", 20)); + header.append(" | "); + header.append(profiling::CentreAlignFormatting("headGuid", 12)); + header.append(" | "); + header.append(profiling::CentreAlignFormatting("tailGuid", 12)); + header.append("\n"); + + std::cout << "\n" << "\n"; + std::cout << profiling::CentreAlignFormatting("RELATIONSHIPS", static_cast(header.size())); + std::cout << "\n"; + std::cout << std::string(header.size(), '=') << "\n"; + std::cout << header; + + for (uint32_t i = 0; i < m_Model.m_Relationships.size(); ++i) + { + std::string body; + + body.append( + profiling::CentreAlignFormatting(std::to_string(static_cast + (m_Model.m_Relationships[i].m_RelationshipType)), + 20)); + body.append(" | "); + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_Relationships[i].m_Guid), 20)); + body.append(" | "); + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_Relationships[i].m_HeadGuid), 12)); + body.append(" | "); + body.append(profiling::CentreAlignFormatting(std::to_string(m_Model.m_Relationships[i].m_TailGuid), 12)); + body.append(" | "); + body.append("\n"); + + std::cout << std::string(body.size(), '-') << "\n"; + std::cout << body; + } +} +} +} \ No newline at end of file diff --git a/src/timelineDecoder/TimelineDecoder.hpp b/src/timelineDecoder/TimelineDecoder.hpp new file mode 100644 index 0000000000..fc14603927 --- /dev/null +++ b/src/timelineDecoder/TimelineDecoder.hpp @@ -0,0 +1,68 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "armnn/profiling/ITimelineDecoder.hpp" +#include + +namespace armnn +{ +namespace timelinedecoder +{ +class TimelineDecoder : public ITimelineDecoder +{ + +public: + + struct Model + { + std::vector m_Entities; + std::vector m_EventClasses; + std::vector m_Events; + std::vector