<commit_before>/* =======================================================================
   Copyright (c) 2010, Institute for Microelectronics, TU Vienna.
   http://www.iue.tuwien.ac.at
                             -----------------
                     ViennaCL - The Vienna Computing Library
                             -----------------
                            
   authors:    <NAME>                          <EMAIL>
               <NAME>                     <EMAIL>
               <NAME>                      <EMAIL>

   license:    MIT (X11), see file LICENSE in the ViennaCL base directory
======================================================================= */

#ifndef _VIENNACL_CONTEXT_HPP_
#define _VIENNACL_CONTEXT_HPP_

/** @file command_queue.hpp
    @brief Represents an OpenCL context within ViennaCL
*/

#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif

#include <algorithm>
#include <vector>
#include <map>
#include "viennacl/ocl/forwards.h"
#include "viennacl/ocl/handle.hpp"
#include "viennacl/ocl/program.hpp"
#include "viennacl/ocl/device.hpp"
#include "viennacl/ocl/platform.hpp"
#include "viennacl/ocl/command_queue.hpp"

namespace viennacl
{
  namespace ocl
  {
    class context
    {
      typedef std::vector< viennacl::ocl::program >   ProgramContainer;
      
      public:
        context() : initialized_(false), device_type_(CL_DEVICE_TYPE_DEFAULT), current_device_id(0) {}
        
        
        ////////// get and set preferred device type /////////////////////
        /** @brief Returns the default device type for the context */
        cl_device_type default_device_type()
        {
          return device_type_;
        }
        
        /** @brief Sets the device type for this context */
        void default_device_type(cl_device_type dtype) 
        { 
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Setting new device type for context " << h_ << std::endl;
          #endif
          if (!initialized_)
            device_type_ = dtype; //assume that the user provided a correct value
        }
        
        //////////////////// get devices //////////////////
        /** @brief Returns a vector with all devices in this context */
        std::vector<viennacl::ocl::device> const & devices() const
        {
          return devices_;
        }
        
        /** @brief Returns the current device */
        viennacl::ocl::device const & current_device() const
        {
          //std::cout << "Current device id in context: " << current_device_id << std::endl;
          return devices_[current_device_id];
        }
        
        /** @brief Switches the current device to the i-th device in this context */
        void switch_device(size_t i)
        {
          assert(i >= 0 && i < devices_.size());
          current_device_id = i;
        }

        /** @brief If the supplied device is used within the context, it becomes the current active device. */
        void switch_device(viennacl::ocl::device const & d)
        {
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Setting new current device for context " << h_ << std::endl;
          #endif
          bool found = false;
          for (size_t i=0; i<devices_.size(); ++i)
          {
            if (devices_[i] == d)
            {
              found = true;
              current_device_id = i;
              break;
            }
          }
          if (found == false)
            std::cerr << "ViennaCL: Warning: Could not set device " << d.name() << " for context." << std::endl;
        }
        
        /** @brief Add a device to the context. Must be done before the context is initialized */
        void add_device(viennacl::ocl::device const & d)
        {
          assert(!initialized_ && "Device must be added to context before it is initialized!");
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Adding new device to context " << h_ << std::endl;
          #endif
          if (std::find(devices_.begin(), devices_.end(), d) != devices_.end())
            devices_.push_back(d);
        }

        /** @brief Add a device to the context. Must be done before the context is initialized */
        void add_device(cl_device_id d)
        {
          assert(!initialized_ && "Device must be added to context before it is initialized!");
          add_device(viennacl::ocl::device(d));
        }


        /////////////////////// initialize context ///////////////////
        
        /** @brief Initializes a new context */
        void init()
        {
          init_new();
        }

        /** @brief Initializes the context from an existing, user-supplied context */
        void init(cl_context c)
        {
          init_existing(c);
        }

/*        void existing_context(cl_context context_id)
        {
          assert(!initialized_ && "ViennaCL: FATAL error: Provided a new context for an already initialized context.");
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Reusing existing context " << h_ << std::endl;
          #endif
          h_ = context_id;
        }*/
        
