aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Flynn <jim.flynn@arm.com>2019-12-13 14:43:24 +0000
committerTeresaARM <teresa.charlinreyes@arm.com>2020-01-24 14:49:52 +0000
commit829ad30a4f13bc0b9cb32bab5a4efeeeab541f76 (patch)
tree21fcbeca2f1f94c6a82863ae52aa8aa536f53106
parent1bde8e31935ac375fd0aaa0dfddb0f7851c16087 (diff)
downloadandroid-nn-driver-829ad30a4f13bc0b9cb32bab5a4efeeeab541f76.tar.gz
IVGCVSW-4270 Change .dot file name to start with netId
* .dot file will start with the same number as the associated input and output tensor dump files Change-Id: Ic64539854c2b8c34a7034fa18a142b2dfe67df7d Signed-off-by: Jim Flynn <jim.flynn@arm.com> IVGCVSW-4271 Add getSupportedOperations marker file * Also fix segfault in previous graph dump code Change-Id: I01915f47ae17d89ad3595430d073a17b1a1fda58 Signed-off-by: Jim Flynn <jim.flynn@arm.com>
-rw-r--r--1.2/ArmnnDriver.hpp2
-rw-r--r--1.2/ArmnnDriverImpl.cpp10
-rw-r--r--ArmnnDriverImpl.cpp34
-rw-r--r--Utils.cpp89
-rw-r--r--Utils.hpp43
-rw-r--r--test/UtilsTests.cpp57
6 files changed, 160 insertions, 75 deletions
diff --git a/1.2/ArmnnDriver.hpp b/1.2/ArmnnDriver.hpp
index 40116c8a..177cab63 100644
--- a/1.2/ArmnnDriver.hpp
+++ b/1.2/ArmnnDriver.hpp
@@ -119,7 +119,7 @@ public:
Return<void> getVersionString(getVersionString_cb cb)
{
- ALOGV("hal_1_2::ArmnnDriver::getSupportedOperations()");
+ ALOGV("hal_1_2::ArmnnDriver::getVersionString()");
cb(ErrorStatus::NONE, "ArmNN");
return Void();
diff --git a/1.2/ArmnnDriverImpl.cpp b/1.2/ArmnnDriverImpl.cpp
index d369aa27..691156fa 100644
--- a/1.2/ArmnnDriverImpl.cpp
+++ b/1.2/ArmnnDriverImpl.cpp
@@ -161,8 +161,8 @@ Return<ErrorStatus> ArmnnDriverImpl::prepareArmnnModel_1_2(const armnn::IRuntime
// Export the optimized network graph to a dot file if an output dump directory
// has been specified in the drivers' arguments.
- ExportNetworkGraphToDotFile<hal_1_2::HalPolicy::Model>(*optNet, options.GetRequestInputsAndOutputsDumpDir(),
- model);
+ std::string dotGraphFileName = ExportNetworkGraphToDotFile(*optNet,
+ options.GetRequestInputsAndOutputsDumpDir());
// Load it into the runtime.
armnn::NetworkId netId = 0;
@@ -181,6 +181,12 @@ Return<ErrorStatus> ArmnnDriverImpl::prepareArmnnModel_1_2(const armnn::IRuntime
return ErrorStatus::NONE;
}
+ // Now that we have a networkId for the graph rename the dump file to use it
+ // so that we can associate the graph file and the input/output tensor dump files
+ RenameGraphDotFile(dotGraphFileName,
+ options.GetRequestInputsAndOutputsDumpDir(),
+ netId);
+
std::unique_ptr<ArmnnPreparedModel_1_2<hal_1_2::HalPolicy>> preparedModel(
new ArmnnPreparedModel_1_2<hal_1_2::HalPolicy>(
netId,
diff --git a/ArmnnDriverImpl.cpp b/ArmnnDriverImpl.cpp
index 9fe2c0e7..14af3c06 100644
--- a/ArmnnDriverImpl.cpp
+++ b/ArmnnDriverImpl.cpp
@@ -131,7 +131,7 @@ Return<ErrorStatus> ArmnnDriverImpl<HalPolicy>::prepareModel(
// Export the optimized network graph to a dot file if an output dump directory
// has been specified in the drivers' arguments.
- ExportNetworkGraphToDotFile<HalModel>(*optNet, options.GetRequestInputsAndOutputsDumpDir(), model);
+ std::string dotGraphFileName = ExportNetworkGraphToDotFile(*optNet, options.GetRequestInputsAndOutputsDumpDir());
// Load it into the runtime.
armnn::NetworkId netId = 0;
@@ -150,6 +150,12 @@ Return<ErrorStatus> ArmnnDriverImpl<HalPolicy>::prepareModel(
return ErrorStatus::NONE;
}
+ // Now that we have a networkId for the graph rename the dump file to use it
+ // so that we can associate the graph file and the input/output tensor dump files
+ RenameGraphDotFile(dotGraphFileName,
+ options.GetRequestInputsAndOutputsDumpDir(),
+ netId);
+
sp<ArmnnPreparedModel<HalPolicy>> preparedModel(
new ArmnnPreparedModel<HalPolicy>(
netId,
@@ -191,7 +197,31 @@ Return<void> ArmnnDriverImpl<HalPolicy>::getSupportedOperations(const armnn::IRu
const HalModel& model,
HalGetSupportedOperations_cb cb)
{
- ALOGV("ArmnnDriverImpl::getSupportedOperations()");
+ std::stringstream ss;
+ ss << "ArmnnDriverImpl::getSupportedOperations()";
+ std::string fileName;
+ std::string timestamp;
+ if (!options.GetRequestInputsAndOutputsDumpDir().empty())
+ {
+ timestamp = GetFileTimestamp();
+ fileName = boost::str(boost::format("%1%/%2%_getSupportedOperations.txt")
+ % options.GetRequestInputsAndOutputsDumpDir()
+ % timestamp);
+ ss << " : " << fileName;
+ }
+ ALOGV(ss.str().c_str());
+
+ if (!options.GetRequestInputsAndOutputsDumpDir().empty())
+ {
+ //dump the marker file
+ std::ofstream fileStream;
+ fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);
+ if (fileStream.good())
+ {
+ fileStream << timestamp << std::endl;
+ }
+ fileStream.close();
+ }
vector<bool> result;
diff --git a/Utils.cpp b/Utils.cpp
index 6ee025e6..3583d62d 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -13,7 +13,13 @@
#include <armnn/Utils.hpp>
#include <cassert>
+#include <cerrno>
#include <cinttypes>
+#include <sstream>
+#include <cstdio>
+#include <time.h>
+
+
using namespace android;
using namespace android::hardware;
@@ -359,10 +365,93 @@ void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
profiler->Print(fileStream);
}
+std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
+ const std::string& dumpDir)
+{
+ std::string fileName;
+ // The dump directory must exist in advance.
+ if (dumpDir.empty())
+ {
+ return fileName;
+ }
+
+ std::string timestamp = GetFileTimestamp();
+ if (timestamp.empty())
+ {
+ return fileName;
+ }
+
+ // Set the name of the output .dot file.
+ fileName = boost::str(boost::format("%1%/%2%_networkgraph.dot")
+ % dumpDir
+ % timestamp);
+
+ ALOGV("Exporting the optimized network graph to file: %s", fileName.c_str());
+
+ // Write the network graph to a dot file.
+ std::ofstream fileStream;
+ fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);
+
+ if (!fileStream.good())
+ {
+ ALOGW("Could not open file %s for writing", fileName.c_str());
+ return fileName;
+ }
+
+ if (optimizedNetwork.SerializeToDot(fileStream) != armnn::Status::Success)
+ {
+ ALOGW("An error occurred when writing to file %s", fileName.c_str());
+ }
+ return fileName;
+}
+
bool IsDynamicTensor(const armnn::TensorInfo& outputInfo)
{
// Dynamic tensors have at least one 0-sized dimension
return outputInfo.GetNumElements() == 0u;
}
+std::string GetFileTimestamp()
+{
+ // used to get a timestamp to name diagnostic files (the ArmNN serialized graph
+ // and getSupportedOperations.txt files)
+ timespec ts;
+ int iRet = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+ std::stringstream ss;
+ if (iRet == 0)
+ {
+ ss << std::to_string(ts.tv_sec) << "_" << std::to_string(ts.tv_nsec);
+ }
+ else
+ {
+ ALOGW("clock_gettime failed with errno %s : %s", std::to_string(errno).c_str(), std::strerror(errno));
+ }
+ return ss.str();
+}
+
+void RenameGraphDotFile(const std::string& oldName, const std::string& dumpDir, const armnn::NetworkId networkId)
+{
+ if (dumpDir.empty())
+ {
+ return;
+ }
+ if (oldName.empty())
+ {
+ return;
+ }
+ const std::string newFileName = boost::str(boost::format("%1%/%2%_networkgraph.dot")
+ % dumpDir
+ % std::to_string(networkId));
+ int iRet = rename(oldName.c_str(), newFileName.c_str());
+ if (iRet != 0)
+ {
+ std::stringstream ss;
+ ss << "rename of [" << oldName << "] to [" << newFileName << "] failed with errno " << std::to_string(errno)
+ << " : " << std::strerror(errno);
+ ALOGW(ss.str().c_str());
+ }
+}
+
+
+
} // namespace armnn_driver
diff --git a/Utils.hpp b/Utils.hpp
index 267e519e..c5a2e650 100644
--- a/Utils.hpp
+++ b/Utils.hpp
@@ -104,47 +104,14 @@ void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
armnn::NetworkId networkId,
const armnn::IProfiler* profiler);
-template <typename HalModel>
-void ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
- const std::string& dumpDir,
- const HalModel& model)
-{
- // The dump directory must exist in advance.
- if (dumpDir.empty())
- {
- return;
- }
-
- // Get the memory address of the model and convert it to a hex string (of at least a '0' character).
- size_t modelAddress = uintptr_t(&model);
- std::stringstream ss;
- ss << std::uppercase << std::hex << std::setfill('0') << std::setw(1) << modelAddress;
- std::string modelAddressHexString = ss.str();
-
- // Set the name of the output .dot file.
- const std::string fileName = boost::str(boost::format("%1%/networkgraph_%2%.dot")
- % dumpDir
- % modelAddressHexString);
-
- ALOGV("Exporting the optimized network graph to file: %s", fileName.c_str());
+std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
+ const std::string& dumpDir);
- // Write the network graph to a dot file.
- std::ofstream fileStream;
- fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);
-
- if (!fileStream.good())
- {
- ALOGW("Could not open file %s for writing", fileName.c_str());
- return;
- }
-
- if (optimizedNetwork.SerializeToDot(fileStream) != armnn::Status::Success)
- {
- ALOGW("An error occurred when writing to file %s", fileName.c_str());
- }
-}
+void RenameGraphDotFile(const std::string& oldName, const std::string& dumpDir, const armnn::NetworkId networkId);
/// Checks if a tensor info represents a dynamic tensor
bool IsDynamicTensor(const armnn::TensorInfo& outputInfo);
+std::string GetFileTimestamp();
+
} // namespace armnn_driver
diff --git a/test/UtilsTests.cpp b/test/UtilsTests.cpp
index f337db77..a11c8274 100644
--- a/test/UtilsTests.cpp
+++ b/test/UtilsTests.cpp
@@ -35,20 +35,16 @@ public:
{}
ExportNetworkGraphFixture(const std::string& requestInputsAndOutputsDumpDir)
: m_RequestInputsAndOutputsDumpDir(requestInputsAndOutputsDumpDir)
- , m_Model({})
, m_FileName()
, m_FileStream()
{
- // Get the memory address of the model and convert it to a hex string (of at least a '0' character).
- size_t modelAddress = uintptr_t(&m_Model);
- std::stringstream ss;
- ss << std::uppercase << std::hex << std::setfill('0') << std::setw(1) << modelAddress;
- std::string modelAddressHexString = ss.str();
-
// Set the name of the output .dot file.
- m_FileName = boost::str(boost::format("%1%/networkgraph_%2%.dot")
+ // NOTE: the export now uses a time stamp to name the file so we
+ // can't predict ahead of time what the file name will be.
+ std::string timestamp = "dummy";
+ m_FileName = boost::str(boost::format("%1%/%2%_networkgraph.dot")
% m_RequestInputsAndOutputsDumpDir
- % modelAddressHexString);
+ % timestamp);
}
// Teardown: delete the dump file regardless of the outcome of the tests.
@@ -69,6 +65,11 @@ public:
m_FileStream.close();
}
+ if (m_FileName.empty())
+ {
+ return false;
+ }
+
// Open the file.
m_FileStream.open(m_FileName, std::ifstream::in);
@@ -96,10 +97,9 @@ public:
}
std::string m_RequestInputsAndOutputsDumpDir;
- V1_0::Model m_Model;
+ std::string m_FileName;
private:
- std::string m_FileName;
std::ifstream m_FileStream;
};
@@ -144,9 +144,8 @@ BOOST_AUTO_TEST_CASE(ExportToEmptyDirectory)
MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
// Export the mock optimized network.
- armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
- fixture.m_RequestInputsAndOutputsDumpDir,
- fixture.m_Model);
+ fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
+ fixture.m_RequestInputsAndOutputsDumpDir);
// Check that the output file does not exist.
BOOST_TEST(!fixture.FileExists());
@@ -164,9 +163,8 @@ BOOST_AUTO_TEST_CASE(ExportNetwork)
MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
// Export the mock optimized network.
- armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
- fixture.m_RequestInputsAndOutputsDumpDir,
- fixture.m_Model);
+ fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
+ fixture.m_RequestInputsAndOutputsDumpDir);
// Check that the output file exists and that it has the correct name.
BOOST_TEST(fixture.FileExists());
@@ -187,9 +185,8 @@ BOOST_AUTO_TEST_CASE(ExportNetworkOverwriteFile)
MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
// Export the mock optimized network.
- armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
- fixture.m_RequestInputsAndOutputsDumpDir,
- fixture.m_Model);
+ fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
+ fixture.m_RequestInputsAndOutputsDumpDir);
// Check that the output file exists and that it has the correct name.
BOOST_TEST(fixture.FileExists());
@@ -202,9 +199,8 @@ BOOST_AUTO_TEST_CASE(ExportNetworkOverwriteFile)
mockOptimizedNetwork.UpdateMockSerializedContent(mockSerializedContent);
// Export the mock optimized network.
- armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
- fixture.m_RequestInputsAndOutputsDumpDir,
- fixture.m_Model);
+ fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
+ fixture.m_RequestInputsAndOutputsDumpDir);
// Check that the output file still exists and that it has the correct name.
BOOST_TEST(fixture.FileExists());
@@ -227,9 +223,8 @@ BOOST_AUTO_TEST_CASE(ExportMultipleNetworks)
MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
// Export the mock optimized network.
- armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
- fixture1.m_RequestInputsAndOutputsDumpDir,
- fixture1.m_Model);
+ fixture1.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
+ fixture1.m_RequestInputsAndOutputsDumpDir);
// Check that the output file exists and that it has the correct name.
BOOST_TEST(fixture1.FileExists());
@@ -238,9 +233,8 @@ BOOST_AUTO_TEST_CASE(ExportMultipleNetworks)
BOOST_TEST(fixture1.GetFileContent() == mockSerializedContent);
// Export the mock optimized network.
- armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
- fixture2.m_RequestInputsAndOutputsDumpDir,
- fixture2.m_Model);
+ fixture2.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
+ fixture2.m_RequestInputsAndOutputsDumpDir);
// Check that the output file exists and that it has the correct name.
BOOST_TEST(fixture2.FileExists());
@@ -249,9 +243,8 @@ BOOST_AUTO_TEST_CASE(ExportMultipleNetworks)
BOOST_TEST(fixture2.GetFileContent() == mockSerializedContent);
// Export the mock optimized network.
- armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
- fixture3.m_RequestInputsAndOutputsDumpDir,
- fixture3.m_Model);
+ fixture3.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
+ fixture3.m_RequestInputsAndOutputsDumpDir);
// Check that the output file exists and that it has the correct name.
BOOST_TEST(fixture3.FileExists());