IVGCVSW-4417 'Serialise ArmNN Model on android-nn-driver'

* Implemented serialization of the network on android-nn-driver

!armnn:4850

Signed-off-by: Sadik Armagan <sadik.armagan@arm.com>
Change-Id: I3caf07bd4d1d2a3068c58f0b344303c4cf977ca6
diff --git a/Utils.cpp b/Utils.cpp
index 895278a..53877ba 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -8,6 +8,7 @@
 #include "Utils.hpp"
 #include "Half.hpp"
 
+#include <armnnSerializer/ISerializer.hpp>
 #include <armnnUtils/Permute.hpp>
 
 #include <armnn/Utils.hpp>
@@ -22,8 +23,6 @@
 #include <cstdio>
 #include <time.h>
 
-
-
 using namespace android;
 using namespace android::hardware;
 using namespace android::hidl::memory::V1_0;
@@ -572,6 +571,41 @@
     return fileName;
 }
 
+std::string SerializeNetwork(const armnn::INetwork& network, 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;
+    }
+
+    auto serializer(armnnSerializer::ISerializer::Create());
+
+    // Serialize the Network
+    serializer->Serialize(network);
+
+    // Set the name of the output .armnn file.
+    fs::path dumpPath = dumpDir;
+    fs::path tempFilePath = dumpPath / (timestamp + "_network.armnn");
+    fileName = tempFilePath.string();
+
+    // Save serialized network to a file
+    std::ofstream serializedFile(fileName, std::ios::out | std::ios::binary);
+    bool serialized = serializer->SaveSerializedToStream(serializedFile);
+    if (!serialized)
+    {
+        ALOGW("An error occurred when serializing to file %s", fileName.c_str());
+    }
+    return fileName;
+}
+
 bool IsDynamicTensor(const armnn::TensorInfo& tensorInfo)
 {
     if (tensorInfo.GetShape().GetDimensionality() == armnn::Dimensionality::NotSpecified)
@@ -613,25 +647,37 @@
     return ss.str();
 }
 
-void RenameGraphDotFile(const std::string& oldName, const std::string& dumpDir, const armnn::NetworkId networkId)
+void RenameExportedFiles(const std::string& existingSerializedFileName,
+                         const std::string& existingDotFileName,
+                         const std::string& dumpDir,
+                         const armnn::NetworkId networkId)
 {
     if (dumpDir.empty())
     {
         return;
     }
-    if (oldName.empty())
+    RenameFile(existingSerializedFileName, std::string("_network.armnn"), dumpDir, networkId);
+    RenameFile(existingDotFileName, std::string("_networkgraph.dot"), dumpDir, networkId);
+}
+
+void RenameFile(const std::string& existingName,
+                const std::string& extension,
+                const std::string& dumpDir,
+                const armnn::NetworkId networkId)
+{
+    if (existingName.empty() || dumpDir.empty())
     {
         return;
     }
-    fs::path dumpPath = dumpDir;
-    const fs::path newFileName = dumpPath / (std::to_string(networkId) + "_networkgraph.dot");
 
-    int iRet = rename(oldName.c_str(), newFileName.c_str());
+    fs::path dumpPath = dumpDir;
+    const fs::path newFileName = dumpPath / (std::to_string(networkId) + extension);
+    int iRet = rename(existingName.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);
+        ss << "rename of [" << existingName << "] to [" << newFileName << "] failed with errno "
+           << std::to_string(errno) << " : " << std::strerror(errno);
         ALOGW(ss.str().c_str());
     }
 }