Loading [MathJax]/extensions/tex2jax.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
GpuParticleData.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014-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#pragma once
21
22#include "config/config.hpp"
23
24#ifdef CUDA
25
26#include "ParticleRange.hpp"
28#include "system/Leaf.hpp"
29
30#include <utils/Vector.hpp>
31
32#include <bitset>
33#include <cstddef>
34#include <memory>
35#include <span>
36
37/**
38 * @brief Particle data communication manager for the GPU.
39 *
40 * When data is synchronized between host and device memory, a subset
41 * of the @ref Particle struct is copied from each particle on the host
42 * to the corresponding @ref GpuParticle struct on the device via
43 * @ref GpuParticleData::update(). Once the transfer is complete,
44 * the particle AoS on the device is copied (or "split") to a SoA
45 * automatically.
46 *
47 * Note that once a particle member is requested, the corresponding device
48 * memory is allocated and populated at every time step, even when the GPU
49 * method that originally requested the data is disabled.
50 */
51class GpuParticleData : public System::Leaf<GpuParticleData> {
52public:
53 /** @brief Particle properties that need to be communicated to the GPU. */
54 struct prop {
55 static constexpr std::size_t pos = 0;
56 static constexpr std::size_t force = 1;
57 static constexpr std::size_t torque = 2;
58 static constexpr std::size_t q = 3;
59 static constexpr std::size_t dip = 4;
60 using bitset = std::bitset<5>;
61 };
62
63 /** @brief Energies that are retrieved from the GPU. */
64 struct GpuEnergy {
66 };
67
68 /** @brief Subset of @ref Particle which is copied to the GPU. */
69 struct GpuParticle {
71#ifdef DIPOLES
73#endif
74#ifdef ELECTROSTATICS
75 float q;
76#endif
78 };
79
80private:
81 // forward declare
82 class Storage;
83 /** @brief Whether a device was found and data structures were allocated. */
84 bool m_communication_enabled = false;
85 /** @brief Whether to convert particle properties from AoS to SoA. */
86 bool m_split_particle_struct = false;
87 /** @brief Whether particle transfer to the GPU was requested. */
88 bool m_need_particles_update = false;
89 /** @brief Host and device containers. */
90 std::shared_ptr<Storage> m_data;
91
92 bool has_compatible_device_impl() const;
93 void gpu_init_particle_comm();
94 void enable_particle_transfer();
95 void copy_particles_to_device();
96 void copy_particles_to_device(ParticleRange const &particles, int this_node);
97 /** @brief Collect particles from all nodes to the head node. */
98 void gather_particle_data(ParticleRange const &particles,
99 pinned_vector<GpuParticle> &particle_data_host,
100 int this_node);
101 void particles_scatter_forces(ParticleRange const &particles,
102 std::span<float> host_forces,
103 std::span<float> host_torques) const;
104
105public:
106 GpuParticleData() = default;
107 ~GpuParticleData() = default;
108
109 void update() {
110 if (m_need_particles_update and m_communication_enabled) {
111 copy_particles_to_device();
112 }
113 }
114 void initialize();
115 void enable_property(std::size_t property);
117 void copy_forces_to_host(ParticleRange const &particles, int this_node);
118 std::size_t n_particles() const;
119 bool has_compatible_device() const;
120
121 GpuEnergy copy_energy_to_host() const;
122 GpuEnergy *get_energy_device() const;
123 float *get_particle_positions_device() const;
124 float *get_particle_forces_device() const;
125#ifdef ROTATION
126 float *get_particle_torques_device() const;
127#endif
128#ifdef DIPOLES
129 float *get_particle_dipoles_device() const;
130#endif
131#ifdef ELECTROSTATICS
132 float *get_particle_charges_device() const;
133#endif
134};
135
136#endif // CUDA
std::vector< T, CudaHostAllocator< T > > pinned_vector
Vector implementation and trait types for boost qvm interoperability.
Host and device containers for particle data.
Particle data communication manager for the GPU.
~GpuParticleData()=default
float * get_particle_torques_device() const
float * get_particle_charges_device() const
void copy_forces_to_host(ParticleRange const &particles, int this_node)
GpuEnergy * get_energy_device() const
float * get_particle_dipoles_device() const
float * get_particle_forces_device() const
GpuEnergy copy_energy_to_host() const
void enable_property(std::size_t property)
std::size_t n_particles() const
bool has_compatible_device() const
GpuParticleData()=default
float * get_particle_positions_device() const
A range of particles.
Abstract class that represents a component of the system.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
int this_node
The number of this node.
This file contains the defaults for ESPResSo.
static auto gather_particle_data(BoxGeometry const &box_geo, ParticleRange const &particles)
Energies that are retrieved from the GPU.
Subset of Particle which is copied to the GPU.
Particle properties that need to be communicated to the GPU.
static constexpr std::size_t force
static constexpr std::size_t torque
std::bitset< 5 > bitset
static constexpr std::size_t pos
static constexpr std::size_t dip
static constexpr std::size_t q