COMPMID-1180: Add support for bucket multi-threading (Part2)

- Introduced some Hints allowing the function to set its favourite splitting method for a given workload
- Implemented the bucket split (Disabled by default)

Change-Id: I3a48dfb0bd0ec8b69a44d9c4a4c77ad3f6dc9827
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/133079
Tested-by: Jenkins <bsgcomp@arm.com>
Reviewed-by: Gian Marco Iodice <gianmarco.iodice@arm.com>
diff --git a/arm_compute/runtime/CPP/CPPScheduler.h b/arm_compute/runtime/CPP/CPPScheduler.h
index 6462ac6..30bc4c8 100644
--- a/arm_compute/runtime/CPP/CPPScheduler.h
+++ b/arm_compute/runtime/CPP/CPPScheduler.h
@@ -56,10 +56,10 @@
      * - ICPPKernel::is_parallelisable() returns false
      * - The scheduler has been initialized with only one thread.
      *
-     * @param[in] kernel          Kernel to execute.
-     * @param[in] split_dimension Dimension along which to split the kernel's execution window.
+     * @param[in] kernel Kernel to execute.
+     * @param[in] hints  Hints for the scheduler.
      */
-    void schedule(ICPPKernel *kernel, unsigned int split_dimension) override;
+    void schedule(ICPPKernel *kernel, const Hints &hints) override;
 
     /** Will run the workloads in parallel using num_threads
      *
diff --git a/arm_compute/runtime/IScheduler.h b/arm_compute/runtime/IScheduler.h
index 76ff5a3..1f90f4e 100644
--- a/arm_compute/runtime/IScheduler.h
+++ b/arm_compute/runtime/IScheduler.h
@@ -36,6 +36,72 @@
 class IScheduler
 {
 public:
+    /** Strategies available to split a workload */
+    enum class StrategyHint
+    {
+        STATIC,  /**< Split the workload evenly among the threads */
+        DYNAMIC, /**< Split the workload dynamically using a bucket system */
+    };
+    /** Scheduler hints
+     *
+     * Collection of preferences set by the function regarding how to split a given workload
+     */
+    class Hints
+    {
+    public:
+        /** Constructor
+         *
+         * @param[in] split_dimension Dimension along which to split the kernel's execution window.
+         * @param[in] strategy        (Optional) Split strategy.
+         */
+        Hints(unsigned int split_dimension, StrategyHint strategy = StrategyHint::STATIC)
+            : _split_dimension(split_dimension), _strategy(strategy)
+        {
+        }
+        /** Set the split_dimension hint
+         *
+         * @param[in] split_dimension Dimension along which to split the kernel's execution window.
+         *
+         * @return the Hints object
+         */
+        Hints &set_split_dimension(unsigned int split_dimension)
+        {
+            _split_dimension = split_dimension;
+            return *this;
+        }
+        /** Return the prefered split dimension
+         *
+         * @return The split dimension
+         */
+        unsigned int split_dimension() const
+        {
+            return _split_dimension;
+        }
+
+        /** Set the strategy hint
+         *
+         * @param[in] strategy Prefered strategy to use to split the workload
+         *
+         * @return the Hints object
+         */
+        Hints &set_strategy(StrategyHint strategy)
+        {
+            _strategy = strategy;
+            return *this;
+        }
+        /** Return the prefered strategy to use to split workload.
+         *
+         * @return The strategy
+         */
+        StrategyHint strategy() const
+        {
+            return _strategy;
+        }
+
+    private:
+        unsigned int _split_dimension;
+        StrategyHint _strategy;
+    };
     /** Signature for the workloads to execute */
     using Workload = std::function<void(const ThreadInfo &)>;
     /** Default constructor. */
@@ -58,10 +124,10 @@
 
     /** Runs the kernel in the same thread as the caller synchronously.
      *
-     * @param[in] kernel          Kernel to execute.
-     * @param[in] split_dimension Dimension along which to split the kernel's execution window.
+     * @param[in] kernel Kernel to execute.
+     * @param[in] hints  Hints for the scheduler.
      */
-    virtual void schedule(ICPPKernel *kernel, unsigned int split_dimension) = 0;
+    virtual void schedule(ICPPKernel *kernel, const Hints &hints) = 0;
 
     /** Execute all the passed workloads
      *
diff --git a/arm_compute/runtime/OMP/OMPScheduler.h b/arm_compute/runtime/OMP/OMPScheduler.h
index 21df6a6..681a36a 100644
--- a/arm_compute/runtime/OMP/OMPScheduler.h
+++ b/arm_compute/runtime/OMP/OMPScheduler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017-2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -53,10 +53,10 @@
      * - ICPPKernel::is_parallelisable() returns false
      * - The scheduler has been initialized with only one thread.
      *
-     * @param[in] kernel          Kernel to execute.
-     * @param[in] split_dimension Dimension along which to split the kernel's execution window.
+     * @param[in] kernel Kernel to execute.
+     * @param[in] hints  Hints for the scheduler.
      */
-    void schedule(ICPPKernel *kernel, unsigned int split_dimension) override;
+    void schedule(ICPPKernel *kernel, const Hints &hints) override;
 
 private:
     /** Constructor. */
diff --git a/arm_compute/runtime/SingleThreadScheduler.h b/arm_compute/runtime/SingleThreadScheduler.h
index 5672b62..6924601 100644
--- a/arm_compute/runtime/SingleThreadScheduler.h
+++ b/arm_compute/runtime/SingleThreadScheduler.h
@@ -49,10 +49,10 @@
     static SingleThreadScheduler &get();
     /** Runs the kernel in the same thread as the caller synchronously.
      *
-     * @param[in] kernel          Kernel to execute.
-     * @param[in] split_dimension Dimension along which to split the kernel's execution window.
+     * @param[in] kernel Kernel to execute.
+     * @param[in] hints  Hints for the scheduler.
      */
-    void schedule(ICPPKernel *kernel, unsigned int split_dimension) override;
+    void schedule(ICPPKernel *kernel, const Hints &hints) override;
 
     /** Will run the workloads sequentially and in order.
      *