COMPMID-601: Add GraphContext

GraphContext hold all the information about the hints that need to be
passed in the nodes. As these might expand, it serves as a centralized
class for such information.

Change-Id: I0b5527630fb97cc5fa500db0bac8307ff2ea36e6
Reviewed-on: http://mpd-gerrit.cambridge.arm.com/90300
Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
diff --git a/arm_compute/graph/Graph.h b/arm_compute/graph/Graph.h
index 3c263c2..da41548 100644
--- a/arm_compute/graph/Graph.h
+++ b/arm_compute/graph/Graph.h
@@ -65,25 +65,21 @@
      * @param[in] tensor Tensor to add
      */
     void add_tensor(std::unique_ptr<Tensor> tensor);
-    /** Sets an execution hint to the graph
-     *
-     * @note Hint is propagated to the following node and as per name
-     *       its just a hint/preference to be considered by the graph executor
-     *
-     * @param[in] hint execution hint
-     */
-    void set_hint(Hint hint);
     /** Manually sets the output of the current node
      *
      * @param[in] tmp Output info to set
      */
     void set_temp(TensorInfo &&tmp);
-
     /** Sets whether to enable information print out
      *
      * @param[in] is_enabled Set to true if need info printed out
      */
     void set_info_enablement(bool is_enabled);
+    /** Returns the graph hints that are currently used
+     *
+     * @return Graph hints
+     */
+    GraphHints &hints();
 
 private:
     class Private;
@@ -106,14 +102,22 @@
  * @return Updated graph
  */
 Graph &operator<<(Graph &graph, Tensor &&tensor);
-/** Overloaded stream operator to provide an execution hint to the graph
+/** Overloaded stream operator to provide a target hint to the graph
  *
- * @param[in, out] graph Graph to provide the hint to
- * @param[in]      hint  Execution hint to be considered
+ * @param[in, out] graph       Graph to provide the hint to
+ * @param[in]      target_hint Target hint to be considered
  *
  * @return Updated graph
  */
