aboutsummaryrefslogtreecommitdiff
path: root/src/armnn
diff options
context:
space:
mode:
Diffstat (limited to 'src/armnn')
-rw-r--r--src/armnn/LoadedNetwork.cpp69
-rw-r--r--src/armnn/test/RuntimeTests.cpp360
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()