Ejemplo n.º 1
0
// This program demonstrates buffer filling and mapping in CLplusplus
int main() {
   // Program parameters are defined here
   const cl_ulong buffer_size = 4096;

   // Minimal platform and device parameters are specified here
   const CLplusplus::Version target_version = CLplusplus::version_1p2;
   const cl_ulong min_mem_alloc_size = buffer_size;
   const cl_ulong min_global_mem_size = buffer_size;

   // Have the user select a suitable device, according to some criteria (see shared.hpp for more details)
   const auto selected_platform_and_device = Shared::select_device(
      [&](const CLplusplus::Platform & platform) -> bool {
         return (platform.version() >= target_version);                       // Platform OpenCL version is recent enough
      },
      [&](const CLplusplus::Device & device) -> bool {
         if(device.version() < target_version) return false;                  // OpenCL platforms may support older-generation devices, which we need to eliminate
         const bool device_supports_ooe_execution = device.queue_properties() & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;
         return device.available() &&                                         // Device is available for compute purposes
                device_supports_ooe_execution &&                              // Device can execute OpenCL commands out of order
                (device.max_mem_alloc_size() >= min_mem_alloc_size) &&        // Device accepts large enough global memory allocations
                (device.global_mem_size() >= min_global_mem_size);            // Device has enough global memory
      }
   );

   // Create an OpenCL context on the device with some default parameters (see shared.hpp for more details)
   const auto context = Shared::build_default_context(selected_platform_and_device);

   // Create a small OpenCL buffer
   const auto buffer = context.create_buffer(CL_MEM_READ_WRITE, buffer_size);

   // Create an out-of-order command queue for the device
   const auto command_queue = context.create_command_queue(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE);

   // Start to fill the buffer with a constant pattern
   std::cout << "Filling buffer..." << std::endl;
   const cl_uchar pattern = 0x42;
   const auto fill_event = command_queue.enqueued_fill_buffer(pattern, buffer, 0, buffer_size, {});

   // Ask the buffer to be mapped to host memory once this is done, and synchronize on this event
   cl_uchar * const mapped_buffer = static_cast<cl_uchar *>(command_queue.map_buffer(buffer, 0, buffer_size, CL_MAP_READ, {fill_event}));
   std::cout << "Buffer mapped !" << std::endl;

   // Check that the buffer was filled as expected
   bool fill_error = false;
   for(unsigned int i = 0; i < buffer_size; ++i) {
      if(mapped_buffer[i] != 0x42) {
         std::cout << "Buffer fill error !" << std::endl;
         fill_error = true;
         break;
      }
   }
   if(!fill_error) std::cout << "Buffer was filled up successfully" << std::endl;

   // Unmap the buffer and terminate
   command_queue.enqueue_unmap_mem_object(buffer, mapped_buffer, {});
   command_queue.finish();
   std::cout << "Buffer unmapped !" << std::endl;

   return 0;
}
Ejemplo n.º 2
0
    /// Enqueues a command to unmap \p buffer from the host memory space.
    ///
    /// \see_opencl_ref{clEnqueueUnmapMemObject}
    event enqueue_unmap_buffer(const buffer &buffer,
                               void *mapped_ptr,
                               const wait_list &events = wait_list())
    {
        BOOST_ASSERT(buffer.get_context() == this->get_context());

        return enqueue_unmap_mem_object(buffer.get(), mapped_ptr, events);
    }