Release 18.08
diff --git a/src/armnnUtils/CsvReader.cpp b/src/armnnUtils/CsvReader.cpp
new file mode 100644
index 0000000..5b66c94
--- /dev/null
+++ b/src/armnnUtils/CsvReader.cpp
@@ -0,0 +1,63 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+#include "CsvReader.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/tokenizer.hpp>
+
+#include <fstream>
+#include <string>
+#include <vector>
+
+using Tokenizer = boost::tokenizer<boost::escaped_list_separator<char>>;
+
+namespace armnnUtils
+{
+
+CsvRow ParseLine(const std::string& csvLine)
+{
+    Tokenizer tokenizer(csvLine);
+    CsvRow entry;
+
+    for (const auto &token : tokenizer)
+    {
+        entry.values.push_back(boost::trim_copy(token));
+    }
+    return entry;
+}
+
+std::vector<CsvRow> CsvReader::ParseFile(const std::string& csvFile)
+{
+    std::vector<CsvRow> result;
+
+    std::ifstream in(csvFile.c_str());
+    if (!in.is_open())
+        return result;
+
+    std::string line;
+    while (getline(in, line))
+    {
+        if(!line.empty())
+        {
+            CsvRow entry = ParseLine(line);
+            result.push_back(entry);
+        }
+    }
+    return result;
+}
+
+std::vector<CsvRow> CsvReader::ParseVector(const std::vector<std::string>& csvVector)
+{
+    std::vector<CsvRow> result;
+
+    for (auto const& line: csvVector)
+    {
+        CsvRow entry = ParseLine(line);
+        result.push_back(entry);
+    }
+    return result;
+}
+} // namespace armnnUtils
\ No newline at end of file
diff --git a/src/armnnUtils/CsvReader.hpp b/src/armnnUtils/CsvReader.hpp
new file mode 100644
index 0000000..0d52980
--- /dev/null
+++ b/src/armnnUtils/CsvReader.hpp
@@ -0,0 +1,25 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include <vector>
+#include <string>
+
+namespace armnnUtils
+{
+
+struct CsvRow
+{
+    std::vector<std::string> values;
+};
+
+class CsvReader
+{
+public:
+    static std::vector<CsvRow> ParseFile(const std::string& csvFile);
+
+    static std::vector<CsvRow> ParseVector(const std::vector<std::string>& csvVector);
+};
+} // namespace armnnUtils
diff --git a/src/armnnUtils/FloatingPointConverter.cpp b/src/armnnUtils/FloatingPointConverter.cpp
new file mode 100644
index 0000000..5c1a431
--- /dev/null
+++ b/src/armnnUtils/FloatingPointConverter.cpp
@@ -0,0 +1,44 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+#include "FloatingPointConverter.hpp"
+#include "../armnn/Half.hpp"
+
+#include <boost/assert.hpp>
+
+namespace armnnUtils
+{
+
+void FloatingPointConverter::ConvertFloat32To16(const float* srcFloat32Buffer,
+                                                size_t numElements,
+                                                void* dstFloat16Buffer)
+{
+    BOOST_ASSERT(srcFloat32Buffer != nullptr);
+    BOOST_ASSERT(dstFloat16Buffer != nullptr);
+
+    armnn::Half* pHalf = reinterpret_cast<armnn::Half*>(dstFloat16Buffer);
+
+    for (size_t i = 0; i < numElements; i++)
+    {
+        pHalf[i] = armnn::Half(srcFloat32Buffer[i]);
+    }
+}
+
+void FloatingPointConverter::ConvertFloat16To32(const void* srcFloat16Buffer,
+                                                size_t numElements,
+                                                float* dstFloat32Buffer)
+{
+    BOOST_ASSERT(srcFloat16Buffer != nullptr);
+    BOOST_ASSERT(dstFloat32Buffer != nullptr);
+
+    const armnn::Half* pHalf = reinterpret_cast<const armnn::Half*>(srcFloat16Buffer);
+
+    for (size_t i = 0; i < numElements; i++)
+    {
+        dstFloat32Buffer[i] = pHalf[i];
+    }
+}
+
+} //namespace armnnUtils
diff --git a/src/armnnUtils/FloatingPointConverter.hpp b/src/armnnUtils/FloatingPointConverter.hpp
new file mode 100644
index 0000000..e879c81
--- /dev/null
+++ b/src/armnnUtils/FloatingPointConverter.hpp
@@ -0,0 +1,21 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+#pragma once
+
+#include <cstddef>
+
+namespace armnnUtils
+{
+class FloatingPointConverter
+{
+public:
+    // Converts a buffer of FP32 values to FP16, and stores in the given dstFloat16Buffer.
+    // dstFloat16Buffer should be (numElements * 2) in size
+    static void ConvertFloat32To16(const float *srcFloat32Buffer, size_t numElements, void *dstFloat16Buffer);
+
+    static void ConvertFloat16To32(const void *srcFloat16Buffer, size_t numElements, float *dstFloat32Buffer);
+};
+} //namespace armnnUtils
diff --git a/src/armnnUtils/GraphTopologicalSort.hpp b/src/armnnUtils/GraphTopologicalSort.hpp
index f455289..86eb4cc 100644
--- a/src/armnnUtils/GraphTopologicalSort.hpp
+++ b/src/armnnUtils/GraphTopologicalSort.hpp
@@ -5,11 +5,14 @@
 #pragma once
 
 #include <boost/assert.hpp>