        ////////////////////// create memory /////////////////////////////
        /** @brief Creates a memory buffer within the context
        *
        *  @param flags  OpenCL flags for the buffer creation
        *  @param size   Size of the memory buffer in bytes
        *  @param ptr    Optional pointer to CPU memory, with which the OpenCL memory should be initialized
        */
        viennacl::ocl::handle<cl_mem> create_memory(cl_mem_flags flags, unsigned int size, void * ptr = NULL)
        {
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Creating memory of size " << size << " for context " << h_ << std::endl;
          #endif
          if (ptr)
            flags |= CL_MEM_COPY_HOST_PTR;
          cl_int err;
          viennacl::ocl::handle<cl_mem> mem = clCreateBuffer(handle(), flags, size, ptr, &err);
          VIENNACL_ERR_CHECK(err);
          return mem;
        }

        viennacl::ocl::handle<cl_mem> create_image2d(cl_mem_flags flags,const cl_image_format *image_format,unsigned int width,unsigned int height,unsigned row_pitch = 0,void * ptr = NULL)
		{
		  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Creating image of size: " << width << "x" << height << " for context " << h_ << std::endl;
          #endif
          if(ptr)
        	  flags |= CL_MEM_COPY_HOST_PTR;
          cl_int err;
          viennacl::ocl::handle<cl_mem> mem = clCreateImage2D(handle(), flags,image_format, width, height, row_pitch, ptr, &err);
          VIENNACL_ERR_CHECK(err);
          return mem;
		}

        /** @brief Creates a memory buffer within the context initialized from the supplied data
        *<commit_msg>Initialize image2d with cpu allocated memory<commit_after>/* =======================================================================
   Copyright (c) 2010, Institute for Microelectronics, TU Vienna.
   http://www.iue.tuwien.ac.at
                             -----------------
                     ViennaCL - The Vienna Computing Library
                             -----------------
                            
   authors:    <NAME>                          <EMAIL>
               <NAME>                     <EMAIL>
               <NAME>                      <EMAIL>

   license:    MIT (X11), see file LICENSE in the ViennaCL base directory
======================================================================= */

#ifndef _VIENNACL_CONTEXT_HPP_
#define _VIENNACL_CONTEXT_HPP_

/** @file command_queue.hpp
    @brief Represents an OpenCL context within ViennaCL
*/

#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif

#include <algorithm>
#include <vector>
#include <map>
#include "viennacl/ocl/forwards.h"
#include "viennacl/ocl/handle.hpp"
#include "viennacl/ocl/program.hpp"
#include "viennacl/ocl/device.hpp"
#include "viennacl/ocl/platform.hpp"
#include "viennacl/ocl/command_queue.hpp"

namespace viennacl
{
  namespace ocl
  {
    class context
    {
      typedef std::vector< viennacl::ocl::program >   ProgramContainer;
      
      public:
        context() : initialized_(false), device_type_(CL_DEVICE_TYPE_DEFAULT), current_device_id(0) {}
        
        
        ////////// get and set preferred device type /////////////////////
        /** @brief Returns the default device type for the context */
        cl_device_type default_device_type()
        {
          return device_type_;
        }
        
        /** @brief Sets the device type for this context */
        void default_device_type(cl_device_type dtype) 
        { 
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Setting new device type for context " << h_ << std::endl;
          #endif
          if (!initialized_)
            device_type_ = dtype; //assume that the user provided a correct value
        }
        
        //////////////////// get devices //////////////////
        /** @brief Returns a vector with all devices in this context */
        std::vector<viennacl::ocl::device> const & devices() const
        {
          return devices_;
        }
        
        /** @brief Returns the current device */
        viennacl::ocl::device const & current_device() const
        {
          //std::cout << "Current device id in context: " << current_device_id << std::endl;
          return devices_[current_device_id];
        }
        
