GGEMS  1.1
GPU GEant4-based Monte Carlo Simulations
GGEMSParticles.cc
Go to the documentation of this file.
1 // ************************************************************************
2 // * This file is part of GGEMS. *
3 // * *
4 // * GGEMS is free software: you can redistribute it and/or modify *
5 // * it under the terms of the GNU General Public License as published by *
6 // * the Free Software Foundation, either version 3 of the License, or *
7 // * (at your option) any later version. *
8 // * *
9 // * GGEMS is distributed in the hope that it will be useful, *
10 // * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 // * GNU General Public License for more details. *
13 // * *
14 // * You should have received a copy of the GNU General Public License *
15 // * along with GGEMS. If not, see <https://www.gnu.org/licenses/>. *
16 // * *
17 // ************************************************************************
18 
35 
39 
41 : number_of_particles_(nullptr),
42  primary_particles_(nullptr),
43  kernel_alive_(nullptr)
44 {
45  GGcout("GGEMSParticles", "GGEMSParticles", 3) << "GGEMSParticles creating..." << GGendl;
46 
47  GGcout("GGEMSParticles", "GGEMSParticles", 3) << "GGEMSParticles created!!!" << GGendl;
48 }
49 
53 
55 {
56  GGcout("GGEMSParticles", "~GGEMSParticles", 3) << "GGEMSParticles erasing..." << GGendl;
57 
59 
61  delete[] number_of_particles_;
62  number_of_particles_ = nullptr;
63  }
64 
65  if (primary_particles_) {
66  for (GGsize i = 0; i < number_activated_devices_; ++i) {
67  opencl_manager.Deallocate(primary_particles_[i], sizeof(GGEMSPrimaryParticles), i);
68  opencl_manager.Deallocate(status_[i], sizeof(GGint), i);
69  }
70  delete[] primary_particles_;
71  primary_particles_ = nullptr;
72  delete[] status_;
73  status_ = nullptr;
74  }
75 
76  if (kernel_alive_) {
77  delete[] kernel_alive_;
78  kernel_alive_ = nullptr;
79  }
80 
81  GGcout("GGEMSParticles", "~GGEMSParticles", 3) << "GGEMSParticles erased!!!" << GGendl;
82 }
83 
87 
88 void GGEMSParticles::SetNumberOfParticles(GGsize const& thread_index, GGsize const& number_of_particles)
89 {
90  number_of_particles_[thread_index] = number_of_particles;
91 }
92 
96 
98 {
99  GGcout("GGEMSParticles", "InitializeKernel", 3) << "Initializing kernel..." << GGendl;
100 
101  // Getting the path to kernel
102  std::string openCL_kernel_path = OPENCL_KERNEL_PATH;
103  std::string filename = openCL_kernel_path + "/IsAlive.cl";
104 
105 
106  // Storing a kernel for each device
107  kernel_alive_ = new cl::Kernel*[number_activated_devices_];
108 
109  // Compiling the kernel
111 
112  // Compiling kernel on each device
113  opencl_manager.CompileKernel(filename, "is_alive", kernel_alive_, nullptr, nullptr);
114 }
115 
119 
121 {
122  GGcout("GGEMSParticles", "Initialize", 1) << "Initialization of GGEMSParticles..." << GGendl;
123 
125 
126  // Get number of activated device
128 
130 
131  // Allocation of the PrimaryParticle structure
133 
134  // Initializing kernel
136 }
137 
141 
142 bool GGEMSParticles::IsAlive(GGsize const& thread_index) const
143 {
144  // Get command queue and event
146  cl::CommandQueue* queue = opencl_manager.GetCommandQueue(thread_index);
147  cl::Event* event = opencl_manager.GetEvent(thread_index);
148 
149  // Get Device name and storing methode name + device
150  GGsize device_index = opencl_manager.GetIndexOfActivatedDevice(thread_index);
151  std::string device_name = opencl_manager.GetDeviceName(device_index);
152  std::ostringstream oss(std::ostringstream::out);
153  oss << "GGEMSParticles::IsAlive on " << device_name << ", index " << device_index;
154 
155  // Get the OpenCL buffers
156  cl::Buffer* particles = primary_particles_[thread_index];
157  cl::Buffer* status = status_[thread_index];
158 
159  // Getting work group size, and work-item number
160  GGsize work_group_size = opencl_manager.GetWorkGroupSize();
161  GGsize number_of_work_items = opencl_manager.GetBestWorkItem(number_of_particles_[thread_index]);
162 
163  // Parameters for work-item in kernel
164  cl::NDRange global_wi(number_of_work_items);
165  cl::NDRange local_wi(work_group_size);
166 
167  // Set parameters for kernel
168  kernel_alive_[thread_index]->setArg(0, number_of_particles_[thread_index]);
169  kernel_alive_[thread_index]->setArg(1, *particles);
170  kernel_alive_[thread_index]->setArg(2, *status);
171 
172  // Launching kernel
173  GGint kernel_status = queue->enqueueNDRangeKernel(*kernel_alive_[thread_index], 0, global_wi, local_wi, nullptr, event);
174  opencl_manager.CheckOpenCLError(kernel_status, "GGEMSParticles", "IsAlive");
175 
176  // GGEMS Profiling
178  profiler_manager.HandleEvent(*event, oss.str());
179  queue->finish();
180 
181  // Get status from OpenCL device
182  GGint* status_device = opencl_manager.GetDeviceBuffer<GGint>(status_[thread_index], sizeof(GGint), thread_index);
183 
184  GGint status_from_device = status_device[0];
185 
186  // Release the pointer
187  opencl_manager.ReleaseDeviceBuffer(status_[thread_index], status_device, thread_index);
188 
189  // Cleaning buffer
190  opencl_manager.CleanBuffer(status_[thread_index], sizeof(GGint), thread_index);
191 
192  if (status_from_device == static_cast<GGint>(number_of_particles_[thread_index])) return false;
193  else return true;
194 }
195 
199 
201 {
202  GGcout("GGEMSParticles", "AllocatePrimaryParticles", 1) << "Allocation of primary particles..." << GGendl;
203 
204  // Get the OpenCL manager
206 
208  status_ = new cl::Buffer*[number_activated_devices_];
209 
210  // Loop over activated device and allocate particle buffer on each device
211  for (GGsize i = 0; i < number_activated_devices_; ++i) {
212  primary_particles_[i] = opencl_manager.Allocate(nullptr, sizeof(GGEMSPrimaryParticles), i, CL_MEM_READ_WRITE, "GGEMSParticles");
213  status_[i] = opencl_manager.Allocate(nullptr, sizeof(GGint), i, CL_MEM_READ_WRITE, "GGEMSParticles");
214  opencl_manager.CleanBuffer(status_[i], sizeof(GGint), i);
215  }
216 }
GGEMSRAMManager.hh
GGEMS class handling RAM memory.
GGEMSParticles::GGEMSParticles
GGEMSParticles(void)
GGEMSParticles constructor.
Definition: GGEMSParticles.cc:40
GGEMSParticles::AllocatePrimaryParticles
void AllocatePrimaryParticles(void)
Allocate memory for primary particles.
Definition: GGEMSParticles.cc:200
GGEMSParticles::IsAlive
bool IsAlive(GGsize const &thread_index) const
check if some particles are alive in OpenCL particle buffer
Definition: GGEMSParticles.hh:116
GGEMSOpenCLManager::GetNumberOfActivatedDevice
GGsize GetNumberOfActivatedDevice(void) const
get the number of activated devices
Definition: GGEMSOpenCLManager.hh:167
GGEMSParticles::Initialize
void Initialize(void)
Initialize the GGEMSParticles object.
Definition: GGEMSParticles.cc:120
GGEMSPrimaryParticles_t
Structure storing informations about primary particles.
Definition: GGEMSPrimaryParticles.hh:42
GGEMSProfilerManager::GetInstance
static GGEMSProfilerManager & GetInstance(void)
Create at first time the Singleton.
Definition: GGEMSProfilerManager.hh:66
GGEMSParticles::primary_particles_
cl::Buffer ** primary_particles_
Definition: GGEMSParticles.hh:148
GGEMSOpenCLManager::CheckOpenCLError
void CheckOpenCLError(GGint const &error, std::string const &class_name, std::string const &method_name) const
check the OpenCL error
Definition: GGEMSOpenCLManager.cc:1048
GGEMSParticles::number_of_particles_
GGsize * number_of_particles_
Definition: GGEMSParticles.hh:147
GGEMSOpenCLManager::GetBestWorkItem
GGsize GetBestWorkItem(GGsize const &number_of_elements) const
get the best number of work item
Definition: GGEMSOpenCLManager.cc:1030
GGEMSOpenCLManager::GetEvent
cl::Event * GetEvent(GGsize const &thread_index) const
return an event to activated context
Definition: GGEMSOpenCLManager.hh:230
GGEMSOpenCLManager::Deallocate
void Deallocate(cl::Buffer *buffer, GGsize size, GGsize const &thread_index, std::string const &class_name="Undefined")
Deallocation of OpenCL memory.
Definition: GGEMSOpenCLManager.cc:981
GGEMSOpenCLManager::ReleaseDeviceBuffer
void ReleaseDeviceBuffer(cl::Buffer *const device_ptr, T *host_ptr, GGsize const &thread_index)
Get the device pointer on host to write on it. Mandatory after a GetDeviceBufferWrite ou GetDeviceBuf...
Definition: GGEMSOpenCLManager.hh:495
GGEMSParticles::SetNumberOfParticles
void SetNumberOfParticles(GGsize const &thread_index, GGsize const &number_of_particles)
Set the number of particles in buffer.
Definition: GGEMSParticles.hh:100
GGsize
#define GGsize
Definition: GGEMSTypes.hh:252
GGEMSParticles::~GGEMSParticles
~GGEMSParticles(void)
GGEMSParticles destructor.
Definition: GGEMSParticles.cc:54
GGint
#define GGint
Definition: GGEMSTypes.hh:224
GGEMSOpenCLManager::CleanBuffer
void CleanBuffer(cl::Buffer *buffer, GGsize const &size, GGsize const &thread_index)
Cleaning buffer on OpenCL device.
Definition: GGEMSOpenCLManager.cc:998
GGEMSParticles::number_activated_devices_
GGsize number_activated_devices_
Definition: GGEMSParticles.hh:150
GGEMSProfilerManager
GGEMS class managing profiler data.
Definition: GGEMSProfilerManager.hh:48
GGEMSOpenCLManager::GetWorkGroupSize
GGsize GetWorkGroupSize(void) const
Get the work group size defined in GGEMS on activated OpenCL context.
Definition: GGEMSOpenCLManager.hh:198
GGEMSPrimaryParticles.hh
Structure storing the primary particle buffers for both OpenCL and GGEMS.
GGEMSOpenCLManager::Allocate
cl::Buffer * Allocate(void *host_ptr, GGsize const &size, GGsize const &thread_index, cl_mem_flags flags, std::string const &class_name="Undefined")
Allocation of OpenCL memory.
Definition: GGEMSOpenCLManager.cc:945
GGEMSOpenCLManager::CompileKernel
void CompileKernel(std::string const &kernel_filename, std::string const &kernel_name, cl::Kernel **kernel_list, char *const custom_options=nullptr, char *const additional_options=nullptr)
Compile the OpenCL kernel on the activated device.
Definition: GGEMSOpenCLManager.cc:849
GGEMSParticles::InitializeKernel
void InitializeKernel(void)
Initialize kernel for particle in OpenCL.
Definition: GGEMSParticles.cc:97
GGcout
GGEMSStream GGcout
Definition: GGEMSPrint.cc:34
GGEMSSourceManager.hh
GGEMS class handling the source(s)
GGEMSOpenCLManager::GetDeviceBuffer
T * GetDeviceBuffer(cl::Buffer *device_ptr, GGsize const &size, GGsize const &thread_index)
Get the device pointer on host to write on it. ReleaseDeviceBuffer must be used after this method!...
Definition: GGEMSOpenCLManager.hh:480
GGendl
#define GGendl
overload C++ std::endl
Definition: GGEMSPrint.hh:60
GGEMSOpenCLManager
Singleton class storing all informations about OpenCL and managing GPU/CPU devices,...
Definition: GGEMSOpenCLManager.hh:54
GGEMSOpenCLManager::GetDeviceName
std::string GetDeviceName(GGsize const &device_index) const
Get the name of the activated device.
Definition: GGEMSOpenCLManager.hh:145
GGEMSProfilerManager.hh
GGEMS class managing profiler data.
GGEMSProfilerManager::HandleEvent
void HandleEvent(cl::Event event, std::string const &profile_name)
handle an OpenCL event in profile_name type
Definition: GGEMSProfilerManager.cc:75
GGEMSOpenCLManager::GetIndexOfActivatedDevice
GGsize GetIndexOfActivatedDevice(GGsize const &thread_index) const
get the index of activated device
Definition: GGEMSOpenCLManager.hh:175
GGEMSParticles::kernel_alive_
cl::Kernel ** kernel_alive_
Definition: GGEMSParticles.hh:151
GGEMSOpenCLManager::GetCommandQueue
cl::CommandQueue * GetCommandQueue(GGsize const &thread_index) const
Return the command queue to activated context.
Definition: GGEMSOpenCLManager.hh:222
GGEMSOpenCLManager::GetInstance
static GGEMSOpenCLManager & GetInstance(void)
Create at first time the Singleton.
Definition: GGEMSOpenCLManager.hh:72
GGEMSParticles::status_
cl::Buffer ** status_
Definition: GGEMSParticles.hh:149