+#include <boost/optional.hpp>
 
 #include <functional>
 #include <map>
+#include <stack>
 #include <vector>
 
+
 namespace armnnUtils
 {
 
@@ -22,51 +25,88 @@
     Visited,
 };
 
+
+template <typename TNodeId>
+boost::optional<TNodeId> GetNextChild(TNodeId node,
+                                      std::function<std::vector<TNodeId>(TNodeId)> getIncomingEdges,
+                                      std::map<TNodeId, NodeState>& nodeStates)
+{
+    for (TNodeId childNode : getIncomingEdges(node))
+    {
+        if (nodeStates.find(childNode) == nodeStates.end())
+        {
+            return childNode;
+        }
+        else
+        {
+            if (nodeStates.find(childNode)->second == NodeState::Visiting)
+            {
+                return childNode;
+            }
+        }
+    }
+
+    return {};
+}
+
 template<typename TNodeId>
-bool Visit(
-    TNodeId current,
+bool TopologicallySort(
+    TNodeId initialNode,
     std::function<std::vector<TNodeId>(TNodeId)> getIncomingEdges,
     std::vector<TNodeId>& outSorted,
     std::map<TNodeId, NodeState>& nodeStates)
 {
-    auto currentStateIt = nodeStates.find(current);
-    if (currentStateIt != nodeStates.end())
+    std::stack<TNodeId> nodeStack;
+
+    // If the node is never visited we should search it
+    if (nodeStates.find(initialNode) == nodeStates.end())
     {
-        if (currentStateIt->second == NodeState::Visited)
-        {
-            return true;
-        }
-        if (currentStateIt->second == NodeState::Visiting)
-        {
-            return false;
-        }
-        else
-        {
-            BOOST_ASSERT(false);
-        }
+        nodeStack.push(initialNode);
     }
 
-    nodeStates[current] = NodeState::Visiting;
-
-    for (TNodeId inputNode : getIncomingEdges(current))
+    while (!nodeStack.empty())
     {
-        Visit(inputNode, getIncomingEdges, outSorted, nodeStates);
+        TNodeId current = nodeStack.top();
+
+        nodeStates[current] = NodeState::Visiting;
+
+        boost::optional<TNodeId> nextChildOfCurrent = GetNextChild(current, getIncomingEdges, nodeStates);
+
+        if (nextChildOfCurrent)
+        {
+            TNodeId nextChild = nextChildOfCurrent.get();
+
+            // If the child has not been searched, add to the stack and iterate over this node
+            if (nodeStates.find(nextChild) == nodeStates.end())
+            {
+                nodeStack.push(nextChild);
+                continue;
+            }
+
+            // If we re-encounter a node being visited there is a cycle
+            if (nodeStates[nextChild] == NodeState::Visiting)
+            {
+                return false;
+            }
+        }
+
+        nodeStack.pop();
+
+        nodeStates[current] = NodeState::Visited;
+        outSorted.push_back(current);
     }
 
-    nodeStates[current] = NodeState::Visited;
-
-    outSorted.push_back(current);
     return true;
 }
 
 }
 
