// // Copyright © 2019 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ProfilingMocks.hpp" #include "ProfilingTestUtils.hpp" #include #include #include #include #include #include #include #include using namespace armnn; using namespace arm::pipe; TEST_SUITE("TimelineUtilityMethodsTests") { TEST_CASE("CreateTypedLabelTest") { MockBufferManager mockBufferManager(1024); armnn::ArmNNProfilingServiceInitialiser initialiser; ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER, initialiser, arm::pipe::ARMNN_SOFTWARE_INFO, arm::pipe::ARMNN_SOFTWARE_VERSION, arm::pipe::ARMNN_HARDWARE_VERSION); std::unique_ptr sendTimelinePacket = std::make_unique(mockBufferManager); TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket); // Generate first guid to ensure that the named typed entity guid is not 0 on local single test. profilingService.NextGuid(); ProfilingGuid entityGuid(123); const std::string entityName = "some entity"; ProfilingStaticGuid labelTypeGuid(456); CHECK_NOTHROW(timelineUtilityMethods.MarkEntityWithLabel(entityGuid, entityName, labelTypeGuid)); // Commit all packets at once timelineUtilityMethods.Commit(); // Get the readable buffer auto readableBuffer = mockBufferManager.GetReadableBuffer(); CHECK(readableBuffer != nullptr); unsigned int size = readableBuffer->GetSize(); CHECK(size == 76); const unsigned char* readableData = readableBuffer->GetReadableData(); CHECK(readableData != nullptr); // Utils unsigned int offset = 0; // Verify Header VerifyTimelineHeaderBinary(readableData, offset, 68); // First dataset sent: TimelineLabelBinaryPacket VerifyTimelineLabelBinaryPacketData(arm::pipe::EmptyOptional(), entityName, readableData, offset); // Second dataset sent: TimelineRelationshipBinaryPacket VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink, arm::pipe::EmptyOptional(), entityGuid, arm::pipe::EmptyOptional(), labelTypeGuid, readableData, offset); // Mark the buffer as read mockBufferManager.MarkRead(readableBuffer); } TEST_CASE("SendWellKnownLabelsAndEventClassesTest") { MockBufferManager mockBufferManager(1024); armnn::ArmNNProfilingServiceInitialiser initialiser; ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER, initialiser, arm::pipe::ARMNN_SOFTWARE_INFO, arm::pipe::ARMNN_SOFTWARE_VERSION, arm::pipe::ARMNN_HARDWARE_VERSION); SendTimelinePacket sendTimelinePacket(mockBufferManager); CHECK_NOTHROW(TimelineUtilityMethods::SendWellKnownLabelsAndEventClasses(sendTimelinePacket)); // Get the readable buffer auto readableBuffer = mockBufferManager.GetReadableBuffer(); CHECK(readableBuffer != nullptr); unsigned int size = readableBuffer->GetSize(); CHECK(size == 460); const unsigned char* readableData = readableBuffer->GetReadableData(); CHECK(readableData != nullptr); // Utils unsigned int offset = 0; // Verify Header VerifyTimelineHeaderBinary(readableData, offset, 452); // First "well-known" label: NAME VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::NAME_GUID, LabelsAndEventClasses::NAME_LABEL, readableData, offset); // Second "well-known" label: TYPE VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::TYPE_GUID, LabelsAndEventClasses::TYPE_LABEL, readableData, offset); // Third "well-known" label: INDEX VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::INDEX_GUID, LabelsAndEventClasses::INDEX_LABEL, readableData, offset); // Forth "well-known" label: BACKENDID VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::BACKENDID_GUID, LabelsAndEventClasses::BACKENDID_LABEL, readableData, offset); // Fifth "well-known" label: CHILD VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::CHILD_GUID, LabelsAndEventClasses::CHILD_LABEL, readableData, offset); // Sixth "well-known" label: EXECUTION_OF VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::EXECUTION_OF_GUID, LabelsAndEventClasses::EXECUTION_OF_LABEL, readableData, offset); // Seventh "well-known" label: PROCESS_ID_LABEL VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::PROCESS_ID_GUID, LabelsAndEventClasses::PROCESS_ID_LABEL, readableData, offset); // Well-known types // Layer VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::LAYER_GUID, LabelsAndEventClasses::LAYER, readableData, offset); // Workload VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::WORKLOAD_GUID, LabelsAndEventClasses::WORKLOAD, readableData, offset); // Network VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::NETWORK_GUID, LabelsAndEventClasses::NETWORK, readableData, offset); // Connection VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::CONNECTION_GUID, LabelsAndEventClasses::CONNECTION, readableData, offset); // Inference VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::INFERENCE_GUID, LabelsAndEventClasses::INFERENCE, readableData, offset); // Workload Execution VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID, LabelsAndEventClasses::WORKLOAD_EXECUTION, readableData, offset); // First "well-known" event class: START OF LIFE VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS_NAME_GUID, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS_NAME, readableData, offset); VerifyTimelineEventClassBinaryPacketData(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS_NAME_GUID, readableData, offset); // Second "well-known" event class: END OF LIFE VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS_NAME_GUID, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS_NAME, readableData, offset); VerifyTimelineEventClassBinaryPacketData(LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS_NAME_GUID, readableData, offset); // Mark the buffer as read mockBufferManager.MarkRead(readableBuffer); } TEST_CASE("CreateNamedTypedChildEntityTest") { MockBufferManager mockBufferManager(1024); armnn::ArmNNProfilingServiceInitialiser initialiser; ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER, initialiser, arm::pipe::ARMNN_SOFTWARE_INFO, arm::pipe::ARMNN_SOFTWARE_VERSION, arm::pipe::ARMNN_HARDWARE_VERSION); std::unique_ptr sendTimelinePacket = std::make_unique(mockBufferManager); TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket); ProfilingDynamicGuid childEntityGuid(0); ProfilingGuid parentEntityGuid(123); const std::string entityName = "some entity"; const std::string entityType = "some type"; // Generate first guid to ensure that the named typed entity guid is not 0 on local single test. profilingService.NextGuid(); CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedChildEntity(parentEntityGuid, "", entityType), arm::pipe::InvalidArgumentException); CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedChildEntity(parentEntityGuid, entityName, ""), arm::pipe::InvalidArgumentException); CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedChildEntity( childEntityGuid, parentEntityGuid, "", entityType), arm::pipe::InvalidArgumentException); CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedChildEntity( childEntityGuid, parentEntityGuid, entityName, ""), arm::pipe::InvalidArgumentException); CHECK_NOTHROW(childEntityGuid = timelineUtilityMethods.CreateNamedTypedChildEntity(parentEntityGuid, entityName, entityType)); CHECK(childEntityGuid != ProfilingGuid(0)); // Commit all packets at onceTimelineUtilityMethodsTests.cpp timelineUtilityMethods.Commit(); // Get the readable buffer auto readableBuffer = mockBufferManager.GetReadableBuffer(); CHECK(readableBuffer != nullptr); unsigned int size = readableBuffer->GetSize(); CHECK(size == 196); const unsigned char* readableData = readableBuffer->GetReadableData(); CHECK(readableData != nullptr); // Utils unsigned int offset = 0; // Verify Header VerifyTimelineHeaderBinary(readableData, offset, 188); // First dataset sent: TimelineEntityBinaryPacket VerifyTimelineEntityBinaryPacketData(arm::pipe::EmptyOptional(), readableData, offset); // Second dataset sent: TimelineLabelBinaryPacket VerifyTimelineLabelBinaryPacketData(arm::pipe::EmptyOptional(), entityName, readableData, offset); // Third dataset sent: TimelineRelationshipBinaryPacket VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink, arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), LabelsAndEventClasses::NAME_GUID, readableData, offset); // Fifth dataset sent: TimelineLabelBinaryPacket VerifyTimelineLabelBinaryPacketData(arm::pipe::EmptyOptional(), entityType, readableData, offset); // Sixth dataset sent: TimelineRelationshipBinaryPacket VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink, arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), LabelsAndEventClasses::TYPE_GUID, readableData, offset); // Eighth dataset sent: TimelineRelationshipBinaryPacket VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink, arm::pipe::EmptyOptional(), parentEntityGuid, arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), readableData, offset); // Mark the buffer as read mockBufferManager.MarkRead(readableBuffer); } TEST_CASE("DeclareLabelTest") { MockBufferManager mockBufferManager(1024); armnn::ArmNNProfilingServiceInitialiser initialiser; ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER, initialiser, arm::pipe::ARMNN_SOFTWARE_INFO, arm::pipe::ARMNN_SOFTWARE_VERSION, arm::pipe::ARMNN_HARDWARE_VERSION); std::unique_ptr sendTimelinePacket = std::make_unique(mockBufferManager); TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket); // Generate first guid to ensure that the named typed entity guid is not 0 on local single test. profilingService.NextGuid(); // Try declaring an invalid (empty) label CHECK_THROWS_AS(timelineUtilityMethods.DeclareLabel(""), arm::pipe::InvalidArgumentException); // Try declaring an invalid (wrong SWTrace format) label CHECK_THROWS_AS(timelineUtilityMethods.DeclareLabel("inv@lid lab€l"), arm::pipe::ProfilingException); // Declare a valid label const std::string labelName = "valid label"; ProfilingGuid labelGuid = 0; CHECK_NOTHROW(labelGuid = timelineUtilityMethods.DeclareLabel(labelName)); CHECK(labelGuid != ProfilingGuid(0)); // Try adding the same label as before ProfilingGuid newLabelGuid = 0; CHECK_NOTHROW(newLabelGuid = timelineUtilityMethods.DeclareLabel(labelName)); CHECK(newLabelGuid != ProfilingGuid(0)); CHECK(newLabelGuid == labelGuid); } TEST_CASE("CreateNameTypeEntityInvalidTest") { MockBufferManager mockBufferManager(1024); armnn::ArmNNProfilingServiceInitialiser initialiser; ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER, initialiser, arm::pipe::ARMNN_SOFTWARE_INFO, arm::pipe::ARMNN_SOFTWARE_VERSION, arm::pipe::ARMNN_HARDWARE_VERSION); std::unique_ptr sendTimelinePacket = std::make_unique(mockBufferManager); TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket); // Invalid name CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedEntity("", "Type"), arm::pipe::InvalidArgumentException); // Invalid type CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedEntity("Name", ""), arm::pipe::InvalidArgumentException); ProfilingDynamicGuid guid = profilingService.NextGuid(); // CreatedNamedTypedEntity with Guid - Invalid name CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedEntity(guid, "", "Type"), arm::pipe::InvalidArgumentException); // CreatedNamedTypedEntity with Guid - Invalid type CHECK_THROWS_AS(timelineUtilityMethods.CreateNamedTypedEntity(guid, "Name", ""), arm::pipe::InvalidArgumentException); } TEST_CASE("CreateNameTypeEntityTest") { MockBufferManager mockBufferManager(1024); armnn::ArmNNProfilingServiceInitialiser initialiser; ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER, initialiser, arm::pipe::ARMNN_SOFTWARE_INFO, arm::pipe::ARMNN_SOFTWARE_VERSION, arm::pipe::ARMNN_HARDWARE_VERSION); std::unique_ptr sendTimelinePacket = std::make_unique(mockBufferManager); TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket); const std::string entityName = "Entity0"; const std::string entityType = "Type0"; // Generate first guid to ensure that the named typed entity guid is not 0 on local single test. profilingService.NextGuid(); ProfilingDynamicGuid guid = timelineUtilityMethods.CreateNamedTypedEntity(entityName, entityType); CHECK(guid != ProfilingGuid(0)); // Commit all packets at once timelineUtilityMethods.Commit(); // Get the readable buffer auto readableBuffer = mockBufferManager.GetReadableBuffer(); CHECK(readableBuffer != nullptr); unsigned int size = readableBuffer->GetSize(); CHECK(size == 148); const unsigned char* readableData = readableBuffer->GetReadableData(); CHECK(readableData != nullptr); // Utils unsigned int offset = 0; // Verify Header VerifyTimelineHeaderBinary(readableData, offset, 140); // First dataset sent: TimelineEntityBinaryPacket VerifyTimelineEntityBinaryPacketData(guid, readableData, offset); // Packets for Name Entity // First dataset sent: TimelineLabelBinaryPacket VerifyTimelineLabelBinaryPacketData(arm::pipe::EmptyOptional(), entityName, readableData, offset); // Second dataset sent: TimelineRelationshipBinaryPacket VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink, arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), LabelsAndEventClasses::NAME_GUID, readableData, offset); // Packets for Type Entity // First dataset sent: TimelineLabelBinaryPacket VerifyTimelineLabelBinaryPacketData(arm::pipe::EmptyOptional(), entityType, readableData, offset); // Second dataset sent: TimelineRelationshipBinaryPacket VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink, arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), LabelsAndEventClasses::TYPE_GUID, readableData, offset); // Mark the buffer as read mockBufferManager.MarkRead(readableBuffer); } TEST_CASE("RecordEventTest") { MockBufferManager mockBufferManager(1024); armnn::ArmNNProfilingServiceInitialiser initialiser; ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER, initialiser, arm::pipe::ARMNN_SOFTWARE_INFO, arm::pipe::ARMNN_SOFTWARE_VERSION, arm::pipe::ARMNN_HARDWARE_VERSION); std::unique_ptr sendTimelinePacket = std::make_unique(mockBufferManager); TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket); // Generate first guid to ensure that the named typed entity guid is not 0 on local single test. profilingService.NextGuid(); ProfilingGuid entityGuid(123); ProfilingStaticGuid eventClassGuid(456); ProfilingDynamicGuid eventGuid(0); CHECK_NOTHROW(eventGuid = timelineUtilityMethods.RecordEvent(entityGuid, eventClassGuid)); CHECK(eventGuid != ProfilingGuid(0)); // Commit all packets at once timelineUtilityMethods.Commit(); // Get the readable buffer auto readableBuffer = mockBufferManager.GetReadableBuffer(); CHECK(readableBuffer != nullptr); unsigned int size = readableBuffer->GetSize(); CHECK(size == 68 + ThreadIdSize); const unsigned char* readableData = readableBuffer->GetReadableData(); CHECK(readableData != nullptr); // Utils unsigned int offset = 0; // Verify Header VerifyTimelineHeaderBinary(readableData, offset, 60 + ThreadIdSize); // First dataset sent: TimelineEntityBinaryPacket VerifyTimelineEventBinaryPacket( arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), arm::pipe::EmptyOptional(), readableData, offset); // Second dataset sent: TimelineRelationshipBinaryPacket VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink, arm::pipe::EmptyOptional(), entityGuid, eventGuid, eventClassGuid, readableData, offset); // Mark the buffer as read mockBufferManager.MarkRead(readableBuffer); } }