(git:98357aa)
Loading...
Searching...
No Matches
grid_gpu_context.h
Go to the documentation of this file.
1/*----------------------------------------------------------------------------*/
2/* CP2K: A general program to perform molecular dynamics simulations */
3/* Copyright 2000-2026 CP2K developers group <https://cp2k.org> */
4/* */
5/* SPDX-License-Identifier: BSD-3-Clause */
6/*----------------------------------------------------------------------------*/
7
8/*
9 * Authors :
10 - Dr Mathieu Taillefumier (ETH Zurich / CSCS)
11 - Advanced Micro Devices, Inc.
12*/
13
14#ifndef GRID_GPU_CONTEXT_H
15#define GRID_GPU_CONTEXT_H
16
17#ifdef __OFFLOAD_HIP
18#include <hip/hip_runtime_api.h>
19#else
20#include <cuda_runtime.h>
21#endif
22#include <array>
23#include <vector>
24
25extern "C" {
26#include "../common/grid_basis_set.h"
27#include "../common/grid_constants.h"
28}
29
30#include "../../offload/offload_library.h"
31#include "../../offload/offload_runtime.h"
32
33namespace rocm_backend {
34// a little helper class in the same spirit than std::vector. it must exist
35// somewhere. Maybe possible to get the same thing with std::vector and
36// specific allocator.
37
38inline size_t round_up16(size_t n) { return (n + 15) & ~size_t(15); }
39
40class smem_parameters;
41template <typename T> class gpu_vector {
42 size_t allocated_size_{0};
43 size_t current_size_{0};
44 bool internal_allocation_{false};
45 T *device_ptr_{nullptr};
46 T *host_ptr_{nullptr};
47
48 void move_from(gpu_vector &&other) noexcept {
49 allocated_size_ = other.allocated_size_;
50 current_size_ = other.current_size_;
51 internal_allocation_ = other.internal_allocation_;
52 device_ptr_ = other.device_ptr_;
53 host_ptr_ = other.host_ptr_;
54
55 other.allocated_size_ = 0;
56 other.current_size_ = 0;
57 other.internal_allocation_ = false;
58 other.device_ptr_ = nullptr;
59 other.host_ptr_ = nullptr;
60 }
61
62public:
63 gpu_vector() = default;
64
65 gpu_vector(const gpu_vector &) = delete;
66 gpu_vector &operator=(const gpu_vector &) = delete;
67
68 gpu_vector(gpu_vector &&other) noexcept { move_from(std::move(other)); }
69
70 gpu_vector &operator=(gpu_vector &&other) noexcept {
71 if (this != &other) {
72 reset();
73 move_from(std::move(other));
74 }
75 return *this;
76 }
77
78 // size is the number of elements not the memory size
79 explicit gpu_vector(const size_t size__) {
80 allocated_size_ = (size__ < 16) ? 16 : round_up16(size__);
81 current_size_ = size__;
82 internal_allocation_ = true;
83
84#ifndef __OFFLOAD_UNIFIED_MEMORY
85 offloadMalloc((void **)&device_ptr_, sizeof(T) * allocated_size_);
86#else
87 hipMallocManaged((void **)&device_ptr_, sizeof(T) * allocated_size_);
88#endif
89 assert(device_ptr_ != nullptr);
90 }
91
92 gpu_vector(const size_t size__, void *ptr__) {
93 allocated_size_ = size__;
94 current_size_ = size__;
95 internal_allocation_ = false;
96 device_ptr_ = static_cast<T *>(ptr__);
97 }
99
100 inline size_t size() const { return current_size_; }
101
102 inline void copy_to_gpu(const T *data__) {
103 assert(device_ptr_ != nullptr);
104 assert(data__ != nullptr);
105 offloadMemcpyHtoD(device_ptr_, data__, sizeof(T) * current_size_);
106 }
107
108 inline void copy_to_gpu(const T *data__, offloadStream_t &stream__) {
109 assert(device_ptr_ != nullptr);
110 assert(data__ != nullptr);
111 offloadMemcpyAsyncHtoD(device_ptr_, data__, sizeof(T) * current_size_,
112 stream__);
113 }
114
115 inline void copy_associated_host_to_gpu(offloadStream_t &stream__) {
116 assert(device_ptr_ != nullptr);
117 assert(host_ptr_ != nullptr);
118 // If the second assert fails it means that the object was created without
119 // host buffer. It should not happen in the current scenario
120
121 offloadMemcpyAsyncHtoD(device_ptr_, host_ptr_, sizeof(T) * current_size_,
122 stream__);
123 }
124
125 inline void copy_from_gpu(T *data__, offloadStream_t &stream__) {
126 assert(device_ptr_ != nullptr);
127 assert(data__ != nullptr);
128 offloadMemcpyAsyncDtoH(data__, device_ptr_, sizeof(T) * current_size_,
129 stream__);
130 }
131
132 inline void copy_gpu_to_associated_host(offloadStream_t &stream__) {
133 assert(device_ptr_ != nullptr);
134 assert(host_ptr_ != nullptr);
135 // If the second assert fails it means that the object was created without
136 // host buffer. It should not happen in the current scenario
137
138 offloadMemcpyAsyncDtoH(host_ptr_, device_ptr_, sizeof(T) * current_size_,
139 stream__);
140 }
141
142 inline void zero(offloadStream_t &stream__) {
143 assert(device_ptr_ != nullptr);
144 // zero device grid buffers
145 offloadMemsetAsync(device_ptr_, 0, sizeof(T) * current_size_, stream__);
146 }
147
148 inline void associate(void *host_ptr__, void *device_ptr__,
149 const size_t size__) {
150 assert(host_ptr__ != nullptr);
151 assert(device_ptr__ != nullptr);
152 reset();
153 internal_allocation_ = false;
154 allocated_size_ = size__;
155 current_size_ = size__;
156 device_ptr_ = static_cast<T *>(device_ptr__);
157 host_ptr_ = static_cast<T *>(host_ptr__);
158 }
159
160 inline void zero() {
161 // zero device grid buffers
162 offloadMemset(device_ptr_, 0, sizeof(T) * current_size_);
163 }
164
165 inline void copy_to_gpu(const std::vector<T> &data__) {
166 assert(data__.size() == current_size_);
167 // if it fails it means that the vector on the gpu does not have the right
168 // size. two option then
169 // - resize the gpu vector
170 // - or the cpu vector and gpu vector are not representing the quantity.
171 assert(device_ptr_ != nullptr);
172 offloadMemcpyHtoD(device_ptr_, data__.data(), sizeof(T) * data__.size());
173 }
174
175 inline void resize(const size_t new_size__) {
176 if (!internal_allocation_) {
177 allocated_size_ = 0;
178 device_ptr_ = nullptr;
179 host_ptr_ = nullptr;
180 }
181
182 assert(new_size__ != 0);
183 if (allocated_size_ < new_size__) {
184 if (internal_allocation_ && device_ptr_ != nullptr)
185 offloadFree(device_ptr_);
186 device_ptr_ = nullptr;
187 allocated_size_ = (new_size__ < 16) ? 16 : round_up16(new_size__);
188 offloadMalloc((void **)&device_ptr_, sizeof(T) * allocated_size_);
189 internal_allocation_ = true;
190 host_ptr_ = nullptr;
191 }
192 assert(device_ptr_ != nullptr);
193 current_size_ = new_size__;
194 }
195
196 // does not invalidate the pointer. The memory is still allocated
197 inline void clear() { current_size_ = 0; }
198
199 // reset the class and free memory
200 inline void reset() {
201 if (internal_allocation_ && (device_ptr_ != nullptr)) {
202 offloadFree(device_ptr_);
203 }
204
205 allocated_size_ = 0;
206 current_size_ = 0;
207 device_ptr_ = nullptr;
208 host_ptr_ = nullptr;
209 internal_allocation_ = false;
210 }
211
212 inline T *data() { return device_ptr_; }
213 inline const T *data() const { return device_ptr_; }
214};
215
216template <typename T> class grid_info {
217private:
218 int3 full_size_;
219 int3 local_size_;
220 // origin of the local part of the grid in grid point
221 int3 lower_corner_;
222 int3 border_width_;
223 std::array<T, 9> dh_;
224 std::array<T, 9> dh_inv_;
225 bool orthogonal_{false};
226 bool is_distributed_{false};
227 gpu_vector<T> grid_;
228
229public:
230 grid_info(const grid_info &) = delete;
231 grid_info &operator=(const grid_info &) = delete;
232
233 grid_info(grid_info &&) noexcept = default;
234 grid_info &operator=(grid_info &&) noexcept = default;
235
237
238 grid_info(const int *full_size__, const int *local_size__,
239 const int *border_width__) {
240 int roffset__[3] = {0, 0, 0};
241 initialize(full_size__, local_size__, roffset__, border_width__);
242 }
243
244 ~grid_info() = default;
245
246 inline void copy_to_gpu(const T *data, offloadStream_t &stream) {
247 assert(data != nullptr);
248 grid_.copy_to_gpu(data, stream);
249 }
250
251 inline void copy_to_gpu(offloadStream_t &stream) {
252 grid_.copy_associated_host_to_gpu(stream);
253 }
254
255 inline void reset() { grid_.reset(); }
256
257 /*
258 * We do not allocate memory as the buffer is always coming from the outside
259 * world. We only initialize the sizes, etc...
260 */
261 inline void resize(const int *full_size__, const int *local_size__,
262 const int *const roffset__,
263 const int *const border_width__) {
264 initialize(full_size__, local_size__, roffset__, border_width__);
265 }
266
267 inline size_t size() const { return grid_.size(); }
268
269 inline void zero(offloadStream_t &stream) { grid_.zero(stream); }
270
271 inline void set_lattice_vectors(const T *dh__, const T *dh_inv__) {
272 for (int i = 0; i < 9; ++i) {
273 dh_[i] = dh__[i];
274 dh_inv_[i] = dh_inv__[i];
275 }
276 }
277
278 inline void is_distributed(const bool distributed__) {
279 is_distributed_ = distributed__;
280 }
281
282 /// Check if the lattice vectors form a orthogonal basis
283 void check_orthogonality(const bool ortho) {
284 if (ortho) {
285 orthogonal_ = true;
286 return;
287 }
288 T norm1, norm2, norm3;
289 bool orthogonal[3] = {false, false, false};
290 norm1 = dh_[0] * dh_[0] + dh_[1] * dh_[1] + dh_[2] * dh_[2];
291 norm2 = dh_[3] * dh_[3] + dh_[4] * dh_[4] + dh_[5] * dh_[5];
292 norm3 = dh_[6] * dh_[6] + dh_[7] * dh_[7] + dh_[8] * dh_[8];
293
294 norm1 = 1.0 / sqrt(norm1);
295 norm2 = 1.0 / sqrt(norm2);
296 norm3 = 1.0 / sqrt(norm3);
297
298 /* x z */
299 orthogonal[0] =
300 ((fabs(dh_[0] * dh_[6] + dh_[1] * dh_[7] + dh_[2] * dh_[8]) * norm1 *
301 norm3) < 1e-12);
302 /* y z */
303 orthogonal[1] =
304 ((fabs(dh_[3] * dh_[6] + dh_[4] * dh_[7] + dh_[5] * dh_[8]) * norm2 *
305 norm3) < 1e-12);
306 /* x y */
307 orthogonal[2] =
308 ((fabs(dh_[0] * dh_[3] + dh_[1] * dh_[4] + dh_[2] * dh_[5]) * norm1 *
309 norm2) < 1e-12);
310
311 orthogonal_ = orthogonal[0] && orthogonal[1] && orthogonal[2];
312 }
313
314 inline void copy_to_host(T *data__, offloadStream_t &stream) {
315 assert(data__ != nullptr);
316 grid_.copy_from_gpu(data__, stream);
317 }
318
319 inline void copy_to_host(offloadStream_t &stream) {
320 grid_.copy_gpu_to_associated_host(stream);
321 }
322
323 inline void associate(void *host_ptr__, void *device_ptr__,
324 const size_t size__) {
325 assert(host_ptr__ != nullptr);
326 assert(device_ptr__ != nullptr);
327 grid_.associate(host_ptr__, device_ptr__, size__);
328 }
329 inline bool is_distributed() { return is_distributed_; }
330
331 inline int3 &full_size() { return full_size_; }
332
333 inline int3 &local_size() { return local_size_; }
334
335 inline int3 &lower_corner() { return lower_corner_; }
336
337 inline int3 &border_width() { return border_width_; }
338
339 inline T *data() { return grid_.data(); }
340 inline const T *data() const { return grid_.data(); }
341
342 inline gpu_vector<T> &grid() { return grid_; }
343 inline const gpu_vector<T> &grid() const { return grid_; }
344
345 inline T *dh() { return dh_.data(); }
346 inline const T *dh() const { return dh_.data(); }
347
348 inline T *dh_inv() { return dh_inv_.data(); }
349 inline const T *dh_inv() const { return dh_inv_.data(); }
350
351 inline bool is_orthogonal() const { return orthogonal_; }
352 inline bool is_distributed() const { return is_distributed_; }
353
354private:
355 void initialize(const int *const full_size__, const int *const local_size__,
356 const int *const roffset__, const int *const border_width__) {
357 // the calling code store things like this cube[z][y][x] (in fortran
358 // cube(x,y,z)).
359
360 full_size_.x = full_size__[0];
361 full_size_.y = full_size__[1];
362 full_size_.z = full_size__[2];
363
364 local_size_.x = local_size__[0];
365 local_size_.y = local_size__[1];
366 local_size_.z = local_size__[2];
367
368 lower_corner_.x = roffset__[0];
369 lower_corner_.y = roffset__[1];
370 lower_corner_.z = roffset__[2];
371
372 is_distributed_ = (full_size_.x != local_size_.x) ||
373 (full_size_.y != local_size_.y) ||
374 (full_size_.z != local_size_.z);
375
376 border_width_.x = border_width__[0];
377 border_width_.y = border_width__[1];
378 border_width_.z = border_width__[2];
379 }
380};
381
382/*******************************************************************************
383 * \brief Internal representation of a task.
384 ******************************************************************************/
416
417/*******************************************************************************
418 * \brief Device buffers used by the collocate and integrate kernels.
419 * Which fields are non-null depends on which kernel is launched.
420 ******************************************************************************/
422 double *pab_block{nullptr};
423 double *grid{nullptr};
424 double *coef{nullptr};
425 double *hab_block{nullptr};
426 double *forces{nullptr};
427 double *virial{nullptr};
428 double *cab{nullptr};
429};
430
431/*******************************************************************************
432 * \brief Parameters of the collocate kernel.
433 ******************************************************************************/
434
437 // max size of cab.
438 int cab_size_{0};
439 int3 grid_full_size_ = make_int3(0, 0, 0);
440 int3 grid_local_size_ = make_int3(0, 0, 0);
441 int3 grid_lower_corner_ = make_int3(0, 0, 0);
442 int3 grid_border_width_ = make_int3(0, 0, 0);
443 double dh_[9];
444 double dh_inv_[9];
446 int *block_offsets{nullptr};
447 char la_min_diff{0};
448 char lb_min_diff{0};
449 char la_max_diff{0};
450 char lb_max_diff{0};
453 double **sphi_dev{nullptr};
454 int ntasks{0};
458 int *cab_block_offset_dev{nullptr};
459};
460
461/* regroup all information about the context. */
463private:
464 int device_id_{-1};
465 int lmax_{0};
466 unsigned int checksum_{0};
467
468public:
469 int ntasks{0};
470 int nlevels{0};
471 int natoms{0};
472 int nkinds{0};
473 int nblocks{0};
475 std::vector<double *> sphi;
476 std::vector<offloadStream_t> level_streams;
477 offloadStream_t main_stream;
478 int stats[2][20]; // [has_border_mask][lp]
479 // all these tables are on the gpu. we can resize them copy to them and copy
480 // from them
491 std::vector<grid_info<double>> grid_;
493 std::vector<int> first_task_per_level_;
494 std::vector<int> sphi_size;
497 bool calculate_forces{false};
498 bool calculate_virial{false};
499 bool compute_tau{false};
500 bool apply_border_mask{false};
501 // Default constructor
502 context_info() = default;
503
504 explicit context_info(int device_id__) {
505 device_id_ = (device_id__ < 0) ? 0 : device_id__;
506 }
507
509
510 // Non-copyable
511 context_info(const context_info &) = delete;
513
514 // Movable
515 context_info(context_info &&other) noexcept
516 : device_id_{other.device_id_}, lmax_{other.lmax_},
517 checksum_{other.checksum_}, ntasks{other.ntasks},
518 nlevels{other.nlevels}, natoms{other.natoms}, nkinds{other.nkinds},
519 nblocks{other.nblocks}, cab_size_per_block_{other.cab_size_per_block_},
520 sphi{std::move(other.sphi)},
521 level_streams{std::move(other.level_streams)},
522 main_stream{other.main_stream},
523 block_offsets_dev{std::move(other.block_offsets_dev)},
524 cab_block_offset_dev{std::move(other.cab_block_offset_dev)},
525 coef_dev_{std::move(other.coef_dev_)},
526 cab_dev_{std::move(other.cab_dev_)},
527 pab_block_{std::move(other.pab_block_)},
528 hab_block_{std::move(other.hab_block_)},
529 forces_{std::move(other.forces_)}, virial_{std::move(other.virial_)},
530 tasks_dev{std::move(other.tasks_dev)},
531 num_tasks_per_block_dev_{std::move(other.num_tasks_per_block_dev_)},
532 grid_{std::move(other.grid_)},
533 number_of_tasks_per_level_{std::move(other.number_of_tasks_per_level_)},
534 first_task_per_level_{std::move(other.first_task_per_level_)},
535 sphi_size{std::move(other.sphi_size)},
536 sphi_dev{std::move(other.sphi_dev)},
537 task_sorted_by_blocks_dev{std::move(other.task_sorted_by_blocks_dev)},
538 sorted_blocks_offset_dev{std::move(other.sorted_blocks_offset_dev)},
539 calculate_forces{other.calculate_forces},
540 calculate_virial{other.calculate_virial},
541 compute_tau{other.compute_tau},
542 apply_border_mask{other.apply_border_mask} {
543
544 // copy stats
545 for (int i = 0; i < 2; ++i)
546 for (int j = 0; j < 20; ++j)
547 stats[i][j] = other.stats[i][j];
548
549 // leave other in a safe state (no ownership)
550 other.device_id_ = -1;
551 other.lmax_ = 0;
552 other.checksum_ = 0;
553 other.ntasks = 0;
554 other.nlevels = 0;
555 other.natoms = 0;
556 other.nkinds = 0;
557 other.nblocks = 0;
558 other.main_stream = {};
559 other.calculate_forces = false;
560 other.calculate_virial = false;
561 other.compute_tau = false;
562 other.apply_border_mask = false;
563 }
564
566 if (this != &other) {
567 clear(); // free current GPU resources and streams
568
569 device_id_ = other.device_id_;
570 lmax_ = other.lmax_;
571 checksum_ = other.checksum_;
572 ntasks = other.ntasks;
573 nlevels = other.nlevels;
574 natoms = other.natoms;
575 nkinds = other.nkinds;
576 nblocks = other.nblocks;
577 sphi = std::move(other.sphi);
578 level_streams = std::move(other.level_streams);
579 main_stream = other.main_stream;
580
581 for (int i = 0; i < 2; ++i)
582 for (int j = 0; j < 20; ++j)
583 stats[i][j] = other.stats[i][j];
584
585 block_offsets_dev = std::move(other.block_offsets_dev);
586 cab_block_offset_dev = std::move(other.cab_block_offset_dev);
587 coef_dev_ = std::move(other.coef_dev_);
588 cab_dev_ = std::move(other.cab_dev_);
589 pab_block_ = std::move(other.pab_block_);
590 hab_block_ = std::move(other.hab_block_);
591 forces_ = std::move(other.forces_);
592 virial_ = std::move(other.virial_);
593 tasks_dev = std::move(other.tasks_dev);
594 num_tasks_per_block_dev_ = std::move(other.num_tasks_per_block_dev_);
595 grid_ = std::move(other.grid_);
596 number_of_tasks_per_level_ = std::move(other.number_of_tasks_per_level_);
597 first_task_per_level_ = std::move(other.first_task_per_level_);
598 sphi_size = std::move(other.sphi_size);
599 sphi_dev = std::move(other.sphi_dev);
600 task_sorted_by_blocks_dev = std::move(other.task_sorted_by_blocks_dev);
601 sorted_blocks_offset_dev = std::move(other.sorted_blocks_offset_dev);
602
603 calculate_forces = other.calculate_forces;
604 calculate_virial = other.calculate_virial;
605 compute_tau = other.compute_tau;
606 apply_border_mask = other.apply_border_mask;
607
608 // reset other
609 other.device_id_ = -1;
610 other.lmax_ = 0;
611 other.checksum_ = 0;
612 other.ntasks = 0;
613 other.nlevels = 0;
614 other.natoms = 0;
615 other.nkinds = 0;
616 other.nblocks = 0;
617 other.main_stream = {};
618 other.calculate_forces = false;
619 other.calculate_virial = false;
620 other.compute_tau = false;
621 other.apply_border_mask = false;
622 }
623 return *this;
624 }
625
626 void clear() {
627 if (device_id_ >= 0) {
628 offload_set_chosen_device(device_id_);
629 offload_activate_chosen_device();
630 }
631
632 tasks_dev.reset();
636 cab_dev_.reset();
639 sphi_dev.reset();
640 forces_.reset();
641 virial_.reset();
642
643 for (auto &phi : sphi) {
644 if (phi != nullptr)
645 offloadFree(phi);
646 }
647 sphi.clear();
648
649 if (main_stream) {
650 offloadStreamDestroy(main_stream);
651 main_stream = {};
652 }
653
654 for (auto &stream : level_streams) {
655 if (stream)
656 offloadStreamDestroy(stream);
657 }
658 level_streams.clear();
659
660 for (auto &g : grid_) {
661 g.reset();
662 }
663 grid_.clear();
664 }
665
666 int lmax() const { return lmax_; }
667
668 void initialize_basis_sets(const grid_basis_set **basis_sets,
669 const int nkinds__) {
670 nkinds = nkinds__;
671 if (nkinds__ > (int)sphi.size()) {
672 for (auto &phi : sphi)
673 if (phi != nullptr) {
674 offloadFree(phi);
675 }
676
677 sphi_dev.resize(nkinds__);
678
679 sphi.resize(nkinds__, nullptr);
680 sphi_size.clear();
681 sphi_size.resize(nkinds__, 0);
682 sphi_dev.resize(nkinds__);
683 }
684
685 // Upload basis sets to device.
686 for (int i = 0; i < nkinds__; i++) {
687 const auto &basis_set = basis_sets[i];
688 if (sphi_size[i] < basis_set->nsgf * basis_set->maxco) {
689 offloadMalloc((void **)&sphi[i],
690 basis_set->nsgf * basis_set->maxco * sizeof(double));
691 sphi_size[i] = basis_set->nsgf * basis_set->maxco;
692 }
693 // offloadMemset(sphi[i], 0, sizeof(double) * sphi_size[i]);
694 offloadMemcpyHtoD(sphi[i], basis_set->sphi,
695 basis_set->nsgf * basis_set->maxco * sizeof(double));
696 }
698 // Find largest angular momentum.
699 lmax_ = 0;
700 for (int ikind = 0; ikind < nkinds; ikind++) {
701 for (int iset = 0; iset < basis_sets[ikind]->nset; iset++) {
702 lmax_ = std::max(lmax_, basis_sets[ikind]->lmax[iset]);
703 }
704 }
705 }
706
708 // allocate main hip stream
709 offloadStreamCreate(&main_stream);
710
711 // allocate one hip stream per grid level
712 if ((int)level_streams.size() < nlevels) {
713 level_streams.resize(nlevels);
714 for (auto &stream : level_streams) {
715 offloadStreamCreate(&stream);
716 }
717 }
718 }
719
720 void synchronize(offloadStream_t &stream) {
721 offloadStreamSynchronize(stream);
722 }
723
724 void synchornize() {
725 // wait for all the streams to finish
726 offloadDeviceSynchronize();
727 }
728
729 void set_device() {
730 offload_set_chosen_device(device_id_);
731 offload_activate_chosen_device();
732 }
733
734 void collocate_one_grid_level(const int level, const enum grid_func func,
735 int *lp_diff);
736 void integrate_one_grid_level(const int level, int *lp_diff);
738 /* basic checksum computation for simple verification that the object is sane
739 */
740 void compute_checksum() { checksum_ = compute_checksum_(); }
742 if (checksum_ != compute_checksum_()) {
743 fprintf(stderr, "This object does not seem to have the right structure.\n"
744 "A casting went wrong or the object is corrupted\n");
745 abort();
746 }
747 }
748 void calculate_all_coefficients(const enum grid_func func, int *lp_diff);
749
750private:
751 kernel_params set_kernel_parameters(const int level,
752 const smem_parameters &smem_params);
753 unsigned int compute_checksum_() {
754 return natoms ^ ntasks ^ nlevels ^ nkinds ^ nblocks ^ 0x4F2C5D1A;
755 }
756};
757} // namespace rocm_backend
758#endif
std::vector< int > first_task_per_level_
void calculate_all_coefficients(const enum grid_func func, int *lp_diff)
gpu_vector< double > virial_
gpu_vector< int > sorted_blocks_offset_dev
gpu_vector< double > coef_dev_
gpu_vector< int > cab_block_offset_dev
gpu_vector< double > pab_block_
void collocate_one_grid_level(const int level, const enum grid_func func, int *lp_diff)
Launches the Cuda kernel that collocates all tasks of one grid level.
gpu_vector< int > block_offsets_dev
void synchronize(offloadStream_t &stream)
context_info(context_info &&other) noexcept
gpu_vector< double > cab_dev_
gpu_vector< task_info > tasks_dev
context_info & operator=(const context_info &)=delete
std::vector< grid_info< double > > grid_
gpu_vector< double > forces_
gpu_vector< double > hab_block_
std::vector< double * > sphi
std::vector< offloadStream_t > level_streams
void initialize_basis_sets(const grid_basis_set **basis_sets, const int nkinds__)
std::vector< int > number_of_tasks_per_level_
gpu_vector< double * > sphi_dev
context_info & operator=(context_info &&other) noexcept
gpu_vector< int > num_tasks_per_block_dev_
context_info(const context_info &)=delete
void integrate_one_grid_level(const int level, int *lp_diff)
Launches the Cuda kernel that integrates all tasks of one grid level.
gpu_vector< int > task_sorted_by_blocks_dev
gpu_vector & operator=(gpu_vector &&other) noexcept
void zero(offloadStream_t &stream__)
void copy_associated_host_to_gpu(offloadStream_t &stream__)
gpu_vector(const size_t size__)
void resize(const size_t new_size__)
void copy_from_gpu(T *data__, offloadStream_t &stream__)
void copy_gpu_to_associated_host(offloadStream_t &stream__)
void associate(void *host_ptr__, void *device_ptr__, const size_t size__)
gpu_vector(const size_t size__, void *ptr__)
void copy_to_gpu(const std::vector< T > &data__)
void copy_to_gpu(const T *data__, offloadStream_t &stream__)
gpu_vector & operator=(const gpu_vector &)=delete
gpu_vector(const gpu_vector &)=delete
void copy_to_gpu(const T *data__)
gpu_vector(gpu_vector &&other) noexcept
void zero(offloadStream_t &stream)
grid_info(grid_info &&) noexcept=default
void copy_to_gpu(const T *data, offloadStream_t &stream)
void check_orthogonality(const bool ortho)
Check if the lattice vectors form a orthogonal basis.
void copy_to_host(T *data__, offloadStream_t &stream)
gpu_vector< T > & grid()
grid_info & operator=(const grid_info &)=delete
grid_info(const grid_info &)=delete
void copy_to_gpu(offloadStream_t &stream)
void copy_to_host(offloadStream_t &stream)
void resize(const int *full_size__, const int *local_size__, const int *const roffset__, const int *const border_width__)
const gpu_vector< T > & grid() const
void associate(void *host_ptr__, void *device_ptr__, const size_t size__)
grid_info(const int *full_size__, const int *local_size__, const int *border_width__)
void is_distributed(const bool distributed__)
void set_lattice_vectors(const T *dh__, const T *dh_inv__)
grid_func
static void const int const int i
size_t round_up16(size_t n)
Internal representation of a basis set.
Device buffers used by the collocate and integrate kernels. Which fields are non-null depends on whic...
Parameters of the collocate kernel.
Internal representation of a task.