        /** @brief Switches the current device to the i-th device in this context */
        void switch_device(size_t i)
        {
          assert(i >= 0 && i < devices_.size());
          current_device_id = i;
        }

        /** @brief If the supplied device is used within the context, it becomes the current active device. */
        void switch_device(viennacl::ocl::device const & d)
        {
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Setting new current device for context " << h_ << std::endl;
          #endif
          bool found = false;
          for (size_t i=0; i<devices_.size(); ++i)
          {
            if (devices_[i] == d)
            {
              found = true;
              current_device_id = i;
              break;
            }
          }
          if (found == false)
            std::cerr << "ViennaCL: Warning: Could not set device " << d.name() << " for context." << std::endl;
        }
        
        /** @brief Add a device to the context. Must be done before the context is initialized */
        void add_device(viennacl::ocl::device const & d)
        {
          assert(!initialized_ && "Device must be added to context before it is initialized!");
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Adding new device to context " << h_ << std::endl;
          #endif
          if (std::find(devices_.begin(), devices_.end(), d) != devices_.end())
            devices_.push_back(d);
        }

        /** @brief Add a device to the context. Must be done before the context is initialized */
        void add_device(cl_device_id d)
        {
          assert(!initialized_ && "Device must be added to context before it is initialized!");
          add_device(viennacl::ocl::device(d));
        }


        /////////////////////// initialize context ///////////////////
        
        /** @brief Initializes a new context */
        void init()
        {
          init_new();
        }

        /** @brief Initializes the context from an existing, user-supplied context */
        void init(cl_context c)
        {
          init_existing(c);
        }

/*        void existing_context(cl_context context_id)
        {
          assert(!initialized_ && "ViennaCL: FATAL error: Provided a new context for an already initialized context.");
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Reusing existing context " << h_ << std::endl;
          #endif
          h_ = context_id;
        }*/
        
        ////////////////////// create memory /////////////////////////////
        /** @brief Creates a memory buffer within the context
        *
        *  @param flags  OpenCL flags for the buffer creation
        *  @param size   Size of the memory buffer in bytes
        *  @param ptr    Optional pointer to CPU memory, with which the OpenCL memory should be initialized
        */
        viennacl::ocl::handle<cl_mem> create_memory(cl_mem_flags flags, unsigned int size, void * ptr = NULL)
        {
          #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Creating memory of size " << size << " for context " << h_ << std::endl;
          #endif
          if (ptr)
            flags |= CL_MEM_COPY_HOST_PTR;
          cl_int err;
          viennacl::ocl::handle<cl_mem> mem = clCreateBuffer(handle(), flags, size, ptr, &err);
          VIENNACL_ERR_CHECK(err);
          return mem;
        }

        viennacl::ocl::handle<cl_mem> create_image2d(cl_mem_flags flags,const cl_image_format *image_format,unsigned int width,unsigned int height,void * ptr = NULL, unsigned row_pitch = 0)
		{
		  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
          std::cout << "ViennaCL: Creating image of size: " << width << "x" << height << " for context " << h_ << std::endl;
          #endif
          if(ptr)
        	  flags |= CL_MEM_COPY_HOST_PTR;
          cl_int err;
          viennacl::ocl::handle<cl_mem> mem = clCreateImage2D(handle(), flags,image_format, width, height, row_pitch, ptr, &err);
          VIENNACL_ERR_CHECK(err);
          return mem;
		}

        /** @brief Creates a memory buffer within the context initialized from the supplied data
        *
{'fraction_non_alphanumeric': 0.1455134525989576, 'fraction_numerical': 0.0017608113818847724, 'mean_word_length': 1.9186022610483042, 'pattern_counts': {'":': 0, '<': 165, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '482967', 'n_tokens_mistral': 4006, 'n_tokens_neox': 3826, 'n_words': 1082}