-Graph &operator<<(Graph &graph, Hint hint);
+Graph &operator<<(Graph &graph, TargetHint target_hint);
+/** Overloaded stream operator to provide a convolution method hint to the graph
+ *
+ * @param[in, out] graph            Graph to provide the hint to
+ * @param[in]      conv_method_hint Convolution method hint to be considered
+ *
+ * @return Updated graph
+ */
+Graph &operator<<(Graph &graph, ConvolutionMethodHint conv_method_hint);
 /** Overloaded stream operator to add a node to the graph
  *
  * @param[in, out] graph Graph to add the tensor
diff --git a/arm_compute/graph/GraphContext.h b/arm_compute/graph/GraphContext.h
new file mode 100644
index 0000000..98bc8c0
--- /dev/null
+++ b/arm_compute/graph/GraphContext.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_GRAPH_CONTEXT_H__
+#define __ARM_COMPUTE_GRAPH_CONTEXT_H__
+
+#include "arm_compute/graph/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Hints that can be passed to the graph to expose parameterization */
+class GraphHints
+{
+public:
+    /** Default Constructor */
+    GraphHints(TargetHint            target_hint      = TargetHint::DONT_CARE,
+               ConvolutionMethodHint conv_method_hint = ConvolutionMethodHint::GEMM);
+    /** Sets target execution hint
+     *
+     * @param target_hint Target execution hint
+     */
+    void set_target_hint(TargetHint target_hint);
+    /** Sets convolution method to use
+     *
+     * @param convolution_method Convolution method to use
+     */
+    void set_convolution_method_hint(ConvolutionMethodHint convolution_method);
+    /** Returns target execution hint
+     *
+     * @return target execution hint
+     */
+    TargetHint target_hint() const;
+    /** Returns convolution method hint
+     *
+     * @return convolution method hint
+     */
+    ConvolutionMethodHint convolution_method_hint() const;
+
+private:
+    TargetHint            _target_hint;             /**< Target execution hint */
+    ConvolutionMethodHint _convolution_method_hint; /**< Convolution method hint */
+};
+
+/** Graph context */
+class GraphContext
+{
+public:
+    /** Default Constuctor */
+    GraphContext();
+    /** Returns graph hints
+     *
+     * @return Graph hints
+     */
+    GraphHints &hints();
+    /** Returns graph hints
+     *
+     * @return Graph hints
+     */
+    const GraphHints &hints() const;
+
+private:
+    GraphHints _hints; /**< Graph hints */
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_CONTEXT_H__ */
diff --git a/arm_compute/graph/INode.h b/arm_compute/graph/INode.h
index 13b5d05..6ce9b1b 100644
--- a/arm_compute/graph/INode.h
+++ b/arm_compute/graph/INode.h
@@ -24,6 +24,7 @@
 #ifndef __ARM_COMPUTE_GRAPH_INODE_H__
 #define __ARM_COMPUTE_GRAPH_INODE_H__
 
+#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/Types.h"
 #include "arm_compute/runtime/IFunction.h"
 
@@ -41,37 +42,37 @@
     virtual ~INode() = default;
     /** Interface to be implemented that instantiates the node
      *
-     * @param[in] hint   Hint to where the node should be executed
+     * @param[in] ctx    Graph context to be used
      * @param[in] input  Input tensor of the node
      * @param[in] output Output tensor of the node
      */
-    virtual std::unique_ptr<arm_compute::IFunction> instantiate_node(Hint hint, ITensor *input, ITensor *output) = 0;
-    /** Override the existing hint
+    virtual std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensor *input, ITensor *output) = 0;
+    /** Override the existing target hint
      *
      * @note If the input is DONT_CARE then the method has to pick a technology,
      *       else it can accept the hint or override it (But not with DONT_CARE)
      *
-     * @param[in] hint Hint to be considered
+     * @param[in] target_hint Target hint to be considered
      *
-     * @return The updated hint
+     * @return The updated target hint
      */
-    Hint override_hint(Hint hint) const;
+    TargetHint override_target_hint(TargetHint target_hint) const;
 
     virtual void print_info() = 0;
 
 protected:
-    /** Interface to be implement that override the hint
+    /** Interface to be implement that override the hints
      *
-     * @param[in] hint Hint to be considered
+     * @param[in] hints Hints to be considered
      *
-     * @return The updated hint
+     * @return The updated hints
      */
-    virtual Hint node_override_hint(Hint hint) const;
+    virtual GraphHints node_override_hints(GraphHints hints) const;
 
 protected:
-    Hint     _hint{ Hint::DONT_CARE };
-    ITensor *_input{ nullptr };
-    ITensor *_output{ nullptr };
+    TargetHint _target_hint{ TargetHint::DONT_CARE };
+    ITensor   *_input{ nullptr };
+    ITensor   *_output{ nullptr };
 };
 } // namespace graph
 } // namespace arm_compute
diff --git a/arm_compute/graph/SubTensor.h b/arm_compute/graph/SubTensor.h
index a73b0d6..ace93d2 100644
--- a/arm_compute/graph/SubTensor.h
+++ b/arm_compute/graph/SubTensor.h
@@ -55,7 +55,7 @@
      * @param[in] coords       Starting coordinates of the sub-tensor in the parent tensor
      * @param[in] target       Execution target
      */
-    SubTensor(ITensor *parent, TensorShape tensor_shape, Coordinates coords, Hint target);
+    SubTensor(ITensor *parent, TensorShape tensor_shape, Coordinates coords, TargetHint target);
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     SubTensor(const SubTensor &) = delete;
     /** Prevent instances of this class from being copied (As this class contains pointers) */
@@ -86,14 +86,14 @@
      *
      * @return Target of the tensor
      */
-    Hint target() const;
+    TargetHint target() const;
 
 private:
     /** Instantiates a sub-tensor */
     void instantiate_subtensor();
 
 private:
-    Hint                     _target;    /**< Target that this tensor is pinned on */
+    TargetHint               _target;    /**< Target that this tensor is pinned on */
     Coordinates              _coords;    /**< SubTensor Coordinates */
     SubTensorInfo            _info;      /**< SubTensor metadata */
     ITensor                 *_parent;    /**< Parent tensor */
diff --git a/arm_compute/graph/Tensor.h b/arm_compute/graph/Tensor.h
index 0e823ff..9fdd56d 100644
--- a/arm_compute/graph/Tensor.h
+++ b/arm_compute/graph/Tensor.h
@@ -49,7 +49,7 @@
      */
     template <typename AccessorType>
     Tensor(std::unique_ptr<AccessorType> accessor)
-        : _target(Hint::DONT_CARE), _info(), _accessor(std::move(accessor)), _tensor(nullptr)
+        : _target(TargetHint::DONT_CARE), _info(), _accessor(std::move(accessor)), _tensor(nullptr)
     {
     }
     /** Constructor
@@ -58,7 +58,7 @@
      */
     template <typename AccessorType>
     Tensor(AccessorType &&accessor)
-        : _target(Hint::DONT_CARE), _info(), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr)
+        : _target(TargetHint::DONT_CARE), _info(), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr)
     {
     }
     /** Constructor
@@ -68,7 +68,7 @@
      */
     template <typename AccessorType>
     Tensor(TensorInfo &&info, AccessorType &&accessor)
-        : _target(Hint::DONT_CARE), _info(info), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr)
+        : _target(TargetHint::DONT_CARE), _info(info), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr)
     {
     }
     /** Default Destructor */
@@ -95,7 +95,7 @@
      *
      * @return
      */
-    ITensor *set_target(Hint target);
+    ITensor *set_target(TargetHint target);
     /** Returns tensor's TensorInfo
      *
      * @return TensorInfo of the tensor
@@ -114,10 +114,10 @@
      *
      * @return Target of the tensor
      */
-    Hint target() const;
+    TargetHint target() const;
 
 private:
-    Hint                             _target;   /**< Target that this tensor is pinned on */
+    TargetHint                       _target;   /**< Target that this tensor is pinned on */
     TensorInfo                       _info;     /**< Tensor metadata */
     std::unique_ptr<ITensorAccessor> _accessor; /**< Tensor Accessor */
     std::unique_ptr<ITensor>         _tensor;   /**< Tensor */
diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h
index 538d64e..e48ff84 100644
--- a/arm_compute/graph/Types.h
+++ b/arm_compute/graph/Types.h
@@ -47,7 +47,7 @@
 using arm_compute::PoolingType;
 
 /**< Execution hint to the graph executor */
