diff options
author | Narumol Prangnawarat <narumol.prangnawarat@arm.com> | 2019-11-22 11:26:06 +0000 |
---|---|---|
committer | Jim Flynn Arm <jim.flynn@arm.com> | 2019-11-29 17:01:45 +0000 |
commit | df31cfe29f9dccc4c2055a1d2a97de644b07d522 (patch) | |
tree | 15e848d398c35e669ecb0cff574907c4bd1662b9 /src/armnn | |
parent | a68d8530d3dcfc7c54b9c2bfa00b407f45145253 (diff) | |
download | armnn-df31cfe29f9dccc4c2055a1d2a97de644b07d522.tar.gz |
IVGCVSW-4070 Implement "send post-optimized network structure"
* Send post-optimisation network structure if profiling service is enabled
* Refactor TimelineUtilityMethods
* Fix RecordEvent to link eventGuid with eventClassGuid
* Add common types and guid to LabelsAndEventClasses
* Add CreateRelationship to TimelineUtilityMethods
* Add CreateTypedEntity to TimelineUtilityMethods
* Add MarkEntityWithType to TimelineUtilityMethods
* Move VerifyTimeline functions to ProfilingTestUtils
* Post-optimisation network structure unit tests to Ref, Cl, Neon
Signed-off-by: Narumol Prangnawarat <narumol.prangnawarat@arm.com>
Change-Id: I0194f2037c236450c912f4c3cb11e46b80c0f512
Diffstat (limited to 'src/armnn')
-rw-r--r-- | src/armnn/LoadedNetwork.cpp | 69 | ||||
-rw-r--r-- | src/armnn/test/RuntimeTests.cpp | 360 |
2 files changed, 428 insertions, 1 deletions
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp index e9a3545e35..36a56b044e 100644 --- a/src/armnn/LoadedNetwork.cpp +++ b/src/armnn/LoadedNetwork.cpp @@ -17,6 +17,9 @@ #include <backendsCommon/IMemoryManager.hpp> #include <backendsCommon/MemCopyWorkload.hpp> #include <backendsCommon/MemSyncWorkload.hpp> +#include <LabelsAndEventClasses.hpp> +#include <ProfilingService.hpp> +#include <TimelineUtilityMethods.hpp> #include <boost/polymorphic_cast.hpp> #include <boost/assert.hpp> @@ -27,6 +30,7 @@ namespace armnn { using namespace std; +using namespace armnn::profiling; namespace { @@ -39,6 +43,43 @@ std::string ToErrorMessage(const char * prefix, const ExceptionType & error) return ss.str(); } +void AddLayerStructure(std::unique_ptr<TimelineUtilityMethods>& timelineUtils, + const Layer& layer, + ProfilingGuid networkGuid) +{ + // Add layer to the post-optimisation network structure + std::string layerName = layer.GetNameStr().empty() ? "<Unnamed>" : layer.GetNameStr(); + timelineUtils->CreateNamedTypedChildEntity(layer.GetGuid(), + networkGuid, + layerName, + LabelsAndEventClasses::LAYER_GUID); + for (auto&& input : layer.GetInputSlots()) + { + const IOutputSlot* source = input.GetConnectedOutputSlot(); + BOOST_ASSERT(source != NULL); + timelineUtils->CreateConnectionRelationship(ProfilingRelationshipType::RetentionLink, + source->GetOwningLayerGuid(), + layer.GetGuid()); + } +} + +void AddWorkloadStructure(std::unique_ptr<TimelineUtilityMethods>& timelineUtils, + std::unique_ptr<IWorkload>& workload, + const Layer& layer) +{ + // Add workload to the post-optimisation network structure + timelineUtils->CreateTypedEntity(workload->GetGuid(), LabelsAndEventClasses::WORKLOAD_GUID); + timelineUtils->MarkEntityWithLabel(workload->GetGuid(), + layer.GetBackendId().Get(), + LabelsAndEventClasses::BACKENDID_GUID); + + // Link the workload to the layer + timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink, + layer.GetGuid(), + workload->GetGuid()); + +} + } // anonymous std::unique_ptr<LoadedNetwork> LoadedNetwork::MakeLoadedNetwork(std::unique_ptr<OptimizedNetwork> net, @@ -149,9 +190,22 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net, } } + ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid(); + std::unique_ptr<TimelineUtilityMethods> timelineUtils = TimelineUtilityMethods::GetTimelineUtils(); + if (timelineUtils) + { + timelineUtils->CreateTypedEntity(networkGuid, LabelsAndEventClasses::NETWORK_GUID); + } + //Then create workloads. for (auto&& layer : order) { + if (timelineUtils) + { + // Add layer to the post-optimisation network structure + AddLayerStructure(timelineUtils, *layer, networkGuid); + } + const IWorkloadFactory& workloadFactory = GetWorkloadFactory(*layer); switch (layer->GetType()) @@ -168,13 +222,20 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net, if (!workload) { - const char* const layerName = layer->GetNameStr().length() != 0 ? layer->GetName() : "<Unnamed>"; + const char* const layerName = + layer->GetNameStr().length() != 0 ? layer->GetName() : "<Unnamed>"; throw InvalidArgumentException(boost::str( boost::format("No workload created for layer (name: '%1%' type: '%2%') (compute '%3%')") % layerName % static_cast<int>(layer->GetType()) % layer->GetBackendId().Get() )); } + if (timelineUtils) + { + // Add workload to the post-optimisation network structure + AddWorkloadStructure(timelineUtils, workload, *layer); + } + m_WorkloadQueue.push_back(move(workload)); // release the constant data in the layer.. layer->ReleaseConstantData(); @@ -183,6 +244,12 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net, } } + if (timelineUtils) + { + // Commit to send the post-optimisation network structure + timelineUtils->Commit(); + } + // Set up memory. m_OptimizedNetwork->GetGraph().AllocateDynamicBuffers(); diff --git a/src/armnn/test/RuntimeTests.cpp b/src/armnn/test/RuntimeTests.cpp index 998808c508..f84f73d810 100644 --- a/src/armnn/test/RuntimeTests.cpp +++ b/src/armnn/test/RuntimeTests.cpp @@ -9,6 +9,9 @@ #include <Runtime.hpp> #include <armnn/TypesUtils.hpp> +#include <LabelsAndEventClasses.hpp> +#include <test/ProfilingTestUtils.hpp> + #include <HeapProfiling.hpp> #include <LeakChecking.hpp> @@ -17,6 +20,7 @@ #endif #include <boost/test/unit_test.hpp> +#include "RuntimeTests.hpp" namespace armnn { @@ -284,4 +288,360 @@ BOOST_AUTO_TEST_CASE(IVGCVSW_1929_QuantizedSoftmaxIssue) BOOST_TEST(!optNet); } +BOOST_AUTO_TEST_CASE(ProfilingDisable) +{ + using namespace armnn; + + // Create runtime in which the test will run + armnn::IRuntime::CreationOptions options; + armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options)); + + // build up the structure of the network + INetworkPtr net(INetwork::Create()); + + IConnectableLayer* input = net->AddInputLayer(0); + + // This layer configuration isn't supported by CpuAcc, should fall back to CpuRef. + NormalizationDescriptor descriptor; + IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor); + + IConnectableLayer* output = net->AddOutputLayer(0); + + input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0)); + normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0)); + + input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32)); + normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32)); + + // optimize the network + std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; + IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec()); + + // Load it into the runtime. It should succeed. + armnn::NetworkId netId; + BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet)) == Status::Success); + + profiling::ProfilingServiceRuntimeHelper profilingServiceHelper; + profiling::BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager(); + auto readableBuffer = bufferManager.GetReadableBuffer(); + + // Profiling is not enabled, the post-optimisation structure should not be created + BOOST_TEST(!readableBuffer); +} + +BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) +{ + using namespace armnn; + using namespace armnn::profiling; + + // Create runtime in which the test will run + armnn::IRuntime::CreationOptions options; + options.m_ProfilingOptions.m_EnableProfiling = true; + armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options)); + + // build up the structure of the network + INetworkPtr net(INetwork::Create()); + + IConnectableLayer* input = net->AddInputLayer(0, "input"); + + NormalizationDescriptor descriptor; + IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor, "normalization"); + + IConnectableLayer* output = net->AddOutputLayer(0, "output"); + + input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0)); + normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0)); + + input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32)); + normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32)); + + // optimize the network + std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; + IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec()); + + ProfilingGuid optNetGuid = optNet->GetGuid(); + + // Load it into the runtime. It should succeed. + armnn::NetworkId netId; + BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet)) == Status::Success); + + profiling::ProfilingServiceRuntimeHelper profilingServiceHelper; + profiling::BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager(); + auto readableBuffer = bufferManager.GetReadableBuffer(); + + // Profiling is enabled, the post-optimisation structure should be created + BOOST_CHECK(readableBuffer != nullptr); + + unsigned int size = readableBuffer->GetSize(); + BOOST_CHECK(size == 1356); + + const unsigned char* readableData = readableBuffer->GetReadableData(); + BOOST_CHECK(readableData != nullptr); + + unsigned int offset = 0; + + // Post-optimisation network + // Network entity + VerifyTimelineEntityBinaryPacket(optNetGuid, readableData, offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + optNetGuid, + LabelsAndEventClasses::NETWORK_GUID, + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Input layer + // Input layer entity + VerifyTimelineEntityBinaryPacket(input->GetGuid(), readableData, offset); + + // Name Entity + VerifyTimelineLabelBinaryPacket(EmptyOptional(), "input", readableData, offset); + + // Entity - Name relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + input->GetGuid(), + EmptyOptional(), + readableData, + offset); + + // Name label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::NAME_GUID, + readableData, + offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + input->GetGuid(), + EmptyOptional(), + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Network - Input layer relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + optNetGuid, + input->GetGuid(), + readableData, + offset); + + // Normalization layer + // Normalization layer entity + VerifyTimelineEntityBinaryPacket(normalize->GetGuid(), readableData, offset); + + // Name entity + VerifyTimelineLabelBinaryPacket(EmptyOptional(), "normalization", readableData, offset); + + // Entity - Name relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + normalize->GetGuid(), + EmptyOptional(), + readableData, + offset); + + // Name label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::NAME_GUID, + readableData, + offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + normalize->GetGuid(), + EmptyOptional(), + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Network - Normalize layer relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + optNetGuid, + normalize->GetGuid(), + readableData, + offset); + + // Input layer - Normalize layer relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + input->GetGuid(), + normalize->GetGuid(), + readableData, + offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::CONNECTION_GUID, + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Normalization workload + // Normalization workload entity + VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // BackendId entity + VerifyTimelineLabelBinaryPacket(EmptyOptional(), "CpuRef", readableData, offset); + + // Entity - BackendId relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // BackendId label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::BACKENDID_GUID, + readableData, + offset); + + // Normalize layer - Normalize workload relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + normalize->GetGuid(), + EmptyOptional(), + readableData, + offset); + + // Output layer + // Output layer entity + VerifyTimelineEntityBinaryPacket(output->GetGuid(), readableData, offset); + + // Name entity + VerifyTimelineLabelBinaryPacket(EmptyOptional(), "output", readableData, offset); + + // Entity - Name relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + output->GetGuid(), + EmptyOptional(), + readableData, + offset); + + // Name label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::NAME_GUID, + readableData, + offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + output->GetGuid(), + EmptyOptional(), + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Network - Output layer relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + optNetGuid, + output->GetGuid(), + readableData, + offset); + + // Normalize layer - Output layer relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + normalize->GetGuid(), + output->GetGuid(), + readableData, + offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::CONNECTION_GUID, + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + bufferManager.MarkRead(readableBuffer); +} + +BOOST_AUTO_TEST_CASE(ProfilingPostOptimisationStructureCpuRef) +{ + VerifyPostOptimisationStructureTestImpl(armnn::Compute::CpuRef); +} + BOOST_AUTO_TEST_SUITE_END() |