SIRIUS 7.5.0
Electronic structure library and applications
create_beta_gk.cu
Go to the documentation of this file.
1// Copyright (c) 2013-2018 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file create_beta_gk.cu
21 *
22 * \brief CUDA kernel for the generation of beta(G+k) projectors.
23 */
24
27
28#ifdef SIRIUS_CUDA
30#endif
31
32using namespace sirius;
33using namespace sirius::acc;
34
35template <typename T>
36__global__ void create_beta_gk_gpu_kernel
37(
38 int num_gkvec__,
39 int const* beta_desc__,
40 gpu_complex_type<T> const* beta_gk_t,
41 double const* gkvec,
42 double const* atom_pos,
43 gpu_complex_type<T>* beta_gk
44);
45
46template <>
47__global__ void create_beta_gk_gpu_kernel<float>
48(
49 int num_gkvec__,
50 int const* beta_desc__,
51 acc_complex_float_t const* beta_gk_t,
52 double const* gkvec,
53 double const* atom_pos,
54 acc_complex_float_t* beta_gk
55)
56{
57 int ia = blockIdx.y;
58 int igk = blockDim.x * blockIdx.x + threadIdx.x;
59
60 int nbf = beta_desc__[array2D_offset(0, ia, 4)];
61 int offset_beta_gk = beta_desc__[array2D_offset(1, ia, 4)];
62 int offset_beta_gk_t = beta_desc__[array2D_offset(2, ia, 4)];
63
64 if (igk < num_gkvec__) {
65 float p = 0;
66 for (int x = 0; x < 3; x++) {
67 p += atom_pos[array2D_offset(x, ia, 3)] * gkvec[array2D_offset(x, igk, 3)];
68 }
69 p *= twopi;
70
71 float sinp = sin(p);
72 float cosp = cos(p);
73
74 for (int xi = 0; xi < nbf; xi++) {
75 beta_gk[array2D_offset(igk, offset_beta_gk + xi, num_gkvec__)] =
76 accCmulf(beta_gk_t[array2D_offset(igk, offset_beta_gk_t + xi, num_gkvec__)],
77 make_accFloatComplex(cosp, -sinp));
78 }
79 }
80}
81
82template <>
83__global__ void create_beta_gk_gpu_kernel<double>
84(
85 int num_gkvec__,
86 int const* beta_desc__,
87 acc_complex_double_t const* beta_gk_t,
88 double const* gkvec,
89 double const* atom_pos,
90 acc_complex_double_t* beta_gk
91)
92{
93 int ia = blockIdx.y;
94 int igk = blockDim.x * blockIdx.x + threadIdx.x;
95
96 int nbf = beta_desc__[array2D_offset(0, ia, 4)];
97 int offset_beta_gk = beta_desc__[array2D_offset(1, ia, 4)];
98 int offset_beta_gk_t = beta_desc__[array2D_offset(2, ia, 4)];
99
100 if (igk < num_gkvec__) {
101 double p = 0;
102 for (int x = 0; x < 3; x++) {
103 p += atom_pos[array2D_offset(x, ia, 3)] * gkvec[array2D_offset(x, igk, 3)];
104 }
105 p *= twopi;
106
107 double sinp = sin(p);
108 double cosp = cos(p);
109
110 for (int xi = 0; xi < nbf; xi++) {
111 beta_gk[array2D_offset(igk, offset_beta_gk + xi, num_gkvec__)] =
112 accCmul(beta_gk_t[array2D_offset(igk, offset_beta_gk_t + xi, num_gkvec__)],
113 make_accDoubleComplex(cosp, -sinp));
114 }
115 }
116}
117
118extern "C" void create_beta_gk_gpu_float(int num_atoms,
119 int num_gkvec,
120 int const* beta_desc,
121 acc_complex_float_t const* beta_gk_t,
122 double const* gkvec,
123 double const* atom_pos,
124 acc_complex_float_t* beta_gk)
125{
126#ifdef SIRIUS_CUDA
127 CUDA_timer t("create_beta_gk_gpu");
128#endif
129
130 dim3 grid_t(64);
131 dim3 grid_b(num_blocks(num_gkvec, grid_t.x), num_atoms);
132
133 accLaunchKernel((create_beta_gk_gpu_kernel<float>), dim3(grid_b), dim3(grid_t), 0, 0,
134 num_gkvec,
135 beta_desc,
136 beta_gk_t,
137 gkvec,
138 atom_pos,
139 beta_gk
140 );
141}
142
143extern "C" void create_beta_gk_gpu_double(int num_atoms,
144 int num_gkvec,
145 int const* beta_desc,
146 acc_complex_double_t const* beta_gk_t,
147 double const* gkvec,
148 double const* atom_pos,
149 acc_complex_double_t* beta_gk)
150{
151#ifdef SIRIUS_CUDA
152 CUDA_timer t("create_beta_gk_gpu");
153#endif
154
155 dim3 grid_t(64);
156 dim3 grid_b(num_blocks(num_gkvec, grid_t.x), num_atoms);
157
158 accLaunchKernel((create_beta_gk_gpu_kernel<double>), dim3(grid_b), dim3(grid_t), 0, 0,
159 num_gkvec,
160 beta_desc,
161 beta_gk_t,
162 gkvec,
163 atom_pos,
164 beta_gk
165 );
166}
167
Common device functions used by GPU kernels.
Uniform interface to the runtime API of CUDA and ROCm.
Timer for CUDA kernels.
Namespace for accelerator-related functions.
Definition: acc.cpp:30
Namespace of the SIRIUS library.
Definition: sirius.f90:5