epicf / ef

Low-energy charged particles' dynamics simulation using particle-in-cell method
MIT License
11 stars 9 forks source link

Port computational part to GPU #17

Open noooway opened 5 years ago

noooway commented 5 years ago

Single GPU should be sufficient for a start. CUDA can be used.

A general idea is to define pointers in each class that would hold data about that class on GPU, e.g.

class Time_grid {
  public:
    double total_time, current_time;
    double time_step_size;
    double time_save_step;
    double *total_time_gpu, *current_time_gpu;
    double *time_step_size_gpu;
    double *time_step_step_gpu;
   .....

Then define methods that would allocate memory on GPU and transfer data to and from GPU

class Time_grid {
 .....
  public:
    .....
    void allocate_on_gpu();
    void transfer_to_gpu();
    void transfer_from_gpu();
    ......

Then duplicate all computational methods to perform on GPU. Those methods are supposed to call CUDA kernels.

class Time_grid {
 .....
  public:
  .....
  void update_to_next_step();
  void update_to_next_time_step_gpu();
  .....

Finally, it should be necessary to replace all calls to update methods to calls to update_on_gpu methods and perform data transfer from GPU to CPU when saving on disk is required

void Domain::run_pic()
{
    .....
    for ( int i = current_node; i < total_time_iterations; i++ ){
        std::cout << "Time step from " << i << " to " << i+1
                  << " of " << total_time_iterations << std::endl;
        advance_one_time_step_on_gpu();
        transfer_from_gpu_and_write_step_to_save();
    }
.....
}