@chapsummary
GPU-accelerated octree based voxel modeling library.  
@endchapsummary

@section OpenCL Process

The algorithms such as rendering, updating the volume, refining the model 
or detecting change are implemented in OpenCL.  Each process is a subclass of
@code{boxm2_opencl_process_base}, which provides three virtual functions: 

@itemize
@item @code{init_kernel(cl_context* context, cl_device_id* device)} : to initialize data members and compile OpenCL source.
@item @code{run(vcl_vector<brdb_value_sptr> & input, vcl_vector<brdb_value_sptr> & output)}:  runs the algorithm. The input and output vectors are used for interfacing with the process.
@item @code{finish()}: to destroy any intermediate data created.
@end itemize

The following processes have been implemented: 
@itemize
@item @code{boxm2_opencl_render_process}: This process renders an expected image of the provided 
model from a given viewpoint. The inputs to such process include scene, camera, and dimensions 
of output image and the output of such a process include expected image. This process uses 
a single pass of ray-tracing to update the volume.

@item @code{boxm2_opencl_update_process}: This process updates the model using an EO image and the 
given sensor model. The inputs to such process include scene, camera, image and the output of 
such a process is updated scene. This process uses multiple passes of ray-tracing to update the 
volume.

@item @code{boxm2_opencl_refine_process}: This process refines the scene. This 
refining results in the scene getting finer at places where the evidence 
of surface increases. The inputs to such process include scene 
and threshold and the output of such a process is updated scene. This process requires 
serial iterating over blocks.
@end itemize

Each process uses inputs as processing inputs and return output if any through output vector. 
The process is light-weight as it only process whats given to it.

@section Boxm2 OpenCL Processor

All data structures and algorithms have been optimized to run on a GPU.  
The GPU processor has been designed as a wrapper around some necessary OpenCL
objects, and allows for a simple interface to processes in boxm2.  The 
Boxm2 OpenCL Processor is also a singleton class, allowing only one to be
instantiated at a time.  

An OpenCL cache has also been implemented in order to handle the incoming 
and outgoing memory on the GPU, as well as ensure that memory allocated does not
surpass the GPU's limits.  


@subsection OpenCL Cache
The OpenCL cache currently maintains one block and its data on GPU memory.  
Whenever a new block is requested, the GPU releases the old block and writes the 
requested block to the device.  

The OpenCL cache returns @code{bocl_mem*} pointers, which are wrappers around 
an OpenCL buffer, its corresponding host memory buffer, its size, a string ID, 
as well as methods to transfer memory between host and device.  

In a future iteration, the OpenCL cache will eventually process the data transfers 
asynchronously, which will hide the latency between host (CPU) and device (GPU) 
data transfers.  


@subsection Example: boxm2_opencl_render_process

The following is an example of how to render a single image 
using the @code{boxm2_opencl_render_process}:
@example
  //set up render camera, image buffer and vis image buffer (for algorithm)
  vpgl_camera_double_sptr cam = pcam;
  brdb_value_sptr brdb_cam = new brdb_value_t<vpgl_camera_double_sptr>(cam);
  vil_image_view<unsigned int>* expimg = new vil_image_view<unsigned int>(ni(), nj());
  expimg->fill(0);
  vil_image_view_base_sptr expimg_sptr(expimg);// = new vil_image_view<unsigned int>(ni(), nj());
  brdb_value_sptr brdb_expimg = new brdb_value_t<vil_image_view_base_sptr>(expimg_sptr);
  vil_image_view<float>* vis_img = new vil_image_view<float>(ni(), nj());
  vis_img->fill(1.0f);
  brdb_value_sptr brdb_vis = new brdb_value_t<vil_image_view_base_sptr>(vis_img);

  //set up scene 
  boxm2_scene_sptr scene = new boxm2_scene(scene_file());
  brdb_value_sptr brdb_scene = new brdb_value_t<boxm2_scene_sptr>(scene);
  boxm2_nn_cache cache = new cache( scene.ptr() );

  //initialize gpu_processor
  boxm2_opencl_processor* gpu_pro = boxm2_opencl_processor::instance();
  gpu_pro->set_scene(scene.ptr());
  gpu_pro->set_cpu_cache(cache);
  gpu_pro->init();

  //set inputs
  vcl_vector<brdb_value_sptr> input;
  input.push_back(brdb_scene);
  input.push_back(brdb_cam);
  input.push_back(brdb_expimg);
  input.push_back(brdb_vis);

  //output vector
  vcl_vector<brdb_value_sptr> output;

  //initialize the GPU render process
  boxm2_opencl_render_process gpu_render;
  gpu_render.init_kernel(&gpu_pro->context(), &gpu_pro->devices()[0]);

  //execute gpu_render process
  gpu_pro->run(&gpu_render, input, output);
  gpu_pro->finish();

  //the brdb_expimg now contains the expected image of 'scene'  

  //clean up
  gpu_render.clean();
  gpu_pro->finish();
@end example