-enum class Hint
+enum class TargetHint
 {
     DONT_CARE, /**< Run node in any device */
     OPENCL,    /**< Run node on an OpenCL capable device (GPU) */
diff --git a/arm_compute/graph/nodes/ActivationLayer.h b/arm_compute/graph/nodes/ActivationLayer.h
index c23674e..ea32dd0 100644
--- a/arm_compute/graph/nodes/ActivationLayer.h
+++ b/arm_compute/graph/nodes/ActivationLayer.h
@@ -24,6 +24,7 @@
 #ifndef __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__
 #define __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__
 
+#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
 #include "arm_compute/graph/Tensor.h"
 #include "arm_compute/graph/Types.h"
@@ -33,7 +34,7 @@
 namespace graph
 {
 /** Activation Layer node */
-class ActivationLayer : public INode
+class ActivationLayer final : public INode
 {
 public:
     /** Default Constructor
@@ -43,7 +44,7 @@
     ActivationLayer(const ActivationLayerInfo activation_info);
 
     // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(Hint hint, ITensor *input, ITensor *output) override;
+    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensor *input, ITensor *output) override;
     void print_info() override;
 
 private:
diff --git a/arm_compute/graph/nodes/ConvolutionLayer.h b/arm_compute/graph/nodes/ConvolutionLayer.h
index fcd097b..086bf03 100644
--- a/arm_compute/graph/nodes/ConvolutionLayer.h
+++ b/arm_compute/graph/nodes/ConvolutionLayer.h
@@ -24,6 +24,7 @@
 #ifndef __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_H__
 #define __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_H__
 
+#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
 #include "arm_compute/graph/SubTensor.h"
 #include "arm_compute/graph/Tensor.h"
@@ -76,7 +77,7 @@
     }
 
     // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(Hint hint, ITensor *input, ITensor *output) override;
+    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensor *input, ITensor *output) override;
     void print_info() override;
 
 private:
diff --git a/arm_compute/graph/nodes/FullyConnectedLayer.h b/arm_compute/graph/nodes/FullyConnectedLayer.h
index 3e1fe23..b05bc96 100644
--- a/arm_compute/graph/nodes/FullyConnectedLayer.h
+++ b/arm_compute/graph/nodes/FullyConnectedLayer.h
@@ -24,6 +24,7 @@
 #ifndef __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_H__
 #define __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_H__
 
+#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
 #include "arm_compute/graph/Tensor.h"
 #include "arm_compute/graph/Types.h"
@@ -33,7 +34,7 @@
 namespace graph
 {
 /** Fully connected layer node */
-class FullyConnectedLayer : public INode
+class FullyConnectedLayer final : public INode
 {
 public:
     /** Default constructor
@@ -49,7 +50,7 @@
     }
 
     // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(Hint hint, ITensor *input, ITensor *output) override;
+    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensor *input, ITensor *output) override;
     void print_info() override;
 
     // Inherited methods overriden:
diff --git a/arm_compute/graph/nodes/NormalizationLayer.h b/arm_compute/graph/nodes/NormalizationLayer.h
index 40b9c2b..52f67d2 100644
--- a/arm_compute/graph/nodes/NormalizationLayer.h
+++ b/arm_compute/graph/nodes/NormalizationLayer.h
@@ -24,6 +24,7 @@
 #ifndef __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__
 #define __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__
 
+#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
 #include "arm_compute/graph/Types.h"
 
@@ -42,7 +43,7 @@
     explicit NormalizationLayer(const NormalizationLayerInfo norm_info);
 
     // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(Hint hint, ITensor *input, ITensor *output) override;
+    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensor *input, ITensor *output) override;
     void print_info() override;
 
 private:
diff --git a/arm_compute/graph/nodes/PoolingLayer.h b/arm_compute/graph/nodes/PoolingLayer.h
index 14e2c6d..f07800a 100644
--- a/arm_compute/graph/nodes/PoolingLayer.h
+++ b/arm_compute/graph/nodes/PoolingLayer.h
@@ -24,6 +24,7 @@
 #ifndef __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__
 #define __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__
 
+#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
 #include "arm_compute/graph/Tensor.h"
 #include "arm_compute/graph/Types.h"
@@ -33,7 +34,7 @@
 namespace graph
 {
 /** Pooling layer node */
-class PoolingLayer : public INode
+class PoolingLayer final : public INode
 {
 public:
     /** Default Constructor
@@ -43,7 +44,7 @@
     PoolingLayer(const PoolingLayerInfo pool_info);
 
     // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(Hint hint, ITensor *input, ITensor *output) override;
+    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensor *input, ITensor *output) override;
     void print_info() override;
 
 private:
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/nodes/SoftmaxLayer.h
index 1779ada..1515a0f 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/nodes/SoftmaxLayer.h
@@ -24,6 +24,7 @@
 #ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
 #define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
 
+#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
 #include "arm_compute/graph/Tensor.h"
 #include "arm_compute/graph/Types.h"
@@ -37,7 +38,7 @@
 {
 public:
     // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(Hint hint, ITensor *input, ITensor *output) override;
+    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensor *input, ITensor *output) override;
     void print_info() override;
 };