aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Murtagh <francis.murtagh@arm.com>2021-02-15 10:11:28 +0000
committerKeithARM <keith.davis@arm.com>2021-02-15 15:10:09 +0000
commit33199c25e5af1553e474a6f6eede07e888cd45ee (patch)
tree4d7980289479f83eb0cae81a460fb71a184f6dc9
parent406463269f55a5baefb941b51e10f423f6d3250a (diff)
downloadarmnn-33199c25e5af1553e474a6f6eede07e888cd45ee.tar.gz
IVGCVSW-5675 Implement Pimpl Idiom for IProfiler (lower priority)
Signed-off-by: Francis Murtagh <francis.murtagh@arm.com> Change-Id: If716f5f4e9b5433586b8a939d326830482da2f74
-rw-r--r--include/armnn/IProfiler.hpp29
-rw-r--r--src/armnn/LoadedNetwork.cpp2
-rw-r--r--src/armnn/LoadedNetwork.hpp4
-rw-r--r--src/armnn/Profiling.cpp68
-rw-r--r--src/armnn/Profiling.hpp32
-rw-r--r--src/armnn/ProfilingEvent.cpp4
-rw-r--r--src/armnn/ProfilingEvent.hpp8
-rw-r--r--src/armnn/test/ProfilerTests.cpp14
-rw-r--r--src/armnn/test/UnitTests.hpp4
-rw-r--r--src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp2
-rw-r--r--tests/InferenceTest.cpp2
11 files changed, 109 insertions, 60 deletions
diff --git a/include/armnn/IProfiler.hpp b/include/armnn/IProfiler.hpp
index 5e6f5087ca..ac422b714f 100644
--- a/include/armnn/IProfiler.hpp
+++ b/include/armnn/IProfiler.hpp
@@ -6,33 +6,50 @@
#pragma once
#include <iostream>
+#include <memory>
+#include <vector>
namespace armnn
{
+class ProfilerImpl;
+class BackendId;
+class Instrument;
+class Event;
class IProfiler
{
public:
/// Enables/disables profiling for this profiler.
/// @param [in] enableProfiling A flag that indicates whether profiling should be enabled or not.
- virtual void EnableProfiling(bool enableProfiling) = 0;
+ void EnableProfiling(bool enableProfiling);
/// Checks whether profiling is enabled.
/// Profiling is disabled by default.
/// @return true if profiling is enabled, false otherwise.
- virtual bool IsProfilingEnabled() = 0;
+ bool IsProfilingEnabled();
/// Analyzes the tracked events and writes the results to the given output stream.
/// Please refer to the configuration variables in Profiling.cpp to customize the information written.
/// @param [out] outStream The stream where to write the profiling results to.
- virtual void AnalyzeEventsAndWriteResults(std::ostream& outStream) const = 0;
+ void AnalyzeEventsAndWriteResults(std::ostream& outStream) const;
/// Print stats for events in JSON Format to the given output stream.
/// @param [out] outStream The stream where to write the profiling results to.
- virtual void Print(std::ostream& outStream) const = 0;
+ void Print(std::ostream& outStream) const;
-protected:
- ~IProfiler() {}
+ ~IProfiler();
+ IProfiler();
+
+private:
+ using InstrumentPtr = std::unique_ptr<Instrument>;
+ Event* BeginEvent(const BackendId& backendId,
+ const std::string& label,
+ std::vector<InstrumentPtr>&& instruments);
+ std::unique_ptr<ProfilerImpl> pProfilerImpl;
+ friend class ScopedProfilingEvent;
+
+ // Friend functions for unit testing, see ProfilerTests.cpp.
+ friend size_t GetProfilerEventSequenceSize(armnn::IProfiler* profiler);
};
} // namespace armnn
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp
index f85191059c..4a307e2e04 100644
--- a/src/armnn/LoadedNetwork.cpp
+++ b/src/armnn/LoadedNetwork.cpp
@@ -125,7 +125,7 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net,
m_ProfilingService(profilingService)
{
// Create a profiler and register it for the current thread.
- m_Profiler = std::make_shared<Profiler>();
+ m_Profiler = std::make_shared<IProfiler>();
ProfilerManager::GetInstance().RegisterProfiler(m_Profiler.get());
Graph& order = m_OptimizedNetwork->GetGraph().TopologicalSort();
diff --git a/src/armnn/LoadedNetwork.hpp b/src/armnn/LoadedNetwork.hpp
index 39b6089ac9..3a44206683 100644
--- a/src/armnn/LoadedNetwork.hpp
+++ b/src/armnn/LoadedNetwork.hpp
@@ -50,7 +50,7 @@ public:
// NOTE we return by reference as the purpose of this method is only to provide
// access to the private m_Profiler and in theory we should not need to increment
// the shared_ptr's reference counter
- const std::shared_ptr<Profiler>& GetProfiler() const { return m_Profiler; }
+ const std::shared_ptr<IProfiler>& GetProfiler() const { return m_Profiler; }
void FreeWorkingMemory();
@@ -91,7 +91,7 @@ private:
WorkloadQueue m_InputQueue;
WorkloadQueue m_WorkloadQueue;
WorkloadQueue m_OutputQueue;
- std::shared_ptr<Profiler> m_Profiler;
+ std::shared_ptr<IProfiler> m_Profiler;
mutable std::mutex m_WorkingMemMutex;
diff --git a/src/armnn/Profiling.cpp b/src/armnn/Profiling.cpp
index 1cdf30cbdf..c30b482888 100644
--- a/src/armnn/Profiling.cpp
+++ b/src/armnn/Profiling.cpp
@@ -80,7 +80,7 @@ std::vector<Measurement> FindKernelMeasurements(const Event* event)
return measurements;
}
-std::map<std::string, Profiler::ProfilingEventStats> Profiler::CalculateProfilingEventStats() const
+std::map<std::string, ProfilerImpl::ProfilingEventStats> ProfilerImpl::CalculateProfilingEventStats() const
{
std::map<std::string, ProfilingEventStats> nameToStatsMap;
@@ -111,7 +111,7 @@ const Event* GetEventPtr(const Event* ptr) { return ptr;}
const Event* GetEventPtr(const std::unique_ptr<Event>& ptr) {return ptr.get(); }
template<typename ItertType>
-void Profiler::AnalyzeEventSequenceAndWriteResults(ItertType first, ItertType last, std::ostream& outStream) const
+void ProfilerImpl::AnalyzeEventSequenceAndWriteResults(ItertType first, ItertType last, std::ostream& outStream) const
{
// Outputs event sequence, if needed.
if (g_WriteProfilingEventSequence)
@@ -162,7 +162,7 @@ void Profiler::AnalyzeEventSequenceAndWriteResults(ItertType first, ItertType la
outStream << std::endl;
}
-Profiler::Profiler()
+ProfilerImpl::ProfilerImpl()
: m_ProfilingEnabled(false)
{
m_EventSequence.reserve(g_ProfilingEventCountHint);
@@ -173,7 +173,7 @@ Profiler::Profiler()
#endif
}
-Profiler::~Profiler()
+ProfilerImpl::~ProfilerImpl()
{
if (m_ProfilingEnabled)
{
@@ -187,22 +187,23 @@ Profiler::~Profiler()
ProfilerManager::GetInstance().RegisterProfiler(nullptr);
}
-bool Profiler::IsProfilingEnabled()
+bool ProfilerImpl::IsProfilingEnabled()
{
return m_ProfilingEnabled;
}
-void Profiler::EnableProfiling(bool enableProfiling)
+void ProfilerImpl::EnableProfiling(bool enableProfiling)
{
m_ProfilingEnabled = enableProfiling;
}
-Event* Profiler::BeginEvent(const BackendId& backendId,
+Event* ProfilerImpl::BeginEvent(armnn::IProfiler* profiler,
+ const BackendId& backendId,
const std::string& label,
std::vector<InstrumentPtr>&& instruments)
{
Event* parent = m_Parents.empty() ? nullptr : m_Parents.top();
- m_EventSequence.push_back(std::make_unique<Event>(label, this, parent, backendId, std::move(instruments)));
+ m_EventSequence.push_back(std::make_unique<Event>(label, profiler, parent, backendId, std::move(instruments)));
Event* event = m_EventSequence.back().get();
event->Start();
@@ -214,7 +215,7 @@ Event* Profiler::BeginEvent(const BackendId& backendId,
return event;
}
-void Profiler::EndEvent(Event* event)
+void ProfilerImpl::EndEvent(Event* event)
{
event->Stop();
@@ -242,7 +243,7 @@ int CalcLevel(const Event* eventPtr)
return level;
}
-void Profiler::PopulateInferences(std::vector<const Event*>& outInferences, int& outBaseLevel) const
+void ProfilerImpl::PopulateInferences(std::vector<const Event*>& outInferences, int& outBaseLevel) const
{
outInferences.reserve(m_EventSequence.size());
for (const auto& event : m_EventSequence)
@@ -256,7 +257,7 @@ void Profiler::PopulateInferences(std::vector<const Event*>& outInferences, int&
}
}
-void Profiler::PopulateDescendants(std::map<const Event*, std::vector<const Event*>>& outDescendantsMap) const
+void ProfilerImpl::PopulateDescendants(std::map<const Event*, std::vector<const Event*>>& outDescendantsMap) const
{
for (const auto& event : m_EventSequence)
{
@@ -327,7 +328,7 @@ void ExtractJsonObjects(unsigned int inferenceIndex,
}
}
-void Profiler::Print(std::ostream& outStream) const
+void ProfilerImpl::Print(std::ostream& outStream) const
{
// Makes sure timestamps are output with 6 decimals, and save old settings.
std::streamsize oldPrecision = outStream.precision();
@@ -377,7 +378,7 @@ void Profiler::Print(std::ostream& outStream) const
outStream.precision(oldPrecision);
}
-void Profiler::AnalyzeEventsAndWriteResults(std::ostream& outStream) const
+void ProfilerImpl::AnalyzeEventsAndWriteResults(std::ostream& outStream) const
{
// Stack should be empty now.
const bool saneMarkerSequence = m_Parents.empty();
@@ -460,7 +461,7 @@ void Profiler::AnalyzeEventsAndWriteResults(std::ostream& outStream) const
}
}
-std::uint32_t Profiler::GetEventColor(const BackendId& backendId) const
+std::uint32_t ProfilerImpl::GetEventColor(const BackendId& backendId) const
{
static BackendId cpuRef("CpuRef");
static BackendId cpuAcc("CpuAcc");
@@ -481,7 +482,9 @@ std::uint32_t Profiler::GetEventColor(const BackendId& backendId) const
}
// The thread_local pointer to the profiler instance.
-thread_local Profiler* tl_Profiler = nullptr;
+thread_local IProfiler* tl_Profiler = nullptr;
+
+
ProfilerManager& ProfilerManager::GetInstance()
{
@@ -490,14 +493,45 @@ ProfilerManager& ProfilerManager::GetInstance()
return s_ProfilerManager;
}
-void ProfilerManager::RegisterProfiler(Profiler* profiler)
+void ProfilerManager::RegisterProfiler(IProfiler* profiler)
{
tl_Profiler = profiler;
}
-Profiler* ProfilerManager::GetProfiler()
+IProfiler* ProfilerManager::GetProfiler()
{
return tl_Profiler;
}
+
+void IProfiler::EnableProfiling(bool enableProfiling)
+{
+ pProfilerImpl->EnableProfiling(enableProfiling);
+}
+
+bool IProfiler::IsProfilingEnabled()
+{
+ return pProfilerImpl->IsProfilingEnabled();
+}
+
+void IProfiler::AnalyzeEventsAndWriteResults(std::ostream& outStream) const
+{
+ pProfilerImpl->AnalyzeEventsAndWriteResults(outStream);
+}
+
+void IProfiler::Print(std::ostream& outStream) const
+{
+ pProfilerImpl->Print(outStream);
+}
+
+Event* IProfiler::BeginEvent(const BackendId& backendId,
+ const std::string& label,
+ std::vector<InstrumentPtr>&& instruments)
+{
+ return pProfilerImpl->BeginEvent(this, backendId, label, std::move(instruments));
+}
+
+IProfiler::~IProfiler() = default;
+IProfiler::IProfiler() : pProfilerImpl(new ProfilerImpl()) {};
+
} // namespace armnn
diff --git a/src/armnn/Profiling.hpp b/src/armnn/Profiling.hpp
index c0d37dc13e..d134425b6c 100644
--- a/src/armnn/Profiling.hpp
+++ b/src/armnn/Profiling.hpp
@@ -24,40 +24,42 @@ namespace armnn
// Simple single-threaded profiler.
// Tracks events reported by BeginEvent()/EndEvent() and outputs detailed information and stats when
// Profiler::AnalyzeEventsAndWriteResults() is called.
-class Profiler final : public IProfiler
+class ProfilerImpl
{
public:
- Profiler();
- ~Profiler();
+ ProfilerImpl();
+ ~ProfilerImpl();
using InstrumentPtr = std::unique_ptr<Instrument>;
// Marks the beginning of a user-defined event.
// No attempt will be made to copy the name string: it must be known at compile time.
- Event* BeginEvent(const BackendId& backendId, const std::string& name, std::vector<InstrumentPtr>&& instruments);
+ Event* BeginEvent(armnn::IProfiler* profiler,
+ const BackendId& backendId,
+ const std::string& name,
+ std::vector<InstrumentPtr>&& instruments);
// Marks the end of a user-defined event.
void EndEvent(Event* event);
// Enables/disables profiling.
- void EnableProfiling(bool enableProfiling) override;
+ void EnableProfiling(bool enableProfiling);
// Checks if profiling is enabled.
- bool IsProfilingEnabled() override;
+ bool IsProfilingEnabled();
// Increments the event tag, allowing grouping of events in a user-defined manner (e.g. per inference).
void UpdateEventTag();
// Analyzes the tracked events and writes the results to the given output stream.
// Please refer to the configuration variables in Profiling.cpp to customize the information written.
- void AnalyzeEventsAndWriteResults(std::ostream& outStream) const override;
+ void AnalyzeEventsAndWriteResults(std::ostream& outStream) const;
// Print stats for events in JSON Format to the given output stream.
- void Print(std::ostream& outStream) const override;
+ void Print(std::ostream& outStream) const;
// Gets the color to render an event with, based on which device it denotes.
uint32_t GetEventColor(const BackendId& backendId) const;
-private:
using EventPtr = std::unique_ptr<Event>;
struct Marker
{
@@ -82,10 +84,6 @@ private:
std::stack<Event*> m_Parents;
std::vector<EventPtr> m_EventSequence;
bool m_ProfilingEnabled;
-
-private:
- // Friend functions for unit testing, see ProfilerTests.cpp.
- friend size_t GetProfilerEventSequenceSize(armnn::Profiler* profiler);
};
// Singleton profiler manager.
@@ -94,10 +92,10 @@ class ProfilerManager
{
public:
// Register the given profiler as a thread local pointer.
- void RegisterProfiler(Profiler* profiler);
+ void RegisterProfiler(IProfiler* profiler);
// Gets the thread local pointer to the profiler.
- Profiler* GetProfiler();
+ IProfiler* GetProfiler();
// Accesses the singleton.
static ProfilerManager& GetInstance();
@@ -132,7 +130,7 @@ public:
{
if (m_Profiler && m_Event)
{
- m_Profiler->EndEvent(m_Event);
+ m_Profiler->pProfilerImpl->EndEvent(m_Event);
}
}
@@ -151,7 +149,7 @@ private:
}
Event* m_Event; ///< Event to track
- Profiler* m_Profiler; ///< Profiler used
+ IProfiler* m_Profiler; ///< Profiler used
};
} // namespace armnn
diff --git a/src/armnn/ProfilingEvent.cpp b/src/armnn/ProfilingEvent.cpp
index 60fb2f79c6..1ba9789034 100644
--- a/src/armnn/ProfilingEvent.cpp
+++ b/src/armnn/ProfilingEvent.cpp
@@ -9,7 +9,7 @@
namespace armnn
{
Event::Event(const std::string& eventName,
- Profiler* profiler,
+ IProfiler* profiler,
Event* parent,
const BackendId backendId,
std::vector<InstrumentPtr>&& instruments)
@@ -69,7 +69,7 @@ const std::string& Event::GetName() const
return m_EventName;
}
-const Profiler* Event::GetProfiler() const
+const IProfiler* Event::GetProfiler() const
{
return m_Profiler;
}
diff --git a/src/armnn/ProfilingEvent.hpp b/src/armnn/ProfilingEvent.hpp
index 9f57753585..7afd5c100c 100644
--- a/src/armnn/ProfilingEvent.hpp
+++ b/src/armnn/ProfilingEvent.hpp
@@ -16,7 +16,7 @@ namespace armnn
{
/// Forward declaration
-class Profiler;
+class IProfiler;
/// Event class records measurements reported by BeginEvent()/EndEvent() and returns measurements when
/// Event::GetMeasurements() is called.
@@ -27,7 +27,7 @@ public:
using Instruments = std::vector<InstrumentPtr>;
Event(const std::string& eventName,
- Profiler* profiler,
+ IProfiler* profiler,
Event* parent,
const BackendId backendId,
std::vector<InstrumentPtr>&& instrument);
@@ -56,7 +56,7 @@ public:
/// Get the pointer of the profiler associated with this event
/// \return Pointer of the profiler associated with this event
- const Profiler* GetProfiler() const;
+ const IProfiler* GetProfiler() const;
/// Get the pointer of the parent event
/// \return Pointer of the parent event
@@ -77,7 +77,7 @@ private:
std::string m_EventName;
/// Stored associated profiler
- Profiler* m_Profiler;
+ IProfiler* m_Profiler;
/// Stores optional parent event
Event* m_Parent;
diff --git a/src/armnn/test/ProfilerTests.cpp b/src/armnn/test/ProfilerTests.cpp
index 7bd258e430..a0df3b6b62 100644
--- a/src/armnn/test/ProfilerTests.cpp
+++ b/src/armnn/test/ProfilerTests.cpp
@@ -19,14 +19,14 @@
namespace armnn
{
-size_t GetProfilerEventSequenceSize(armnn::Profiler* profiler)
+size_t GetProfilerEventSequenceSize(armnn::IProfiler* profiler)
{
if (!profiler)
{
return static_cast<size_t>(-1);
}
- return profiler->m_EventSequence.size();
+ return profiler->pProfilerImpl->m_EventSequence.size();
}
} // namespace armnn
@@ -45,7 +45,7 @@ void RegisterUnregisterProfilerSingleThreadImpl(bool &res)
res = !profilerManager.GetProfiler();
// Create and register a profiler for this thread.
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
profilerManager.RegisterProfiler(profiler.get());
// Check that on a single thread we get the same profiler we registered.
@@ -66,7 +66,7 @@ BOOST_AUTO_TEST_SUITE(Profiler)
BOOST_AUTO_TEST_CASE(EnableDisableProfiling)
{
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
// Check that profiling is disabled by default.
BOOST_TEST(!profiler->IsProfilingEnabled());
@@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(ProfilingMacros)
}
// Create and register a profiler for this thread.
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
profilerManager.RegisterProfiler(profiler.get());
{ // --- Profiler, but profiling disabled ---
@@ -201,7 +201,7 @@ BOOST_AUTO_TEST_CASE(WriteEventResults)
armnn::ProfilerManager& profileManager = armnn::ProfilerManager::GetInstance();
// Create and register a profiler for this thread.
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
profileManager.RegisterProfiler(profiler.get());
// Enable profiling.
@@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(ProfilerJsonPrinter)
armnn::ProfilerManager& profilerManager = armnn::ProfilerManager::GetInstance();
// Create and register a profiler for this thread.
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
profilerManager.RegisterProfiler(profiler.get());
profiler->EnableProfiling(true);
diff --git a/src/armnn/test/UnitTests.hpp b/src/armnn/test/UnitTests.hpp
index e0505c9a9f..c15477bf19 100644
--- a/src/armnn/test/UnitTests.hpp
+++ b/src/armnn/test/UnitTests.hpp
@@ -64,7 +64,7 @@ void CompareTestResultIfSupported(const std::string& testName, const std::vector
template<typename FactoryType, typename TFuncPtr, typename... Args>
void RunTestFunction(const char* testName, TFuncPtr testFunction, Args... args)
{
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
@@ -80,7 +80,7 @@ void RunTestFunction(const char* testName, TFuncPtr testFunction, Args... args)
template<typename FactoryType, typename TFuncPtr, typename... Args>
void RunTestFunctionUsingTensorHandleFactory(const char* testName, TFuncPtr testFunction, Args... args)
{
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
diff --git a/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp
index 34ff31effc..3ee1fadd81 100644
--- a/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp
@@ -148,7 +148,7 @@ void DetectionPostProcessImpl(const armnn::TensorInfo& boxEncodingsInfo,
const std::vector<float>& expectedNumDetections,
bool useRegularNms)
{
- std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+ std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
diff --git a/tests/InferenceTest.cpp b/tests/InferenceTest.cpp
index 3392f6ea51..e31e7dc6fb 100644
--- a/tests/InferenceTest.cpp
+++ b/tests/InferenceTest.cpp
@@ -142,7 +142,7 @@ bool InferenceTest(const InferenceTestOptions& params,
}
// Create a profiler and register it for the current thread.
- std::unique_ptr<Profiler> profiler = std::make_unique<Profiler>();
+ std::unique_ptr<IProfiler> profiler = std::make_unique<IProfiler>();
ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
// Enable profiling if requested.