-// Sorts an directed acyclic graph (DAG) into a flat list such that all inputs to a node are before the node itself.
+// Sorts a directed acyclic graph (DAG) into a flat list such that all inputs to a node are before the node itself.
 // Returns true if successful or false if there is an error in the graph structure (e.g. it contains a cycle).
 // The graph is defined entirely by the "getIncomingEdges" function which the user provides. For a given node,
 // it must return the list of nodes which are required to come before it.
 // "targetNodes" is the list of nodes where the search begins - i.e. the nodes that you want to evaluate.
-// The implementation is based on https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search
+// This is an iterative implementation based on https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search
 template<typename TNodeId, typename TTargetNodes>
 bool GraphTopologicalSort(
     const TTargetNodes& targetNodes,
@@ -78,7 +118,7 @@
 
     for (TNodeId targetNode : targetNodes)
     {
-        if (!Visit(targetNode, getIncomingEdges, outSorted, nodeStates))
+        if (!TopologicallySort(targetNode, getIncomingEdges, outSorted, nodeStates))
         {
             return false;
         }
diff --git a/src/armnnUtils/HeapProfiling.hpp b/src/armnnUtils/HeapProfiling.hpp
index febcbfe..4ba38f5 100644
--- a/src/armnnUtils/HeapProfiling.hpp
+++ b/src/armnnUtils/HeapProfiling.hpp
@@ -9,8 +9,8 @@
 #include <string>
 #include <cstddef>
 
-// this is conditional so we can change the environment variable
-// at build time
+// This is conditional so we can change the environment variable
+// at build time.
 #ifndef ARMNN_HEAP_PROFILE_DUMP_DIR
 #define ARMNN_HEAP_PROFILE_DUMP_DIR "ARMNN_HEAP_PROFILE_DUMP_DIR"
 #endif // ARMNN_HEAP_PROFILE_DUMP_DIR
@@ -24,12 +24,12 @@
     ~ScopedHeapProfiler();
 
 private:
-    // Location comes from the ARMNN_HEAP_PROFILE_DUMP_DIR
-    // if not available then it dumps to /tmp
+    // Location comes from the ARMNN_HEAP_PROFILE_DUMP_DIR.
+    // If it is not available then it dumps to /tmp.
     std::string m_Location;
     std::string m_Tag;
 
-    // No default construction and copying
+    // No default construction and copying.
     ScopedHeapProfiler() = delete;
     ScopedHeapProfiler(const ScopedHeapProfiler &) = delete;
     ScopedHeapProfiler & operator=(const ScopedHeapProfiler &) = delete;
diff --git a/src/armnnUtils/LeakChecking.cpp b/src/armnnUtils/LeakChecking.cpp
index ac12fe0..83aa5d8 100644
--- a/src/armnnUtils/LeakChecking.cpp
+++ b/src/armnnUtils/LeakChecking.cpp
@@ -8,6 +8,9 @@
 #include "LeakChecking.hpp"
 #include "gperftools/heap-checker.h"
 
+namespace armnnUtils
+{
+
 struct ScopedLeakChecker::Impl
 {
     HeapLeakChecker m_LeakChecker;
@@ -59,4 +62,20 @@
 {
 }
 
+void LocalLeakCheckingOnly()
+{
+    auto * globalChecker = HeapLeakChecker::GlobalChecker();
+    if (globalChecker)
+    {
+        // Don't care about global leaks and make sure we won't report any.
+        // This is because leak checking supposed to run in well defined
+        // contexts through the ScopedLeakChecker, otherwise we risk false
+        // positives because of external factors.
+        globalChecker->NoGlobalLeaks();
+        globalChecker->CancelGlobalCheck();
+    }
+}
+
+} // namespace armnnUtils
+
 #endif // ARMNN_LEAK_CHECKING_ENABLED
diff --git a/src/armnnUtils/LeakChecking.hpp b/src/armnnUtils/LeakChecking.hpp
index b65befe..22b3b67 100644
--- a/src/armnnUtils/LeakChecking.hpp
+++ b/src/armnnUtils/LeakChecking.hpp
@@ -19,7 +19,7 @@
     ScopedLeakChecker(const std::string & name);
     ~ScopedLeakChecker();
 
-    // forwarding these to Google Performance Tools
+    // Forwarding these to Google Performance Tools.
     static bool IsActive();
     bool NoLeaks();
     // Note that the following two functions only work after
@@ -29,12 +29,12 @@
     ssize_t ObjectsLeaked() const;
 
 private:
-    // hide imlementation so we don't litter other's namespaces
-    // with heap checker related stuff
+    // Hides imlementation so we don't litter other's namespaces
+    // with heap checker related stuff.
     struct Impl;
     std::unique_ptr<Impl> m_Impl;
 
-    // No default construction and copying
+    // No default construction and copying.
     ScopedLeakChecker() = delete;
     ScopedLeakChecker(const ScopedLeakChecker &) = delete;
     ScopedLeakChecker & operator=(const ScopedLeakChecker &) = delete;
@@ -47,16 +47,19 @@
     ~ScopedDisableLeakChecking();
 
 private:
-    // hide imlementation so we don't litter other's namespaces
-    // with heap checker related stuff
+    // Hides imlementation so we don't litter other's namespaces
+    // with heap checker related stuff.
     struct Impl;
     std::unique_ptr<Impl> m_Impl;
 
-    // No copying
+    // No copying.
     ScopedDisableLeakChecking(const ScopedDisableLeakChecking &) = delete;
     ScopedDisableLeakChecking & operator=(const ScopedDisableLeakChecking &) = delete;
 };
 
+// disable global leak checks starting from 'main'
+void LocalLeakCheckingOnly();
+
 } // namespace armnnUtils
 
 #define ARMNN_SCOPED_LEAK_CHECKER(TAG) \
@@ -77,6 +80,9 @@
 #define ARMNN_DISABLE_LEAK_CHECKING_IN_SCOPE() \
     armnnUtils::ScopedDisableLeakChecking __disable_leak_checking_in_scope__
 
+#define ARMNN_LOCAL_LEAK_CHECKING_ONLY() \
+    armnnUtils::LocalLeakCheckingOnly()
+
 #else // ARMNN_LEAK_CHECKING_ENABLED
 
 #define ARMNN_SCOPED_LEAK_CHECKER(TAG)
@@ -85,5 +91,6 @@
 #define ARMNN_BYTES_LEAKED_IN_SCOPE() 0
 #define ARMNN_OBJECTS_LEAKED_IN_SCOPE() 0
 #define ARMNN_DISABLE_LEAK_CHECKING_IN_SCOPE()
+#define ARMNN_LOCAL_LEAK_CHECKING_ONLY()
 
 #endif // ARMNN_LEAK_CHECKING_ENABLED
diff --git a/src/armnnUtils/Logging.cpp b/src/armnnUtils/Logging.cpp
index 95978d4..4d759a3 100644
--- a/src/armnnUtils/Logging.cpp
+++ b/src/armnnUtils/Logging.cpp
@@ -47,7 +47,7 @@
     // stdout, so we have to explicitly disable logging in this case.
     core->set_logging_enabled(printToStandardOutput || printToDebugOutput);
 
-    // Setup severity filter
+    // Sets up severity filter.
     boost::log::trivial::severity_level boostSeverity;
     switch (severity)
     {
diff --git a/src/armnnUtils/ParserFlatbuffersFixture.hpp b/src/armnnUtils/ParserFlatbuffersFixture.hpp
deleted file mode 100644
index 16f9620..0000000
--- a/src/armnnUtils/ParserFlatbuffersFixture.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Copyright © 2017 Arm Ltd. All rights reserved.
-// See LICENSE file in the project root for full license information.
-//
-
-#pragma once
-
-namespace armnnUtils
-{
-
-}
diff --git a/src/armnnUtils/ParserPrototxtFixture.hpp b/src/armnnUtils/ParserPrototxtFixture.hpp
index 81e3057..e2e6459 100644
--- a/src/armnnUtils/ParserPrototxtFixture.hpp
+++ b/src/armnnUtils/ParserPrototxtFixture.hpp
@@ -6,11 +6,15 @@
 #pragma once
 
 #include "armnn/IRuntime.hpp"
+#include "armnnOnnxParser/IOnnxParser.hpp"
 #include "test/TensorHelpers.hpp"
+#include "VerificationHelpers.hpp"
+
+#include <boost/format.hpp>
 #include <string>
 
-
-// TODO davbec01 (14/05/18) : put these into armnnUtils namespace
+namespace armnnUtils
+{
 
 template<typename TParser>
 struct ParserPrototxtFixture
@@ -19,14 +23,15 @@
         : m_Parser(TParser::Create())
         , m_NetworkIdentifier(-1)
     {
-        m_Runtimes.push_back(armnn::IRuntime::Create(armnn::Compute::CpuRef));
+        armnn::IRuntime::CreationOptions options;
+        m_Runtimes.push_back(std::make_pair(armnn::IRuntime::Create(options), armnn::Compute::CpuRef));
 
 #if ARMCOMPUTENEON_ENABLED
-        m_Runtimes.push_back(armnn::IRuntime::Create(armnn::Compute::CpuAcc));
+        m_Runtimes.push_back(std::make_pair(armnn::IRuntime::Create(options), armnn::Compute::CpuAcc));
 #endif
 
 #if ARMCOMPUTECL_ENABLED
-        m_Runtimes.push_back(armnn::IRuntime::Create(armnn::Compute::GpuAcc));
+        m_Runtimes.push_back(std::make_pair(armnn::IRuntime::Create(options), armnn::Compute::GpuAcc));
 #endif
     }
 
@@ -38,10 +43,11 @@
         const std::string& outputName);
     void Setup(const std::map<std::string, armnn::TensorShape>& inputShapes,
         const std::vector<std::string>& requestedOutputs);
+    void Setup();
     /// @}
 
     /// Executes the network with the given input tensor and checks the result against the given output tensor.
-    /// This overload assumes the network has a single input and a single output.
+    /// This overload assumes that the network has a single input and a single output.
     template <std::size_t NumOutputDimensions>
     void RunTest(const std::vector<float>& inputData, const std::vector<float>& expectedOutputData);
 
@@ -53,7 +59,7 @@
 
     std::string                                         m_Prototext;
     std::unique_ptr<TParser, void(*)(TParser* parser)>  m_Parser;
-    std::vector<armnn::IRuntimePtr>                     m_Runtimes;
+    std::vector<std::pair<armnn::IRuntimePtr, armnn::Compute>> m_Runtimes;
     armnn::NetworkId                                    m_NetworkIdentifier;
 
     /// If the single-input-single-output overload of Setup() is called, these will store the input and output name
@@ -68,7 +74,7 @@
 void ParserPrototxtFixture<TParser>::SetupSingleInputSingleOutput(const std::string& inputName,
     const std::string& outputName)
 {
-    // Store the input and output name so they don't need to be passed to the single-input-single-output RunTest().
+    // Stores the input and output name so they don't need to be passed to the single-input-single-output RunTest().
     m_SingleInputName = inputName;
     m_SingleOutputName = outputName;
     Setup({ }, { outputName });
@@ -79,7 +85,7 @@
     const std::string& inputName,
     const std::string& outputName)
 {
-    // Store the input and output name so they don't need to be passed to the single-input-single-output RunTest().
+    // Stores the input and output name so they don't need to be passed to the single-input-single-output RunTest().
     m_SingleInputName = inputName;
     m_SingleOutputName = outputName;
     Setup({ { inputName, inputTensorShape } }, { outputName });
@@ -91,16 +97,39 @@
 {
     for (auto&& runtime : m_Runtimes)
     {
+        std::string errorMessage;
+
         armnn::INetworkPtr network =
             m_Parser->CreateNetworkFromString(m_Prototext.c_str(), inputShapes, requestedOutputs);
-
-        auto optimized = Optimize(*network, runtime->GetDeviceSpec());
-
-        armnn::Status ret = runtime->LoadNetwork(m_NetworkIdentifier, move(optimized));
-
+        auto optimized = Optimize(*network, { runtime.second, armnn::Compute::CpuRef }, runtime.first->GetDeviceSpec());
+        armnn::Status ret = runtime.first->LoadNetwork(m_NetworkIdentifier, move(optimized), errorMessage);
         if (ret != armnn::Status::Success)
         {
-            throw armnn::Exception("LoadNetwork failed");
+            throw armnn::Exception(boost::str(
+                boost::format("LoadNetwork failed with error: '%1%' %2%")
+                              % errorMessage
+                              % CHECK_LOCATION().AsString()));
+        }
+    }
+}
+
+template<typename TParser>
+void ParserPrototxtFixture<TParser>::Setup()
+{
+    for (auto&& runtime : m_Runtimes)
+    {
+        std::string errorMessage;
+
+        armnn::INetworkPtr network =
+            m_Parser->CreateNetworkFromString(m_Prototext.c_str());
+        auto optimized = Optimize(*network, { runtime.second, armnn::Compute::CpuRef }, runtime.first->GetDeviceSpec());
+        armnn::Status ret = runtime.first->LoadNetwork(m_NetworkIdentifier, move(optimized), errorMessage);
+        if (ret != armnn::Status::Success)
+        {
+            throw armnn::Exception(boost::str(
+                boost::format("LoadNetwork failed with error: '%1%' %2%")
+                              % errorMessage
+                              % CHECK_LOCATION().AsString()));
         }
     }
 }
@@ -122,7 +151,7 @@
     {
         using BindingPointInfo = std::pair<armnn::LayerBindingId, armnn::TensorInfo>;
 
-        // Setup the armnn input tensors from the given vectors.
+        // Sets up the armnn input tensors from the given vectors.
         armnn::InputTensors inputTensors;
         for (auto&& it : inputData)
         {
@@ -130,7 +159,7 @@
             inputTensors.push_back({ bindingInfo.first, armnn::ConstTensor(bindingInfo.second, it.second.data()) });
         }
 
-        // Allocate storage for the output tensors to be written to and setup the armnn output tensors.
+        // Allocates storage for the output tensors to be written to and sets up the armnn output tensors.
         std::map<std::string, boost::multi_array<float, NumOutputDimensions>> outputStorage;
         armnn::OutputTensors outputTensors;
         for (auto&& it : expectedOutputData)
@@ -141,14 +170,27 @@
                 { bindingInfo.first, armnn::Tensor(bindingInfo.second, outputStorage.at(it.first).data()) });
         }
 
-        runtime->EnqueueWorkload(m_NetworkIdentifier, inputTensors, outputTensors);
+        runtime.first->EnqueueWorkload(m_NetworkIdentifier, inputTensors, outputTensors);
 
-        // Compare each output tensor to the expected values
+        // Compares each output tensor to the expected values.
         for (auto&& it : expectedOutputData)
         {
             BindingPointInfo bindingInfo = m_Parser->GetNetworkOutputBindingInfo(it.first);
+            if (bindingInfo.second.GetNumElements() != it.second.size())
+            {
+                throw armnn::Exception(
+                    boost::str(
+                        boost::format("Output tensor %1% is expected to have %2% elements. "
+                                      "%3% elements supplied. %4%") %
+                                      it.first %
+                                      bindingInfo.second.GetNumElements() %
+                                      it.second.size() %
+                                      CHECK_LOCATION().AsString()));
+            }
             auto outputExpected = MakeTensor<float, NumOutputDimensions>(bindingInfo.second, it.second);
             BOOST_TEST(CompareTensors(outputExpected, outputStorage[it.first]));
         }
     }
 }
