aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNarumol Prangnawarat <narumol.prangnawarat@arm.com>2019-11-15 17:38:44 +0000
committerNarumol Prangnawarat <narumol.prangnawarat@arm.com>2019-11-18 11:23:09 +0000
commitdbdd1b438815606bd423cbcfb95d51a3dd206683 (patch)
treef9a268f503b1f33a5e7e150e1ae041532bd8b94f
parentaad2fe41ad5111ad4cde6dc91a794f5f8f8b16f9 (diff)
downloadarmnn-dbdd1b438815606bd423cbcfb95d51a3dd206683.tar.gz
IVGCVSW-3980 Implementation of Guid generator
* Improve implementation of Guid Generator to separate the range of Static Guid and Dynamic Guid * Unit tests to ensure non-collision Signed-off-by: Narumol Prangnawarat <narumol.prangnawarat@arm.com> Change-Id: I4ad1a75ea0b1f37155da0decafb51fc5a61e4187
-rw-r--r--include/armnn/Types.hpp2
-rw-r--r--src/profiling/ProfilingGuidGenerator.hpp17
-rw-r--r--src/profiling/test/ProfilingGuidTest.cpp91
-rw-r--r--src/profiling/test/SendTimelinePacketTests.cpp13
-rw-r--r--src/profiling/test/TimelineUtilityMethodsTests.cpp27
5 files changed, 129 insertions, 21 deletions
diff --git a/include/armnn/Types.hpp b/include/armnn/Types.hpp
index 94f45302c7..4e80c3ccda 100644
--- a/include/armnn/Types.hpp
+++ b/include/armnn/Types.hpp
@@ -229,6 +229,8 @@ using DebugCallbackFunction = std::function<void(LayerGuid guid, unsigned int sl
namespace profiling
{
+static constexpr uint64_t MIN_STATIC_GUID = 1llu << 63;
+
class ProfilingGuid
{
public:
diff --git a/src/profiling/ProfilingGuidGenerator.hpp b/src/profiling/ProfilingGuidGenerator.hpp
index ad3159f201..97de4a88e5 100644
--- a/src/profiling/ProfilingGuidGenerator.hpp
+++ b/src/profiling/ProfilingGuidGenerator.hpp
@@ -22,25 +22,28 @@ public:
ProfilingGuidGenerator() : m_Sequence(0) {}
/// Return the next random Guid in the sequence
- // NOTE: dummy implementation for the moment
inline ProfilingDynamicGuid NextGuid() override
{
- // NOTE: skipping the zero for testing purposes
- ProfilingDynamicGuid guid(++m_Sequence);
+ ProfilingDynamicGuid guid(m_Sequence);
+ m_Sequence++;
+ if (m_Sequence >= MIN_STATIC_GUID)
+ {
+ // Reset the sequence to 0 when it reaches the upper bound of dynamic guid
+ m_Sequence = 0;
+ }
return guid;
}
/// Create a ProfilingStaticGuid based on a hash of the string
- // NOTE: dummy implementation for the moment
inline ProfilingStaticGuid GenerateStaticId(const std::string& str) override
{
- uint64_t guid = static_cast<uint64_t>(m_StringHasher(str));
- return guid;
+ uint64_t staticHash = m_Hash(str) | MIN_STATIC_GUID;
+ return ProfilingStaticGuid(staticHash);
}
private:
- std::hash<std::string> m_StringHasher;
uint64_t m_Sequence;
+ std::hash<std::string> m_Hash;
};
} // namespace profiling
diff --git a/src/profiling/test/ProfilingGuidTest.cpp b/src/profiling/test/ProfilingGuidTest.cpp
index f72cc1c452..c0dd986c8a 100644
--- a/src/profiling/test/ProfilingGuidTest.cpp
+++ b/src/profiling/test/ProfilingGuidTest.cpp
@@ -5,6 +5,11 @@
#include <armnn/Types.hpp>
+#include "LabelsAndEventClasses.hpp"
+#include "ProfilingGuidGenerator.hpp"
+
+#include <set>
+
#include <boost/test/unit_test.hpp>
using namespace armnn::profiling;
@@ -59,4 +64,90 @@ BOOST_AUTO_TEST_CASE(DynamicGuidTest)
BOOST_TEST(guid1 >= guid2);
}
+std::string GenerateRandomString()
+{
+ // Random a string lengh from 3 - 100
+ int minLength = 3;
+ int maxLength = 100;
+
+ // Random a character from lower case alphabets, upper case alphabets, numbers and special characters
+ int minAscii = 32; // space 32
+ int maxAscii = 126; // ~
+
+ int stringLen = rand() % (maxLength - minLength + 1) + minLength;
+ char str[stringLen + 1];
+ for (int i = 0; i < stringLen; ++i)
+ {
+ int randAscii = rand() % (maxAscii - minAscii + 1) + minAscii;
+ str[i] = char(randAscii);
+ }
+ str[stringLen] = '\0';
+ return std::string(str);
+}
+
+void CheckStaticGuid(uint64_t guid, uint64_t expectedGuid)
+{
+ BOOST_TEST(guid == expectedGuid);
+ BOOST_TEST(guid >= MIN_STATIC_GUID);
+}
+
+void CheckDynamicGuid(uint64_t guid, uint64_t expectedGuid)
+{
+ BOOST_TEST(guid == expectedGuid);
+ BOOST_TEST(guid < MIN_STATIC_GUID);
+}
+
+BOOST_AUTO_TEST_CASE(StaticGuidGeneratorCollisionTest)
+{
+ ProfilingGuidGenerator generator;
+ std::set<uint64_t> guids;
+ std::set<std::string> strs;
+ std::map<uint64_t,std::string> guidMap;
+ int collision = 0;
+ for (int i = 0; i < 1000000; ++i)
+ {
+ std::string str = GenerateRandomString();
+ if(strs.find(str) != strs.end())
+ {
+ continue;
+ }
+ strs.insert(str);
+ ProfilingStaticGuid guid = generator.GenerateStaticId(str.c_str());
+ if (guids.find(guid) != guids.end())
+ {
+ collision++;
+ }
+ guids.insert(guid);
+ }
+ BOOST_TEST(collision == 0);
+}
+
+BOOST_AUTO_TEST_CASE(StaticGuidGeneratorTest)
+{
+ ProfilingGuidGenerator generator;
+
+ ProfilingStaticGuid staticGuid0 = generator.GenerateStaticId("name");
+ CheckStaticGuid(staticGuid0, LabelsAndEventClasses::NAME_GUID);
+ BOOST_TEST(staticGuid0 != generator.GenerateStaticId("Name"));
+
+ ProfilingStaticGuid staticGuid1 = generator.GenerateStaticId("type");
+ CheckStaticGuid(staticGuid1, LabelsAndEventClasses::TYPE_GUID);
+ BOOST_TEST(staticGuid1 != generator.GenerateStaticId("Type"));
+
+ ProfilingStaticGuid staticGuid2 = generator.GenerateStaticId("index");
+ CheckStaticGuid(staticGuid2, LabelsAndEventClasses::INDEX_GUID);
+ BOOST_TEST(staticGuid2 != generator.GenerateStaticId("Index"));
+}
+
+BOOST_AUTO_TEST_CASE(DynamicGuidGeneratorTest)
+{
+ ProfilingGuidGenerator generator;
+
+ for (unsigned int i = 0; i < 100; ++i)
+ {
+ ProfilingDynamicGuid guid = generator.NextGuid();
+ CheckDynamicGuid(guid, i);
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/profiling/test/SendTimelinePacketTests.cpp b/src/profiling/test/SendTimelinePacketTests.cpp
index 26b49dfb18..771e117955 100644
--- a/src/profiling/test/SendTimelinePacketTests.cpp
+++ b/src/profiling/test/SendTimelinePacketTests.cpp
@@ -415,10 +415,9 @@ BOOST_AUTO_TEST_CASE(GetGuidsFromProfilingService)
ProfilingService& profilingService = ProfilingService::Instance();
profilingService.ResetExternalProfilingOptions(options, true);
ProfilingStaticGuid staticGuid = profilingService.GenerateStaticId("dummy");
- // TODO this will change again...
std::hash<std::string> hasher;
uint64_t hash = static_cast<uint64_t>(hasher("dummy"));
- ProfilingStaticGuid expectedStaticValue(hash);
+ ProfilingStaticGuid expectedStaticValue(hash | MIN_STATIC_GUID);
BOOST_CHECK(staticGuid == expectedStaticValue);
ProfilingDynamicGuid dynamicGuid = profilingService.NextGuid();
uint64_t dynamicGuidValue = static_cast<uint64_t>(dynamicGuid);
@@ -448,23 +447,23 @@ BOOST_AUTO_TEST_CASE(CheckStaticGuidsAndEvents)
std::hash<std::string> hasher;
uint64_t hash = static_cast<uint64_t>(hasher(LabelsAndEventClasses::NAME_LABEL));
- ProfilingStaticGuid expectedNameGuid(hash);
+ ProfilingStaticGuid expectedNameGuid(hash | MIN_STATIC_GUID);
BOOST_CHECK(LabelsAndEventClasses::NAME_GUID == expectedNameGuid);
hash = static_cast<uint64_t>(hasher(LabelsAndEventClasses::TYPE_LABEL));
- ProfilingStaticGuid expectedTypeGuid(hash);
+ ProfilingStaticGuid expectedTypeGuid(hash | MIN_STATIC_GUID);
BOOST_CHECK(LabelsAndEventClasses::TYPE_GUID == expectedTypeGuid);
hash = static_cast<uint64_t>(hasher(LabelsAndEventClasses::INDEX_LABEL));
- ProfilingStaticGuid expectedIndexGuid(hash);
+ ProfilingStaticGuid expectedIndexGuid(hash | MIN_STATIC_GUID);
BOOST_CHECK(LabelsAndEventClasses::INDEX_GUID == expectedIndexGuid);
hash = static_cast<uint64_t>(hasher("ARMNN_PROFILING_SOL"));
- ProfilingStaticGuid expectedSol(hash);
+ ProfilingStaticGuid expectedSol(hash | MIN_STATIC_GUID);
BOOST_CHECK(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS == expectedSol);
hash = static_cast<uint64_t>(hasher("ARMNN_PROFILING_EOL"));
- ProfilingStaticGuid expectedEol(hash);
+ ProfilingStaticGuid expectedEol(hash | MIN_STATIC_GUID);
BOOST_CHECK(LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS == expectedEol);
}
diff --git a/src/profiling/test/TimelineUtilityMethodsTests.cpp b/src/profiling/test/TimelineUtilityMethodsTests.cpp
index f784afc6ef..2eb96e62d1 100644
--- a/src/profiling/test/TimelineUtilityMethodsTests.cpp
+++ b/src/profiling/test/TimelineUtilityMethodsTests.cpp
@@ -368,6 +368,9 @@ BOOST_AUTO_TEST_CASE(CreateTypedLabelTest)
SendTimelinePacket sendTimelinePacket(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
+ // Generate first guid to ensure that the named typed entity guid is not 0 on local single test.
+ ProfilingService::Instance().NextGuid();
+
ProfilingGuid entityGuid(123);
const std::string entityName = "some entity";
ProfilingStaticGuid labelTypeGuid(456);
@@ -475,6 +478,9 @@ BOOST_AUTO_TEST_CASE(CreateNamedTypedChildEntityTest)
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::Instance().NextGuid();
+
BOOST_CHECK_THROW(timelineUtilityMethods.CreateNamedTypedChildEntity(parentEntityGuid, "", entityType),
InvalidArgumentException);
BOOST_CHECK_THROW(timelineUtilityMethods.CreateNamedTypedChildEntity(parentEntityGuid, entityName, ""),
@@ -559,6 +565,9 @@ BOOST_AUTO_TEST_CASE(DeclareLabelTest)
SendTimelinePacket sendTimelinePacket(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
+ // Generate first guid to ensure that the named typed entity guid is not 0 on local single test.
+ ProfilingService::Instance().NextGuid();
+
// Try declaring an invalid (empty) label
BOOST_CHECK_THROW(timelineUtilityMethods.DeclareLabel(""), InvalidArgumentException);
@@ -569,15 +578,13 @@ BOOST_AUTO_TEST_CASE(DeclareLabelTest)
const std::string labelName = "valid label";
ProfilingGuid labelGuid = 0;
BOOST_CHECK_NO_THROW(labelGuid = timelineUtilityMethods.DeclareLabel(labelName));
- // TODO when the implementation of the profiling GUID generator is done, enable the following test
- //BOOST_CHECK(labelGuid != ProfilingGuid(0));
+ BOOST_CHECK(labelGuid != ProfilingGuid(0));
- // TODO when the implementation of the profiling GUID generator is done, enable the following tests
// Try adding the same label as before
- //ProfilingGuid newLabelGuid = 0;
- //BOOST_CHECK_NO_THROW(labelGuid = timelineUtilityMethods.DeclareLabel(labelName));
- //BOOST_CHECK(newLabelGuid != ProfilingGuid(0));
- //BOOST_CHECK(newLabelGuid == labelGuid);
+ ProfilingGuid newLabelGuid = 0;
+ BOOST_CHECK_NO_THROW(newLabelGuid = timelineUtilityMethods.DeclareLabel(labelName));
+ BOOST_CHECK(newLabelGuid != ProfilingGuid(0));
+ BOOST_CHECK(newLabelGuid == labelGuid);
}
BOOST_AUTO_TEST_CASE(CreateNameTypeEntityInvalidTest)
@@ -603,6 +610,9 @@ BOOST_AUTO_TEST_CASE(CreateNameTypeEntityTest)
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::Instance().NextGuid();
+
ProfilingDynamicGuid guid = timelineUtilityMethods.CreateNamedTypedEntity(entityName, entityType);
BOOST_CHECK(guid != ProfilingGuid(0));
@@ -673,6 +683,9 @@ BOOST_AUTO_TEST_CASE(RecordEventTest)
SendTimelinePacket sendTimelinePacket(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
+ // Generate first guid to ensure that the named typed entity guid is not 0 on local single test.
+ ProfilingService::Instance().NextGuid();
+
ProfilingGuid entityGuid(123);
ProfilingStaticGuid eventClassGuid(456);
ProfilingDynamicGuid eventGuid(0);