1 /*-------------------------------------------------------------------
2 Copyright 2012 Ravishankar Sundararaman
3 
4 This file is part of JDFTx.
5 
6 JDFTx 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 JDFTx 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 JDFTx.  If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #include <core/GpuKernelUtils.h>
21 #include <electronic/ExCorr_internal.h>
22 #include <electronic/ExCorr_internal_LDA.h>
23 #include <electronic/ExCorr_internal_GGA.h>
24 #include <electronic/ExCorr_internal_mGGA.h>
25 
26 //---------------- Spin-density-matrix transformations for noncollinear magentism --------------------
27 
28 __global__
spinDiagonalize_kernel(int N,array<const double *,4> n,array<const double *,4> x,array<double *,2> xDiag)29 void spinDiagonalize_kernel(int N, array<const double*,4> n, array<const double*,4> x, array<double*,2> xDiag)
30 {	int i = kernelIndex1D();
31 	if(i<N) spinDiagonalize_calc(i, n, x, xDiag);
32 }
spinDiagonalize_gpu(int N,std::vector<const double * > n,std::vector<const double * > x,std::vector<double * > xDiag)33 void spinDiagonalize_gpu(int N, std::vector<const double*> n, std::vector<const double*> x, std::vector<double*> xDiag)
34 {	GpuLaunchConfig1D glc(spinDiagonalize_kernel, N);
35 	spinDiagonalize_kernel<<<glc.nBlocks,glc.nPerBlock>>>(N, n, x, xDiag);
36 	gpuErrorCheck();
37 }
38 
39 __global__
spinDiagonalizeGrad_kernel(int N,array<const double *,4> n,array<const double *,4> x,array<const double *,2> E_xDiag,array<double *,4> E_n,array<double *,4> E_x)40 void spinDiagonalizeGrad_kernel(int N, array<const double*,4> n, array<const double*,4> x, array<const double*,2> E_xDiag, array<double*,4> E_n, array<double*,4> E_x)
41 {	int i = kernelIndex1D();
42 	if(i<N) spinDiagonalizeGrad_calc(i, n, x, E_xDiag, E_n, E_x);
43 }
spinDiagonalizeGrad_gpu(int N,std::vector<const double * > n,std::vector<const double * > x,std::vector<const double * > E_xDiag,std::vector<double * > E_n,std::vector<double * > E_x)44 void spinDiagonalizeGrad_gpu(int N, std::vector<const double*> n, std::vector<const double*> x, std::vector<const double*> E_xDiag, std::vector<double*> E_n, std::vector<double*> E_x)
45 {	GpuLaunchConfig1D glc(spinDiagonalizeGrad_kernel, N);
46 	spinDiagonalizeGrad_kernel<<<glc.nBlocks,glc.nPerBlock>>>(N, n, x, E_xDiag, E_n, E_x);
47 	gpuErrorCheck();
48 }
49 
50 //-------------------------- LDA GPU launch mechanism ----------------------------
51 
52 template<LDA_Variant variant, int nCount> __global__
LDA_kernel(int N,array<const double *,nCount> n,double * E,array<double *,nCount> E_n,double scaleFac)53 void LDA_kernel(int N, array<const double*,nCount> n, double* E, array<double*,nCount> E_n, double scaleFac)
54 {	int i = kernelIndex1D();
55 	if(i<N) LDA_calc<variant,nCount>::compute(i, n, E, E_n, scaleFac);
56 }
57 template<LDA_Variant variant, int nCount>
LDA_gpu(int N,array<const double *,nCount> n,double * E,array<double *,nCount> E_n,double scaleFac)58 void LDA_gpu(int N, array<const double*,nCount> n, double* E, array<double*,nCount> E_n, double scaleFac)
59 {	GpuLaunchConfig1D glc(LDA_kernel<variant,nCount>, N);
60 	LDA_kernel<variant,nCount><<<glc.nBlocks,glc.nPerBlock>>>(N, n, E, E_n, scaleFac);
61 	gpuErrorCheck();
62 }
LDA_gpu(LDA_Variant variant,int N,std::vector<const double * > n,double * E,std::vector<double * > E_n,double scaleFac)63 void LDA_gpu(LDA_Variant variant, int N, std::vector<const double*> n, double* E, std::vector<double*> E_n, double scaleFac)
64 {	SwitchTemplate_spin(SwitchTemplate_LDA, variant, n.size(), LDA_gpu, (N, n, E, E_n, scaleFac) )
65 }
66 
67 //-------------------------- GGA GPU launch mechanism ----------------------------
68 
69 template<GGA_Variant variant, bool spinScaling, int nCount> __global__
GGA_kernel(int N,array<const double *,nCount> n,array<const double *,2* nCount-1> sigma,double * E,array<double *,nCount> E_n,array<double *,2* nCount-1> E_sigma,double scaleFac)70 void GGA_kernel(int N, array<const double*,nCount> n, array<const double*,2*nCount-1> sigma,
71 	double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma, double scaleFac)
72 {	int i = kernelIndex1D();
73 	if(i<N) GGA_calc<variant,spinScaling,nCount>::compute(i, n, sigma, E, E_n, E_sigma, scaleFac);
74 }
75 template<GGA_Variant variant, bool spinScaling, int nCount>
GGA_gpu(int N,array<const double *,nCount> n,array<const double *,2* nCount-1> sigma,double * E,array<double *,nCount> E_n,array<double *,2* nCount-1> E_sigma,double scaleFac)76 void GGA_gpu(int N, array<const double*,nCount> n, array<const double*,2*nCount-1> sigma,
77 	double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma, double scaleFac)
78 {	GpuLaunchConfig1D glc(GGA_kernel<variant,spinScaling,nCount>, N);
79 	GGA_kernel<variant,spinScaling,nCount><<<glc.nBlocks,glc.nPerBlock>>>(N, n, sigma, E, E_n, E_sigma, scaleFac);
80 	gpuErrorCheck();
81 }
GGA_gpu(GGA_Variant variant,int N,std::vector<const double * > n,std::vector<const double * > sigma,double * E,std::vector<double * > E_n,std::vector<double * > E_sigma,double scaleFac)82 void GGA_gpu(GGA_Variant variant, int N, std::vector<const double*> n, std::vector<const double*> sigma,
83 	double* E, std::vector<double*> E_n, std::vector<double*> E_sigma, double scaleFac)
84 {	SwitchTemplate_spin(SwitchTemplate_GGA, variant, n.size(), GGA_gpu, (N, n, sigma, E, E_n, E_sigma, scaleFac) )
85 }
86 
87 //-------------------------- metaGGA GPU launch mechanism ----------------------------
88 
89 template<mGGA_Variant variant, bool spinScaling, int nCount> __global__
mGGA_kernel(int N,array<const double *,nCount> n,array<const double *,2* nCount-1> sigma,array<const double *,nCount> lap,array<const double *,nCount> tau,double * E,array<double *,nCount> E_n,array<double *,2* nCount-1> E_sigma,array<double *,nCount> E_lap,array<double *,nCount> E_tau,double scaleFac)90 void mGGA_kernel(int N, array<const double*,nCount> n, array<const double*,2*nCount-1> sigma,
91 	array<const double*,nCount> lap, array<const double*,nCount> tau,
92 	double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma,
93 	array<double*,nCount> E_lap, array<double*,nCount> E_tau, double scaleFac)
94 {	int i = kernelIndex1D();
95 	if(i<N) mGGA_calc<variant,spinScaling,nCount>::compute(i,
96 		n, sigma, lap, tau, E, E_n, E_sigma, E_lap, E_tau, scaleFac);
97 }
98 template<mGGA_Variant variant, bool spinScaling, int nCount>
mGGA_gpu(int N,array<const double *,nCount> n,array<const double *,2* nCount-1> sigma,array<const double *,nCount> lap,array<const double *,nCount> tau,double * E,array<double *,nCount> E_n,array<double *,2* nCount-1> E_sigma,array<double *,nCount> E_lap,array<double *,nCount> E_tau,double scaleFac)99 void mGGA_gpu(int N, array<const double*,nCount> n, array<const double*,2*nCount-1> sigma,
100 	array<const double*,nCount> lap, array<const double*,nCount> tau,
101 	double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma,
102 	array<double*,nCount> E_lap, array<double*,nCount> E_tau, double scaleFac)
103 {	GpuLaunchConfig1D glc(mGGA_kernel<variant,spinScaling,nCount>, N);
104 	mGGA_kernel<variant,spinScaling,nCount><<<glc.nBlocks,glc.nPerBlock>>>(N,
105 		n, sigma, lap, tau, E, E_n, E_sigma, E_lap, E_tau, scaleFac);
106 	gpuErrorCheck();
107 }
mGGA_gpu(mGGA_Variant variant,int N,std::vector<const double * > n,std::vector<const double * > sigma,std::vector<const double * > lap,std::vector<const double * > tau,double * E,std::vector<double * > E_n,std::vector<double * > E_sigma,std::vector<double * > E_lap,std::vector<double * > E_tau,double scaleFac)108 void mGGA_gpu(mGGA_Variant variant, int N, std::vector<const double*> n, std::vector<const double*> sigma,
109 	std::vector<const double*> lap, std::vector<const double*> tau,
110 	double* E, std::vector<double*> E_n, std::vector<double*> E_sigma,
111 	std::vector<double*> E_lap, std::vector<double*> E_tau, double scaleFac)
112 {	SwitchTemplate_spin(SwitchTemplate_mGGA, variant, n.size(), mGGA_gpu,
113 		(N, n, sigma, lap, tau, E, E_n, E_sigma, E_lap, E_tau, scaleFac) )
114 }
115 
116