Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:19:07

0001 /** CLVisc C++ Version by LongGang Pang 
0002  * Served as a c++ wrapper for JetScape
0003  * This file wrap the commonly used OpenCL functionalities*/
0004 #ifndef __OPENCL_BACKEND_H__
0005 #define __OPENCL_BACKEND_H__
0006 
0007 #define __CL_ENABLE_EXCEPTIONS
0008 //#if defined(__APPLE__) || defined(__MACOSX)
0009 //#include <OpenCL/cl.hpp>
0010 //#else
0011 //#include <CL/cl.hpp>
0012 //#endif
0013 #include "cl.hpp"
0014 #include "Config.h"
0015 
0016 #include <map>
0017 #include <ctime>
0018 #include <algorithm>
0019 #include <random>
0020 #include <string>
0021 #include <sstream>
0022 #include <iostream>
0023 #include <iomanip>
0024 #include <fstream>
0025 #include <type_traits>
0026 
0027 namespace clvisc {
0028 
0029 #ifdef USE_SINGLE_PRECISION
0030 /*!< typedef cl_float to cl_real for easier switch from double to float */
0031  typedef cl_float cl_real;
0032  typedef cl_float2 cl_real2;
0033  typedef cl_float4 cl_real4;
0034  typedef cl_float3 cl_real3;
0035  typedef cl_float8 cl_real8;
0036 #else
0037  typedef cl_double cl_real;
0038  typedef cl_double2 cl_real2;
0039  typedef cl_double4 cl_real4;
0040  typedef cl_double3 cl_real3;
0041  typedef cl_double8 cl_real8;
0042 #endif
0043 
0044 
0045 /* compile options to build opencl kernel files on device*/
0046 class CompileOption {
0047     public:
0048         std::stringstream opt;
0049 
0050         CompileOption();
0051         /*! \breif if you see strange behaviour in opencl, please
0052          *  set compilation option optimize=false */
0053         CompileOption(bool use_single_precision, bool optimize);
0054 
0055 
0056         /*! \breif return the string in the CompileOption */
0057         std::string str();
0058 
0059         void Define(std::string name);
0060         void SetDoubleConst(std::string name, double value);
0061         void SetFloatConst(std::string name, float value);
0062         void SetIntConst(std::string name, int value);
0063         void KernelIncludePath(std::string abs_path);
0064 };
0065 
0066 class OpenclBackend {
0067   public:
0068     OpenclBackend(std::string device_type, int device_id);
0069 
0070     // make context_ and queue_ public in case one wants 
0071     // to use the native opencl APIs.
0072     cl::Context context_;
0073     cl::CommandQueue queue_;
0074 
0075     std::map<std::string, cl::Program> programs;
0076     std::map<std::string, cl::Kernel> kernel_funcs;
0077     std::map<std::string, cl::Buffer> buffers;
0078 
0079     /*!\breif helper functions: Build each program in programs vector with given options
0080     *  \note The compiling error of the kernel *.cl can be print out
0081     */
0082     cl::Program BuildProgram(std::string fname, const std::string & option);
0083 
0084     cl::Kernel CreateKernel(const cl::Program & prg, std::string func_name) {
0085         return cl::Kernel(prg, func_name.c_str());
0086     }
0087 
0088     /*! \breif return gpu context */
0089     inline cl::Context Context() {return context_;};
0090 
0091     /*! \breif return command queue */
0092     inline cl::CommandQueue Queue() {return queue_;};
0093 
0094     /*! \breif printout the available devices*/
0095     void DeviceInfo();
0096 
0097     /*! \breif printout the device type, CL_DEVICE_TYPE_CPU or  CL_DEVICE_TYPE_GPU*/
0098     cl_int DeviceType();
0099  
0100     /*! \breif utility to compute the excution time of one event */
0101     float ExcutionTime(cl::Event & event);
0102 
0103     /*! \breif create a buffer on GPU, e.g., for one cl_real array of N elements,
0104      * the bytes_of_buffer = N * sizeof(cl_real) */
0105     cl::Buffer CreateBuffer(size_t bytes_of_buffer);
0106 
0107     /*! \breif create a image2d_t buffer on GPU by copying host point*/
0108     cl::Image2D CreateImage2DByCopyVector(std::vector<cl_float4> & source_vector,
0109                                           size_t width, size_t height, bool read_only);
0110 
0111     /*! \breif create a buffer on GPU, with the same size and content as source_vector 
0112     Notice: the cl.hpp does not support creating buffers from (const void *);
0113     so one can not use const std::vector<ValueType> & source_vector here */
0114     template <typename ValueType>
0115     cl::Buffer CreateBufferByCopyVector(std::vector<ValueType> & source_vector,
0116                                         bool read_only);
0117 
0118     void enqueue_run(const cl::Kernel  & kernel_,
0119                      const cl::NDRange & global_size,
0120                      const cl::NDRange & local_size);
0121 
0122     template <typename ValueType>
0123     void enqueue_copy(const std::vector<ValueType> & src_vector,  cl::Buffer & dst_buffer);
0124 
0125     template <typename ValueType>
0126     void enqueue_copy(const cl::Buffer & src_buffer, std::vector<ValueType> & dst_vector);
0127 
0128     // copy cl::Buffer to cl::Buffer
0129     void enqueue_copy(const cl::Buffer & src_buffer, cl::Buffer & dst_buffer, size_t size);
0130   private:
0131     cl_int device_type_;
0132     std::vector<cl::Device> devices_;
0133     cl_int device_id_;
0134     cl::Device device_;
0135     /*! \breif helper functions: create context from the device type with one platform which support it 
0136      * \return one context in the type of cl::Context
0137      */
0138     cl::Context CreateContext_(const cl_int & device_type);
0139     
0140     /*! \breif CreateContext, AddProgram, Build program, Initialize Buffer*/
0141 };
0142 
0143 } // end namespace clvisc
0144 
0145 #endif