+
+} // namespace armnnUtils
diff --git a/src/armnnUtils/Permute.cpp b/src/armnnUtils/Permute.cpp
index 58e5858..ba842db 100644
--- a/src/armnnUtils/Permute.cpp
+++ b/src/armnnUtils/Permute.cpp
@@ -107,7 +107,7 @@
     PermuteLoop(dstShape, mappings).Unroll(src, dst);
 }
 
-// Instantiate for types
+// Instantiates for types.
 template void Permute(const armnn::TensorShape& dstShape, const armnn::PermutationVector& mappings,
                       const float* src, float* dst);
 template void Permute(const armnn::TensorShape& dstShape, const armnn::PermutationVector& mappings,
diff --git a/src/armnnUtils/VerificationHelpers.cpp b/src/armnnUtils/VerificationHelpers.cpp
new file mode 100644
index 0000000..301aa4c
--- /dev/null
+++ b/src/armnnUtils/VerificationHelpers.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+#include "VerificationHelpers.hpp"
+#include <boost/format.hpp>
+#include <armnn/Exceptions.hpp>
+
+using namespace armnn;
+
+namespace armnnUtils
+{
+
+void CheckValidSize(std::initializer_list<size_t> validInputCounts,
+                    size_t actualValue,
+                    const char* validExpr,
+                    const char* actualExpr,
+                    const CheckLocation& location)
+{
+    bool isValid = std::any_of(validInputCounts.begin(),
+                               validInputCounts.end(),
+                               [&actualValue](size_t x) { return x == actualValue; } );
+    if (!isValid)
+    {
+        throw ParseException(
+            boost::str(
+                boost::format("%1% = %2% is not valid, not in {%3%}. %4%") %
+                              actualExpr %
+                              actualValue %
+                              validExpr %
+                              location.AsString()));
+    }
+}
+
+uint32_t NonNegative(const char* expr,
+                     int32_t value,
+                     const CheckLocation& location)
+{
+    if (value < 0)
+    {
+        throw ParseException(
+            boost::str(
+                boost::format("'%1%' must be non-negative, received: %2% at %3%") %
+                              expr %
+                              value %
+                              location.AsString() ));
+    }
+    else
+    {
+        return static_cast<uint32_t>(value);
+    }
+}
+
+int32_t VerifyInt32(const char* expr,
+                     int64_t value,
+                     const armnn::CheckLocation& location)
+{
+    if (value < std::numeric_limits<int>::min()  || value > std::numeric_limits<int>::max())
+    {
+        throw ParseException(
+            boost::str(
+                boost::format("'%1%' must should fit into a int32 (ArmNN don't support int64), received: %2% at %3%") %
+                              expr %
+                              value %
+                              location.AsString() ));
+    }
+    else
+    {
+        return static_cast<int32_t>(value);
+    }
+}
+
+}// armnnUtils
diff --git a/src/armnnUtils/VerificationHelpers.hpp b/src/armnnUtils/VerificationHelpers.hpp
new file mode 100644
index 0000000..8e3550c
--- /dev/null
+++ b/src/armnnUtils/VerificationHelpers.hpp
@@ -0,0 +1,35 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+#include <iostream>
+#include <sstream>
+
+#include <armnn/Exceptions.hpp>
+
+namespace armnnUtils
+{
+
+void CheckValidSize(std::initializer_list<size_t> validInputCounts,
+                    size_t actualValue,
+                    const char* validExpr,
+                    const char* actualExpr,
+                    const armnn::CheckLocation& location);
+
+uint32_t NonNegative(const char* expr,
+                     int32_t value,
+                     const armnn::CheckLocation& location);
+
+int32_t VerifyInt32(const char* expr,
+                    int64_t value,
+                    const armnn::CheckLocation& location);
+
+}//armnnUtils
+
+#define CHECKED_INT32(VALUE) armnnUtils::VerifyInt32(#VALUE, VALUE, CHECK_LOCATION())
+
+#define CHECK_VALID_SIZE(ACTUAL, ...) \
+armnnUtils::CheckValidSize({__VA_ARGS__}, ACTUAL, #__VA_ARGS__, #ACTUAL, CHECK_LOCATION())
+
+#define CHECKED_NON_NEGATIVE(VALUE) armnnUtils::NonNegative(#VALUE, VALUE, CHECK_LOCATION())