arm_compute v18.03

Change-Id: I8f9a2a9d32a6cab019b8504d313216f28671f9f5
diff --git a/src/graph/Graph.cpp b/src/graph/Graph.cpp
index b6c6822..2fe3a90 100644
--- a/src/graph/Graph.cpp
+++ b/src/graph/Graph.cpp
@@ -33,8 +33,19 @@
 #include "arm_compute/runtime/Tensor.h"
 #include "support/ToolchainSupport.h"
 
+#include <sys/stat.h>
+
 using namespace arm_compute::graph;
 
+namespace
+{
+bool file_exists(const std::string &filename)
+{
+    std::ifstream file(filename);
+    return file.good();
+}
+
+} // namespace
 struct Stage
 {
     ITensorObject                          *_input;
@@ -69,9 +80,13 @@
     GraphHints     _previous_hints{};
 };
 
+static const std::string tuner_data_filename = "acl_tuner.csv";
 Graph::~Graph() //NOLINT
 {
-    //Can't use =default because the destructor must be defined after Graph::Private's definition
+    if(_pimpl->_tuner.tune_new_kernels() && !_pimpl->_tuner.lws_table().empty())
+    {
+        _pimpl->_tuner.save_to_file(tuner_data_filename);
+    }
 }
 
 Graph::Graph()
@@ -85,17 +100,14 @@
     // Check if OpenCL is available and initialize the scheduler
     if(opencl_is_available())
     {
-        if(use_cl_tuner)
+        if(_pimpl->_tuner.lws_table().empty() && file_exists(tuner_data_filename))
         {
-            arm_compute::CLScheduler::get().default_init(&_pimpl->_tuner);
+            _pimpl->_tuner.load_from_file(tuner_data_filename);
         }
-        else
-        {
-            arm_compute::CLScheduler::get().default_init();
-        }
+        _pimpl->_tuner.set_tune_new_kernels(use_cl_tuner);
+        arm_compute::CLScheduler::get().default_init(&_pimpl->_tuner);
     }
 }
-
 void Graph::run()
 {
     while(true)