COMPMID-545 add CL printf support

Change-Id: I685a68e7bc8d2cdff19851d839f244206b3d5790
Reviewed-on: http://mpd-gerrit.cambridge.arm.com/89391
Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
diff --git a/arm_compute/core/CL/OpenCL.h b/arm_compute/core/CL/OpenCL.h
index 897e936..151cc9b 100644
--- a/arm_compute/core/CL/OpenCL.h
+++ b/arm_compute/core/CL/OpenCL.h
@@ -83,6 +83,7 @@
     using clGetDeviceInfo_func           = cl_int (*)(cl_device_id, cl_device_info, size_t, void *, size_t *);
     using clGetDeviceIDs_func            = cl_int (*)(cl_platform_id, cl_device_type, cl_uint, cl_device_id *, cl_uint *);
     using clRetainEvent_func             = cl_int (*)(cl_event);
+    using clGetPlatformIDs_func          = cl_int (*)(cl_uint, cl_platform_id *, cl_uint *);
 
     clBuildProgram_func            clBuildProgram            = nullptr;
     clEnqueueNDRangeKernel_func    clEnqueueNDRangeKernel    = nullptr;
@@ -113,6 +114,7 @@
     clGetDeviceInfo_func           clGetDeviceInfo           = nullptr;
     clGetDeviceIDs_func            clGetDeviceIDs            = nullptr;
     clRetainEvent_func             clRetainEvent             = nullptr;
+    clGetPlatformIDs_func          clGetPlatformIDs          = nullptr;
 
 private:
     std::pair<bool, bool> _loaded{ false, false };
diff --git a/arm_compute/runtime/CL/CLScheduler.h b/arm_compute/runtime/CL/CLScheduler.h
index 11affeb..1a7befc 100644
--- a/arm_compute/runtime/CL/CLScheduler.h
+++ b/arm_compute/runtime/CL/CLScheduler.h
@@ -32,6 +32,28 @@
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/CL/CLTuner.h"
 
+#if defined(ARM_COMPUTE_DEBUG_ENABLED)
+namespace
+{
+void printf_callback(const char *buffer, unsigned int len, size_t complete, void *user_data)
+{
+    printf("%.*s", len, buffer);
+}
+
+// Create a cl_context with a printf_callback and user specified buffer size.
+cl_context_properties properties[] =
+{
+    // Enable a printf callback function for this context.
+    CL_PRINTF_CALLBACK_ARM, reinterpret_cast<cl_context_properties>(printf_callback),
+    // Request a minimum printf buffer size of 4MB for devices in the
+    // context that support this extension.
+    CL_PRINTF_BUFFERSIZE_ARM, static_cast<cl_context_properties>(0x100000),
+    CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(cl::Platform::get()()),
+    0
+};
+}
+#endif /* defined(ARM_COMPUTE_DEBUG_ENABLED) */
+
 namespace arm_compute
 {
 class ICLKernel;
@@ -60,6 +82,10 @@
      */
     void default_init(ICLTuner *cl_tuner = nullptr)
     {
+#if defined(ARM_COMPUTE_DEBUG_ENABLED)
+        cl::Context::setDefault(cl::Context(CL_DEVICE_TYPE_DEFAULT, properties));
+#endif // defined(ARM_COMPUTE_DEBUG_ENABLED)
+
         CLKernelLibrary::get().init("./cl_kernels/", cl::Context::getDefault(), cl::Device::getDefault());
         init(cl::Context::getDefault(), cl::CommandQueue::getDefault(), cl::Device::getDefault(), cl_tuner);
     }