ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
barnes_hut_gpu.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "config/config.hpp"
21
22#ifdef DIPOLAR_BARNES_HUT
23
26
27#include "communication.hpp"
28#include "cuda/utils.hpp"
29#include "errorhandling.hpp"
31#include "system/System.hpp"
32
33DipolarBarnesHutGpu::DipolarBarnesHutGpu(double prefactor, double epssq,
34 double itolsq) {
36 m_epssq = epssq;
37 m_itolsq = itolsq;
38 if (m_itolsq <= 0.) {
39 throw std::domain_error("Parameter 'itolsq' must be > 0");
40 }
41 if (m_epssq <= 0.) {
42 throw std::domain_error("Parameter 'epssq' must be > 0");
43 }
44}
45
47 auto &gpu_particle_data = get_system().gpu;
48 gpu_particle_data.enable_property(GpuParticleData::prop::force);
49 gpu_particle_data.enable_property(GpuParticleData::prop::torque);
50 gpu_particle_data.enable_property(GpuParticleData::prop::pos);
51 gpu_particle_data.enable_property(GpuParticleData::prop::dip);
52 if (this_node == 0) {
53 setBHPrecision(static_cast<float>(m_epssq), static_cast<float>(m_itolsq));
54 }
55}
56
57template <class... Args, class... ArgRef>
58int call_kernel(void (*fp)(Args...), ArgRef &&...args) {
59 int error_code = ES_ERROR;
60 try {
61 fp(args...);
62 error_code = ES_OK;
63 } catch (std::runtime_error const &err) {
64 runtimeErrorMsg() << "DipolarBarnesHutGpu: " << err.what();
65 }
66 return error_code;
67}
68
69int DipolarBarnesHutGpu::initialize_data_structure() {
70 auto &gpu = get_system().gpu;
71 auto const n_part = static_cast<int>(gpu.n_particles());
72 auto const error_code = call_kernel(allocBHmemCopy, n_part, &m_bh_data);
73
74 if (error_code == ES_OK) {
75 auto const positions_device = gpu.get_particle_positions_device();
76 auto const dipoles_device = gpu.get_particle_dipoles_device();
77 fill_bh_data(positions_device, dipoles_device, &m_bh_data);
78 initBHgpu(m_bh_data.blocks);
79 buildBoxBH(m_bh_data.blocks);
80 buildTreeBH(m_bh_data.blocks);
81 summarizeBH(m_bh_data.blocks);
82 sortBH(m_bh_data.blocks);
83 }
84
85 return error_code;
86}
87
89 auto &gpu_particle_data = get_system().gpu;
90 gpu_particle_data.update();
91 if (this_node == 0) {
92 if (initialize_data_structure() == ES_OK) {
93 auto forces_device = gpu_particle_data.get_particle_forces_device();
94 auto torques_device = gpu_particle_data.get_particle_torques_device();
95 call_kernel(forceBH, &m_bh_data, static_cast<float>(prefactor),
96 forces_device, torques_device);
97 }
98 }
99}
100
102 auto &gpu_particle_data = get_system().gpu;
103 gpu_particle_data.update();
104 if (this_node == 0) {
105 if (initialize_data_structure() == ES_OK) {
106 auto energy = &(gpu_particle_data.get_energy_device()->dipolar);
107 call_kernel(energyBH, &m_bh_data, static_cast<float>(prefactor), energy);
108 }
109 }
110}
111
112#endif // DIPOLAR_BARNES_HUT
int call_kernel(void(*fp)(Args...), ArgRef &&...args)
void buildBoxBH(int blocks)
Building Barnes-Hut spatial min/max position box.
void setBHPrecision(float epssq, float itolsq)
Barnes-Hut parameters setter.
void energyBH(BHData *bh_data, float k, float *E)
Barnes-Hut energy calculation.
void forceBH(BHData *bh_data, float k, float *f, float *torque)
Barnes-Hut force calculation.
void initBHgpu(int blocks)
Barnes-Hut CUDA initialization.
void summarizeBH(int blocks)
Calculate octant cells masses and cell index counts. Determine cells centers of mass and total dipole...
void allocBHmemCopy(int nbodies, BHData *bh_data)
An allocation of the GPU device memory and an initialization where it is needed.
void sortBH(int blocks)
Sort particle indexes according to the Barnes-Hut tree representation. Crucial for the per-warp perfo...
void fill_bh_data(float const *r, float const *dip, BHData const *bh_data)
Copy Barnes-Hut data to bhpara and copy particle data.
void buildTreeBH(int blocks)
Building Barnes-Hut tree in a linear child array representation of octant cells and particles inside.
double prefactor
Magnetostatics prefactor.
int this_node
The number of this node.
This file contains the defaults for ESPResSo.
#define ES_OK
error code if no error occurred
Definition constants.hpp:78
#define ES_ERROR
error code if an error occurred
Definition constants.hpp:80
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
#define runtimeErrorMsg()
int blocks
CUDA blocks.
DipolarBarnesHutGpu(double prefactor, double epssq, double itolsq)
void on_activation() const
static constexpr std::size_t force
static constexpr std::size_t torque
static constexpr std::size_t pos
static constexpr std::size_t dip