diff --git a/source/Makefile.Objects b/source/Makefile.Objects index 8e1146d8cb9..8e9058cfc10 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -207,6 +207,7 @@ OBJS_ESOLVER=esolver.o\ OBJS_ESOLVER_LCAO=esolver_ks_lcao.o\ esolver_ks_lcao_elec.o\ esolver_ks_lcao_tddft.o\ + esolver_ks_lcao_tmpfunc.o\ OBJS_GINT=gint.o\ gint_gamma.o\ diff --git a/source/module_base/blas_connector.h b/source/module_base/blas_connector.h index 34e093a9295..01dc95dea33 100644 --- a/source/module_base/blas_connector.h +++ b/source/module_base/blas_connector.h @@ -193,9 +193,16 @@ class BlasConnector zgemm_(&transb, &transa, &n, &m, &k, &alpha, b, &ldb, a, &lda, &beta, c, &ldc); - } + } static inline void gemv(const char trans, const int m, const int n, + const double alpha, const double* A, const int lda, const double* X, const int incx, + const double beta, double* Y, const int incy) + { + dgemv_(&trans, &m, &n, &alpha, A, &lda, X, &incx, &beta, Y, &incy); + } + static inline + void gemv(const char trans, const int m, const int n, const std::complex alpha, const std::complex *A, const int lda, const std::complex *X, const int incx, const std::complex beta, std::complex *Y, const int incy) { diff --git a/source/module_base/global_file.cpp b/source/module_base/global_file.cpp index 32d5c834d77..e8da9a5ef4f 100644 --- a/source/module_base/global_file.cpp +++ b/source/module_base/global_file.cpp @@ -71,7 +71,7 @@ void ModuleBase::Global_File::make_dir_out( } } #ifdef __MPI - Parallel_Reduce::reduce_int_all(make_dir); + Parallel_Reduce::reduce_all(make_dir); #endif if(make_dir>0)break; ++times; @@ -108,7 +108,7 @@ void ModuleBase::Global_File::make_dir_out( } } #ifdef __MPI - Parallel_Reduce::reduce_int_all(make_dir_stru); + Parallel_Reduce::reduce_all(make_dir_stru); #endif if(make_dir_stru>0) break; ++times; @@ -147,7 +147,7 @@ void ModuleBase::Global_File::make_dir_out( } } #ifdef __MPI - Parallel_Reduce::reduce_int_all(make_dir_matrix); + Parallel_Reduce::reduce_all(make_dir_matrix); #endif if(make_dir_matrix>0) break; ++times; diff --git a/source/module_base/global_function_ddotreal.cpp b/source/module_base/global_function_ddotreal.cpp index 8206edb7ae2..4ba88753bab 100644 --- a/source/module_base/global_function_ddotreal.cpp +++ b/source/module_base/global_function_ddotreal.cpp @@ -22,7 +22,7 @@ namespace GlobalFunc pL=(double *)psi_L; pR=(double *)psi_R; double result=BlasConnector::dot(dim2,pL,1,pR,1); - if(reduce) Parallel_Reduce::reduce_double_pool( result ); + if (reduce) Parallel_Reduce::reduce_pool(result); return result; //====================================================================== /*std::complex result(0,0); diff --git a/source/module_base/lapack_connector.h b/source/module_base/lapack_connector.h index 5865e178be3..48e28496ddc 100644 --- a/source/module_base/lapack_connector.h +++ b/source/module_base/lapack_connector.h @@ -24,6 +24,11 @@ extern "C" // solve the generalized eigenproblem Ax=eBx, where A is Hermitian and complex couble // zhegv_ & zhegvd_ returns all eigenvalues while zhegvx_ returns selected ones + void dsygvd_(const int* itype, const char* jobz, const char* uplo, const int* n, + double* a, const int* lda, + const double* b, const int* ldb, double* w, + double* work, int* lwork, + int* iwork, int* liwork, int* info); void chegvd_(const int* itype, const char* jobz, const char* uplo, const int* n, std::complex* a, const int* lda, @@ -37,6 +42,12 @@ extern "C" std::complex* work, int* lwork, double* rwork, int* lrwork, int* iwork, int* liwork, int* info); + void dsyevx_(const char* jobz, const char* range, const char* uplo, const int* n, + double* a, const int* lda, + const double* vl, const double* vu, const int* il, const int* iu, const double* abstol, + const int* m, double* w, double* z, const int* ldz, + double* work, const int* lwork, double* rwork, int* iwork, int* ifail, int* info); + void cheevx_(const char* jobz, const char* range, const char* uplo, const int* n, std::complex *a, const int* lda, const float* vl, const float* vu, const int* il, const int* iu, const float* abstol, @@ -313,6 +324,20 @@ class LapackConnector iwork, &liwork, &info); } + // wrap function of fortran lapack routine zhegvd. (pointer version) + static inline + void xhegvd(const int itype, const char jobz, const char uplo, const int n, + double* a, const int lda, + const double* b, const int ldb, double* w, + double* work, int lwork, double* rwork, int lrwork, + int* iwork, int liwork, int& info) + { + // call the fortran routine + dsygvd_(&itype, &jobz, &uplo, &n, + a, &lda, b, &ldb, w, + work, &lwork, + iwork, &liwork, &info); + } // wrap function of fortran lapack routine zhegvd. (pointer version) static inline @@ -358,7 +383,21 @@ class LapackConnector work, &lwork, rwork, iwork, ifail, &info); } - // wrap function of fortran lapack routine zheevx. + // wrap function of fortran lapack routine dsyevx. + static inline + void xheevx(const int itype, const char jobz, const char range, const char uplo, const int n, + double* a, const int lda, + const double vl, const double vu, const int il, const int iu, const double abstol, + const int m, double* w, double* z, const int ldz, + double* work, const int lwork, double* rwork, int* iwork, int* ifail, int& info) + { + dsyevx_(&jobz, &range, &uplo, &n, + a, &lda, &vl, &vu, &il, &iu, + &abstol, &m, w, z, &ldz, + work, &lwork, rwork, iwork, ifail, &info); + } + + // wrap function of fortran lapack routine cheevx. static inline void xheevx( const int itype, const char jobz, const char range, const char uplo, const int n, std::complex* a, const int lda, diff --git a/source/module_base/memory.cpp b/source/module_base/memory.cpp index 0197f8433d1..2759cf2e778 100644 --- a/source/module_base/memory.cpp +++ b/source/module_base/memory.cpp @@ -235,7 +235,7 @@ void Memory::print_all(std::ofstream &ofs) const double small = 1.0; #ifdef __MPI - Parallel_Reduce::reduce_double_all(Memory::total); + Parallel_Reduce::reduce_all(Memory::total); #endif ofs <<"\n NAME---------------|MEMORY(MB)--------" << std::endl; // std::cout<<"\n"<inner_product(pdirect, pAd, this->nx); - Parallel_Reduce::reduce_double_all(dAd); + Parallel_Reduce::reduce_all(dAd); ifPD = 0; // check for positive-definiteness, very important for convergence if (dAd == 0) @@ -183,7 +183,7 @@ void Opt_CG::stantard_CGdirect( temp_gradient[i] = this->pgradient_old[i] + this->alpha * pAd[i]; } this->beta = this->inner_product(temp_gradient, temp_gradient, this->nx) / this->gg; - Parallel_Reduce::reduce_double_all(this->beta); + Parallel_Reduce::reduce_all(this->beta); for (int i = 0; i < this->nx; ++i) { this->pgradient_old[i] = temp_gradient[i]; @@ -193,7 +193,7 @@ void Opt_CG::stantard_CGdirect( delete[] temp_gradient; } this->gg = this->inner_product(this->pgradient_old, this->pgradient_old, this->nx); - Parallel_Reduce::reduce_double_all(this->gg); + Parallel_Reduce::reduce_all(this->gg); this->iter++; } @@ -209,9 +209,9 @@ void Opt_CG::PR_beta( double temp_beta = 0.; temp_beta = this->inner_product(pgradient, pgradient, this->nx); temp_beta -= this->inner_product(pgradient, this->pgradient_old, this->nx); - Parallel_Reduce::reduce_double_all(temp_beta); + Parallel_Reduce::reduce_all(temp_beta); double gg_old = this->inner_product(this->pgradient_old, this->pgradient_old, this->nx); - Parallel_Reduce::reduce_double_all(gg_old); + Parallel_Reduce::reduce_all(gg_old); // temp_beta /= this->inner_product(this->pgradient_old, this->pgradient_old, this->nx); temp_beta /= gg_old; this->beta = std::max(0., temp_beta); @@ -230,19 +230,19 @@ void Opt_CG::HZ_beta( for (int i = 0; i < this->nx; ++i) y[i] = pgradient[i] - this->pgradient_old[i]; double py = this->inner_product(this->pdirect_old, y, this->nx); - Parallel_Reduce::reduce_double_all(py); + Parallel_Reduce::reduce_all(py); double yy = this->inner_product(y, y, this->nx); - Parallel_Reduce::reduce_double_all(yy); + Parallel_Reduce::reduce_all(yy); double pg = this->inner_product(this->pdirect_old, pgradient, this->nx); - Parallel_Reduce::reduce_double_all(pg); + Parallel_Reduce::reduce_all(pg); double yg = this->inner_product(y, pgradient, this->nx); - Parallel_Reduce::reduce_double_all(yg); + Parallel_Reduce::reduce_all(yg); double temp_beta = (yg - 2 * pg * yy / py) /py; double pp = this->inner_product(this->pdirect_old, this->pdirect_old, this->nx); - Parallel_Reduce::reduce_double_all(pp); + Parallel_Reduce::reduce_all(pp); double gg = this->inner_product(this->pgradient_old, this->pgradient_old, this->nx); - Parallel_Reduce::reduce_double_all(gg); + Parallel_Reduce::reduce_all(gg); double temp_eta = -1 / (sqrt(pp) * std::min(this->eta, sqrt(gg))); this->beta = std::max(temp_beta, temp_eta); diff --git a/source/module_base/opt_TN.hpp b/source/module_base/opt_TN.hpp index 6f0e7dbfacf..a8a62ec8980 100644 --- a/source/module_base/opt_TN.hpp +++ b/source/module_base/opt_TN.hpp @@ -100,9 +100,9 @@ class Opt_TN { double epsilon = 0.; double xx = this->inner_product(px, px, this->nx); - Parallel_Reduce::reduce_double_all(xx); + Parallel_Reduce::reduce_all(xx); double dd = this->inner_product(pcgDirect, pcgDirect, this->nx); - Parallel_Reduce::reduce_double_all(dd); + Parallel_Reduce::reduce_all(dd); epsilon = 2 * sqrt(this->machPrec) * (1 + sqrt(xx)) / sqrt(dd); // epsilon = 2 * sqrt(this->machPrec) * (1 + sqrt(this->inner_product(px, px, this->nx))) // / sqrt(this->inner_product(pcgDirect, pcgDirect, this->nx)); diff --git a/source/module_base/parallel_reduce.cpp b/source/module_base/parallel_reduce.cpp index 7c2a5d9c4c7..93cf599187b 100644 --- a/source/module_base/parallel_reduce.cpp +++ b/source/module_base/parallel_reduce.cpp @@ -4,7 +4,8 @@ #include "module_base/global_variable.h" #include "parallel_global.h" -void Parallel_Reduce::reduce_int_all(int &object) +template<> +void Parallel_Reduce::reduce_all(int& object) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE , &object , 1, MPI_INT , MPI_SUM , MPI_COMM_WORLD); @@ -21,8 +22,8 @@ void Parallel_Reduce::reduce_int_diag(int &object) } - -void Parallel_Reduce::reduce_double_all(double &object) +template<> +void Parallel_Reduce::reduce_all(double& object) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE , &object , 1, MPI_DOUBLE , MPI_SUM , MPI_COMM_WORLD); @@ -30,7 +31,8 @@ void Parallel_Reduce::reduce_double_all(double &object) return; } -void Parallel_Reduce::reduce_int_all(int *object, const int n) +template<> +void Parallel_Reduce::reduce_all(int* object, const int n) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, object, n, MPI_INT, MPI_SUM, MPI_COMM_WORLD); @@ -48,8 +50,8 @@ void Parallel_Reduce::reduce_int_grid(int *object, const int n) } - -void Parallel_Reduce::reduce_double_all(double *object, const int n) +template<> +void Parallel_Reduce::reduce_all(double* object, const int n) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, object, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); @@ -76,8 +78,8 @@ void Parallel_Reduce::reduce_double_diag(double *object, const int n) return; } - -void Parallel_Reduce::reduce_double_pool(float &object) +template<> +void Parallel_Reduce::reduce_pool(float& object) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE , &object , 1, MPI_FLOAT , MPI_SUM , POOL_WORLD); @@ -85,7 +87,8 @@ void Parallel_Reduce::reduce_double_pool(float &object) return; } -void Parallel_Reduce::reduce_double_pool(double &object) +template<> +void Parallel_Reduce::reduce_pool(double& object) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE , &object , 1, MPI_DOUBLE , MPI_SUM , POOL_WORLD); @@ -93,7 +96,8 @@ void Parallel_Reduce::reduce_double_pool(double &object) return; } -void Parallel_Reduce::reduce_double_pool(double *object, const int n) +template<> +void Parallel_Reduce::reduce_pool(double* object, const int n) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, object, n, MPI_DOUBLE, MPI_SUM, POOL_WORLD); @@ -130,8 +134,8 @@ void Parallel_Reduce::reduce_double_allpool(double *object, const int n) } - -void Parallel_Reduce::reduce_complex_double_all(std::complex &object) +template<> +void Parallel_Reduce::reduce_all>(std::complex& object) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, &object, 1, MPI_DOUBLE_COMPLEX, MPI_SUM, MPI_COMM_WORLD); @@ -140,7 +144,8 @@ void Parallel_Reduce::reduce_complex_double_all(std::complex &object) } //LiuXh add 2019-07-16 -void Parallel_Reduce::reduce_complex_double_all(std::complex *object, const int n) +template<> +void Parallel_Reduce::reduce_all>(std::complex* object, const int n) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, object, n, MPI_DOUBLE_COMPLEX, MPI_SUM, MPI_COMM_WORLD); @@ -148,7 +153,8 @@ void Parallel_Reduce::reduce_complex_double_all(std::complex *object, c return; } -void Parallel_Reduce::reduce_complex_double_pool(std::complex &object) +template<> +void Parallel_Reduce::reduce_pool>(std::complex& object) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, &object, 1, MPI_DOUBLE_COMPLEX, MPI_SUM, POOL_WORLD); @@ -156,7 +162,8 @@ void Parallel_Reduce::reduce_complex_double_pool(std::complex &object) return; } -void Parallel_Reduce::reduce_complex_double_pool(std::complex *object, const int n) +template<> +void Parallel_Reduce::reduce_pool>(std::complex * object, const int n) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, object, n, MPI_C_FLOAT_COMPLEX, MPI_SUM, POOL_WORLD); @@ -164,7 +171,8 @@ void Parallel_Reduce::reduce_complex_double_pool(std::complex *object, c return; } -void Parallel_Reduce::reduce_complex_double_pool(std::complex *object, const int n) +template<> +void Parallel_Reduce::reduce_pool>(std::complex * object, const int n) { #ifdef __MPI MPI_Allreduce(MPI_IN_PLACE, object, n, MPI_DOUBLE_COMPLEX, MPI_SUM, POOL_WORLD); @@ -267,4 +275,4 @@ void Parallel_Reduce::gather_min_double_all(double &v) } delete[] value; #endif -} +} \ No newline at end of file diff --git a/source/module_base/parallel_reduce.h b/source/module_base/parallel_reduce.h index c56e38cff20..521f3ca7afb 100644 --- a/source/module_base/parallel_reduce.h +++ b/source/module_base/parallel_reduce.h @@ -10,31 +10,28 @@ using std::complex; namespace Parallel_Reduce { - // reduce double in all process - void reduce_int_all(int &object); - void reduce_int_diag(int &object);//mohan add 2012-01-12 - void reduce_int_all(int *object, const int n); - void reduce_int_grid(int *object, const int n);//mohan add 2012-01-12 - void reduce_double_all(double &object); - void reduce_double_all(double *object, const int n); + /// reduce in all process + template + void reduce_all(T& object); + template + void reduce_all(T* object, const int n); + template + void reduce_pool(T& object); + template + void reduce_pool(T* object, const int n); + + void reduce_int_diag(int& object);//mohan add 2012-01-12 + + void reduce_int_grid(int* object, const int n);//mohan add 2012-01-12 // reduce double only in this pool // (each pool contain different k points) void reduce_double_grid(double *object, const int n); void reduce_double_diag(double *object, const int n); - void reduce_double_pool(float &object); - void reduce_double_pool(double &object); - void reduce_double_pool(double *object, const int n); void reduce_double_allpool(double &object); void reduce_double_allpool(double *object, const int n); - void reduce_complex_double_all(std::complex &object); - void reduce_complex_double_all(std::complex *object,const int n); //LiuXh add 2019-07-16 - void reduce_complex_double_pool(std::complex &object); - void reduce_complex_double_pool(std::complex *object,const int n); - void reduce_complex_double_pool(std::complex *object,const int n); - void gather_min_int_all(int &v); void gather_max_double_all(double &v); void gather_min_double_all(double &v); diff --git a/source/module_base/test/CMakeLists.txt b/source/module_base/test/CMakeLists.txt index 222e6862172..8a09995665e 100644 --- a/source/module_base/test/CMakeLists.txt +++ b/source/module_base/test/CMakeLists.txt @@ -31,7 +31,7 @@ AddTest( ) AddTest( TARGET base_memory - SOURCES memory_test.cpp ../memory.cpp + SOURCES memory_test.cpp ../memory.cpp ../parallel_reduce.cpp ) ADDTest( TARGET base_global_function diff --git a/source/module_base/test_parallel/parallel_reduce_test.cpp b/source/module_base/test_parallel/parallel_reduce_test.cpp index 01749e9610a..2c8b80c168f 100644 --- a/source/module_base/test_parallel/parallel_reduce_test.cpp +++ b/source/module_base/test_parallel/parallel_reduce_test.cpp @@ -23,9 +23,9 @@ * using MPI_Allreduce with n numbers. The total array is * deemed as the sum of local arrays with the same length. * 1. ReduceIntAll: - * Tests two variations of reduce_int_all() + * Tests two variations of reduce_all() * 2. ReduceDoubleAll: - * Tests two variations of reduce_double_all() + * Tests two variations of reduce_all() * 3. ReduceComplexAll: * Tests two variations of reduce_complex_all() * 4. GatherIntAll: @@ -41,10 +41,10 @@ * 9. ReduceDoubleGrid: * Tests reduce_double_grid() * 10.ReduceDoublePool: - * Tests two variations of reduce_double_pool() + * Tests two variations of reduce_pool() * and two variations of reduce_double_allpool() * 11.ReduceComplexPool: - * Tests two variations of reduce_complex_double_pool() + * Tests two variations of reduce_pool() * 12.GatherDoublePool: * Tests gather_min_double_pool() and gather_max_double_pool() * @@ -90,9 +90,9 @@ TEST_F(ParaReduce,ReduceIntAll) // first way of calculating global sum int global_sum_first = local_sum; - Parallel_Reduce::reduce_int_all(global_sum_first); + Parallel_Reduce::reduce_all(global_sum_first); // second way of calculating global sum - Parallel_Reduce::reduce_int_all(rand_array,num_per_process); + Parallel_Reduce::reduce_all(rand_array, num_per_process); int global_sum_second = 0; for(int i=0;i global_sum_first = local_sum; - Parallel_Reduce::reduce_complex_double_all(global_sum_first); + Parallel_Reduce::reduce_all(global_sum_first); // second way of calculating global sum - Parallel_Reduce::reduce_complex_double_all(rand_array,num_per_process); + Parallel_Reduce::reduce_all(rand_array, num_per_process); std::complex global_sum_second = std::complex{0.0,0.0}; for(int i=0;i pool_sum_first = local_sum; - Parallel_Reduce::reduce_complex_double_pool(pool_sum_first); + Parallel_Reduce::reduce_pool(pool_sum_first); // second way of calculating pool sum - Parallel_Reduce::reduce_complex_double_pool(rand_array,num_per_process); + Parallel_Reduce::reduce_pool(rand_array, num_per_process); std::complex pool_sum_second = std::complex{0.0,0.0}; for(int i=0;i void reduce_all(T& object) { return; }; + template void reduce_pool(T& object) { return; }; + + template<> + void reduce_all(double& object) { return; }; + template<> + void reduce_pool(double& object) { return; }; + template<> + void reduce_pool(float& object) { return; }; } #endif \ No newline at end of file diff --git a/source/module_basis/module_pw/test/depend_mock.h b/source/module_basis/module_pw/test/depend_mock.h index f0a6d49b2bb..216233d7dca 100644 --- a/source/module_basis/module_pw/test/depend_mock.h +++ b/source/module_basis/module_pw/test/depend_mock.h @@ -1,15 +1,15 @@ #include -//memory.cpp depends on GlobalV::ofs_running and reduce_double_all -//GPU depends on reduce_double_pool +//memory.cpp depends on GlobalV::ofs_running and reduce_all +//GPU depends on reduce_pool #ifdef __MPI #include "mpi.h" extern MPI_Comm POOL_WORLD; namespace Parallel_Reduce { - void reduce_double_all(double &object); - void reduce_double_pool(double &object); - void reduce_double_pool(float &object); + void reduce_all(double& object); + void reduce_pool(double& object); + void reduce_pool(float& object); } #endif diff --git a/source/module_cell/module_paw/paw_cell.cpp b/source/module_cell/module_paw/paw_cell.cpp index 4f78a97aaf6..dddf03efcf4 100644 --- a/source/module_cell/module_paw/paw_cell.cpp +++ b/source/module_cell/module_paw/paw_cell.cpp @@ -473,7 +473,7 @@ void Paw_Cell::accumulate_rhoij(const std::complex * psi, const double w } #ifdef __MPI - Parallel_Reduce::reduce_complex_double_pool(ca.data(), nproj); + Parallel_Reduce::reduce_pool(ca.data(), nproj); #endif paw_atom_list[iat].set_ca(ca, weight); @@ -555,7 +555,7 @@ void Paw_Cell::paw_nl_psi(const int mode, const std::complex * psi, std: } #ifdef __MPI - Parallel_Reduce::reduce_complex_double_pool(ca.data(), nproj); + Parallel_Reduce::reduce_pool(ca.data(), nproj); #endif // sum_ij D_ij ca_j diff --git a/source/module_elecstate/elecstate.cpp b/source/module_elecstate/elecstate.cpp index fb9f15c77c9..393c2d07d59 100644 --- a/source/module_elecstate/elecstate.cpp +++ b/source/module_elecstate/elecstate.cpp @@ -192,7 +192,7 @@ void ElecState::calEBand() //================================== this->f_en.eband /= GlobalV::NPROC_IN_POOL; #ifdef __MPI - Parallel_Reduce::reduce_double_all(this->f_en.eband); + Parallel_Reduce::reduce_all(this->f_en.eband); #endif } return; diff --git a/source/module_elecstate/elecstate_energy.cpp b/source/module_elecstate/elecstate_energy.cpp index 0fbba72f0f8..32c3b30f6ce 100644 --- a/source/module_elecstate/elecstate_energy.cpp +++ b/source/module_elecstate/elecstate_energy.cpp @@ -208,7 +208,7 @@ double ElecState::cal_delta_escf() const } #ifdef __MPI - Parallel_Reduce::reduce_double_pool(descf); + Parallel_Reduce::reduce_pool(descf); #endif descf *= this->omega / this->charge->rhopw->nxyz; diff --git a/source/module_elecstate/magnetism.cpp b/source/module_elecstate/magnetism.cpp index d631ab42b20..5d235f17b22 100644 --- a/source/module_elecstate/magnetism.cpp +++ b/source/module_elecstate/magnetism.cpp @@ -28,8 +28,8 @@ void Magnetism::compute_magnetization(const int& nrxx, const int& nxyz, const do this->abs_magnetization += std::abs(diff); } #ifdef __MPI - Parallel_Reduce::reduce_double_pool( this->tot_magnetization ); - Parallel_Reduce::reduce_double_pool( this->abs_magnetization ); + Parallel_Reduce::reduce_pool(this->tot_magnetization); + Parallel_Reduce::reduce_pool(this->abs_magnetization); #endif this->tot_magnetization *= elecstate::get_ucell_omega() / nxyz; this->abs_magnetization *= elecstate::get_ucell_omega() / nxyz; @@ -61,8 +61,8 @@ void Magnetism::compute_magnetization(const int& nrxx, const int& nxyz, const do this->abs_magnetization += std::abs(diff); } #ifdef __MPI - Parallel_Reduce::reduce_double_pool( this->tot_magnetization_nc, 3 ); - Parallel_Reduce::reduce_double_pool( this->abs_magnetization ); + Parallel_Reduce::reduce_pool(this->tot_magnetization_nc, 3); + Parallel_Reduce::reduce_pool(this->abs_magnetization); #endif for(int i=0;i<3;i++)this->tot_magnetization_nc[i] *= elecstate::get_ucell_omega() / nxyz; this->abs_magnetization *= elecstate::get_ucell_omega() / nxyz; diff --git a/source/module_elecstate/module_charge/charge.cpp b/source/module_elecstate/module_charge/charge.cpp index 825c1b57bd2..e6c9eca1139 100644 --- a/source/module_elecstate/module_charge/charge.cpp +++ b/source/module_elecstate/module_charge/charge.cpp @@ -223,7 +223,7 @@ double Charge::sum_rho(void) const sum_rho *= elecstate::get_ucell_omega() / static_cast(this->rhopw->nxyz); #ifdef __MPI - Parallel_Reduce::reduce_double_pool(sum_rho); + Parallel_Reduce::reduce_pool(sum_rho); #endif // mohan fixed bug 2010-01-18, @@ -294,7 +294,7 @@ void Charge::atomic_rho(const int spin_number_need, } ne[is] *= omega / (double)this->rhopw->nxyz; #ifdef __MPI - Parallel_Reduce::reduce_double_pool(ne[is]); + Parallel_Reduce::reduce_pool(ne[is]); #endif GlobalV::ofs_warning << "\n SETUP ATOMIC RHO FOR SPIN " << is + 1 << std::endl; ModuleBase::GlobalFunc::OUT(GlobalV::ofs_warning, "Electron number from rho", ne[is]); @@ -603,7 +603,7 @@ void Charge::atomic_rho(const int spin_number_need, ne[is] += rho_in[is][ir]; ne[is] *= omega / (double)this->rhopw->nxyz; #ifdef __MPI - Parallel_Reduce::reduce_double_pool(ne[is]); + Parallel_Reduce::reduce_pool(ne[is]); #endif // we check that everything is correct double neg = 0.0; @@ -619,9 +619,9 @@ void Charge::atomic_rho(const int spin_number_need, } #ifdef __MPI - Parallel_Reduce::reduce_double_pool(neg); - Parallel_Reduce::reduce_double_pool(ima); - Parallel_Reduce::reduce_double_pool(sumrea); + Parallel_Reduce::reduce_pool(neg); + Parallel_Reduce::reduce_pool(ima); + Parallel_Reduce::reduce_pool(sumrea); #endif // mohan fix bug 2011-04-03 neg = neg / (double)this->rhopw->nxyz * omega; @@ -679,7 +679,7 @@ double Charge::check_ne(const double* rho_in) const ne += rho_in[ir]; } #ifdef __MPI - Parallel_Reduce::reduce_double_pool(ne); + Parallel_Reduce::reduce_pool(ne); #endif ne = ne * elecstate::get_ucell_omega() / (double)this->rhopw->nxyz; std::cout << std::setprecision(10); diff --git a/source/module_elecstate/module_charge/charge_init.cpp b/source/module_elecstate/module_charge/charge_init.cpp index 737a60d32c9..4f5994bd327 100644 --- a/source/module_elecstate/module_charge/charge_init.cpp +++ b/source/module_elecstate/module_charge/charge_init.cpp @@ -257,8 +257,8 @@ void Charge::set_rho_core( } // mohan fix bug 2011-04-03 - Parallel_Reduce::reduce_double_pool( rhoneg ); - Parallel_Reduce::reduce_double_pool( rhoima ); + Parallel_Reduce::reduce_pool(rhoneg); + Parallel_Reduce::reduce_pool(rhoima); // mohan changed 2010-2-2, make this same as in atomic_rho. // still lack something...... diff --git a/source/module_elecstate/module_charge/charge_mixing.cpp b/source/module_elecstate/module_charge/charge_mixing.cpp index f5cff2c9a6d..12d8acc4b7e 100755 --- a/source/module_elecstate/module_charge/charge_mixing.cpp +++ b/source/module_elecstate/module_charge/charge_mixing.cpp @@ -174,7 +174,7 @@ double Charge_Mixing::get_drho(Charge* chr, const double nelec) } } #ifdef __MPI - Parallel_Reduce::reduce_double_pool(drho); + Parallel_Reduce::reduce_pool(drho); #endif assert(nelec != 0); assert(GlobalC::ucell.omega > 0); @@ -450,7 +450,7 @@ double Charge_Mixing::inner_product_real(double* rho1, double* rho2) rnorm += rho1[ir] * rho2[ir]; } #ifdef __MPI - Parallel_Reduce::reduce_double_pool(rnorm); + Parallel_Reduce::reduce_pool(rnorm); #endif return rnorm; } @@ -576,7 +576,7 @@ double Charge_Mixing::rhog_dot_product(const std::complex* const* const break; } #ifdef __MPI - Parallel_Reduce::reduce_double_pool(sum); + Parallel_Reduce::reduce_pool(sum); #endif ModuleBase::timer::tick("Charge_Mixing", "rhog_dot_product"); diff --git a/source/module_elecstate/potentials/H_Hartree_pw.cpp b/source/module_elecstate/potentials/H_Hartree_pw.cpp index dee67001c2c..055c3f6ade1 100644 --- a/source/module_elecstate/potentials/H_Hartree_pw.cpp +++ b/source/module_elecstate/potentials/H_Hartree_pw.cpp @@ -57,7 +57,7 @@ ModuleBase::matrix H_Hartree_pw::v_hartree(const UnitCell &cell, } } - Parallel_Reduce::reduce_double_pool(ehart); + Parallel_Reduce::reduce_pool(ehart); ehart *= 0.5 * cell.omega; // std::cout << " ehart=" << ehart << std::endl; H_Hartree_pw::hartree_energy = ehart; diff --git a/source/module_elecstate/potentials/efield.cpp b/source/module_elecstate/potentials/efield.cpp index 1f0cc0f269b..529a37c62f0 100644 --- a/source/module_elecstate/potentials/efield.cpp +++ b/source/module_elecstate/potentials/efield.cpp @@ -177,7 +177,7 @@ double Efield::cal_elec_dipole(const UnitCell& cell, } } - Parallel_Reduce::reduce_double_pool(elec_dipole); + Parallel_Reduce::reduce_pool(elec_dipole); elec_dipole *= cell.lat0 / bmod * ModuleBase::FOUR_PI / rho_basis->nxyz; return elec_dipole; @@ -208,7 +208,7 @@ double Efield::cal_induced_dipole(const UnitCell& cell, induced_dipole += induced_rho[ir] * saw; } - Parallel_Reduce::reduce_double_pool(induced_dipole); + Parallel_Reduce::reduce_pool(induced_dipole); induced_dipole *= cell.lat0 / bmod * ModuleBase::FOUR_PI / rho_basis->nxyz; return induced_dipole; diff --git a/source/module_esolver/CMakeLists.txt b/source/module_esolver/CMakeLists.txt index 249bef71657..df545cf9447 100644 --- a/source/module_esolver/CMakeLists.txt +++ b/source/module_esolver/CMakeLists.txt @@ -15,6 +15,7 @@ if(ENABLE_LCAO) esolver_ks_lcao.cpp esolver_ks_lcao_elec.cpp esolver_ks_lcao_tddft.cpp + esolver_ks_lcao_tmpfunc.cpp ) endif() diff --git a/source/module_esolver/esolver.cpp b/source/module_esolver/esolver.cpp index 37cdc3704e5..b5367ccaf13 100644 --- a/source/module_esolver/esolver.cpp +++ b/source/module_esolver/esolver.cpp @@ -114,7 +114,12 @@ namespace ModuleESolver #ifdef __LCAO else if (esolver_type == "ksdft_lcao") { - p_esolver = new ESolver_KS_LCAO(); + if (GlobalV::GAMMA_ONLY_LOCAL) + p_esolver = new ESolver_KS_LCAO(); + else if (GlobalV::NSPIN < 4) + p_esolver = new ESolver_KS_LCAO, double>(); + else + p_esolver = new ESolver_KS_LCAO, std::complex>(); } else if (esolver_type == "ksdft_lcao_tddft") { diff --git a/source/module_esolver/esolver_fp.cpp b/source/module_esolver/esolver_fp.cpp index 30267dbcb22..9702a550dc9 100644 --- a/source/module_esolver/esolver_fp.cpp +++ b/source/module_esolver/esolver_fp.cpp @@ -20,14 +20,6 @@ namespace ModuleESolver } ESolver_FP::~ESolver_FP() { - if (this->psi != nullptr) - { - delete psi; - } - if (this->psid != nullptr) - { - delete psid; - } delete pw_rho; delete pw_rhos; delete this->pelec; diff --git a/source/module_esolver/esolver_fp.h b/source/module_esolver/esolver_fp.h index d9d092e87bb..18434014156 100644 --- a/source/module_esolver/esolver_fp.h +++ b/source/module_esolver/esolver_fp.h @@ -7,7 +7,6 @@ #include "module_cell/module_symmetry/symmetry.h" #include "module_elecstate/elecstate.h" #include "module_hamilt_pw/hamilt_pwdft/structure_factor.h" -#include "module_psi/psi.h" // #include "hamilt.h" namespace ModuleESolver { @@ -30,9 +29,6 @@ namespace ModuleESolver // this is the interface of non-self-consistant calculation virtual void nscf(){}; - // wavefunction coefficients - psi::Psi>* psi = nullptr; - psi::Psi* psid = nullptr; Structure_Factor sf; K_Vectors kv; diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 4c547183dbd..654e3e4d90b 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -61,6 +61,7 @@ namespace ModuleESolver template ESolver_KS::~ESolver_KS() { + delete this->psi; delete this->pw_wfc; delete this->p_hamilt; delete this->phsol; @@ -541,4 +542,7 @@ template class ESolver_KS, psi::DEVICE_CPU>; template class ESolver_KS, psi::DEVICE_GPU>; template class ESolver_KS, psi::DEVICE_GPU>; #endif +#ifdef __LCAO +template class ESolver_KS; +#endif } \ No newline at end of file diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index 94f340fc51a..ef8e57f2fab 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -12,6 +12,7 @@ #include "module_hamilt_general/hamilt.h" #include "module_hamilt_pw/hamilt_pwdft/wavefunc.h" #include "module_hsolver/hsolver.h" +#include "module_psi/psi.h" #include "module_io/cal_test.h" #include "module_io/output_potential.h" #include "module_io/output_rho.h" @@ -90,6 +91,9 @@ namespace ModuleESolver wavefunc wf; Charge_Extra CE; + // wavefunction coefficients + psi::Psi* psi = nullptr; + protected: std::string basisname; //PW or LCAO protected: diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index d6d9c186514..20b81e57deb 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -38,34 +38,37 @@ namespace ModuleESolver { - -ESolver_KS_LCAO::ESolver_KS_LCAO() + template + ESolver_KS_LCAO::ESolver_KS_LCAO() { - classname = "ESolver_KS_LCAO"; - basisname = "LCAO"; + this->classname = "ESolver_KS_LCAO"; + this->basisname = "LCAO"; #ifdef __EXX if (GlobalC::exx_info.info_ri.real_number) { this->exx_lri_double = std::make_shared>(GlobalC::exx_info.info_ri); - this->exd = std::make_shared>(this->exx_lri_double); + this->exd = std::make_shared>(this->exx_lri_double); this->LM.Hexxd = &this->exd->get_Hexxs(); } else { this->exx_lri_complex = std::make_shared>>(GlobalC::exx_info.info_ri); - this->exc = std::make_shared>>(this->exx_lri_complex); + this->exc = std::make_shared>>(this->exx_lri_complex); this->LM.Hexxc = &this->exc->get_Hexxs(); } #endif -} -ESolver_KS_LCAO::~ESolver_KS_LCAO() + } + + template + ESolver_KS_LCAO::~ESolver_KS_LCAO() { #ifndef USE_NEW_TWO_CENTER this->orb_con.clear_after_ions(GlobalC::UOT, GlobalC::ORB, GlobalV::deepks_setorb, GlobalC::ucell.infoNL.nproj); #endif } -void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) + template + void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) { ModuleBase::TITLE("ESolver_KS_LCAO", "Init"); // if we are only calculating S, then there is no need @@ -82,43 +85,27 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) } // Setup the k points according to symmetry. - kv.set(this->symm, GlobalV::global_kpoint_card, GlobalV::NSPIN, ucell.G, ucell.latvec); + this->kv.set(this->symm, GlobalV::global_kpoint_card, GlobalV::NSPIN, ucell.G, ucell.latvec); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); - Print_Info::setup_parameters(ucell, kv); + Print_Info::setup_parameters(ucell, this->kv); } else { - ESolver_KS::Init(inp, ucell); + ESolver_KS::Init(inp, ucell); } // end ifnot get_S // init ElecState // autoset nbands in ElecState, it should before basis_init (for Psi 2d divid) if (this->pelec == nullptr) - { - if (GlobalV::GAMMA_ONLY_LOCAL) - { - this->pelec = new elecstate::ElecStateLCAO(&(chr), - &(kv), - kv.nks, - &(this->LOC), - &(this->UHM), - &(this->LOWF), - this->pw_rho, - pw_big); - } - else if(!GlobalV::GAMMA_ONLY_LOCAL) - { - this->pelec = new elecstate::ElecStateLCAO>(&(chr), - &(kv), - kv.nks, - &(this->LOC), - &(this->UHM), - &(this->LOWF), - this->pw_rho, - pw_big); - } - } + this->pelec = new elecstate::ElecStateLCAO(&(this->chr), + &(this->kv), + this->kv.nks, + &(this->LOC), + &(this->UHM), + &(this->LOWF), + this->pw_rho, + this->pw_big); //------------------init Basis_lcao---------------------- // Init Basis should be put outside of Ensolver. @@ -133,14 +120,7 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) this->LOC.ParaV = this->LOWF.ParaV = this->LM.ParaV = &(this->orb_con.ParaV); // init DensityMatrix - if (GlobalV::GAMMA_ONLY_LOCAL) - { - dynamic_cast*>(this->pelec)->init_DM(&kv, this->LM.ParaV, GlobalV::NSPIN); - } - else if (!GlobalV::GAMMA_ONLY_LOCAL) - { - dynamic_cast>*>(this->pelec)->init_DM(&kv, this->LM.ParaV, GlobalV::NSPIN); - } + dynamic_cast*>(this->pelec)->init_DM(&this->kv, this->LM.ParaV, GlobalV::NSPIN); if (GlobalV::CALCULATION == "get_S") { @@ -150,7 +130,7 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) //------------------init Hamilt_lcao---------------------- // * allocate H and S matrices according to computational resources // * set the 'trace' between local H/S and global H/S - this->LM.divide_HS_in_frag(GlobalV::GAMMA_ONLY_LOCAL, orb_con.ParaV, kv.nks); + this->LM.divide_HS_in_frag(GlobalV::GAMMA_ONLY_LOCAL, orb_con.ParaV, this->kv.nks); //------------------init Hamilt_lcao---------------------- #ifdef __EXX @@ -176,9 +156,9 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) // GlobalC::exx_lcao.init(); if (GlobalC::exx_info.info_ri.real_number) - this->exx_lri_double->init(MPI_COMM_WORLD, kv); + this->exx_lri_double->init(MPI_COMM_WORLD, this->kv); else - this->exx_lri_complex->init(MPI_COMM_WORLD, kv); + this->exx_lri_complex->init(MPI_COMM_WORLD, this->kv); } } #endif @@ -186,18 +166,18 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) // Quxin added for DFT+U if (GlobalV::dft_plus_u) { - GlobalC::dftu.init(ucell, this->LM, kv.nks); + GlobalC::dftu.init(ucell, this->LM, this->kv.nks); } // output is GlobalC::ppcell.vloc 3D local pseudopotentials // without structure factors // this function belongs to cell LOOP - GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, pw_rho); + GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, this->pw_rho); // init HSolver if (this->phsol == nullptr) { - this->phsol = new hsolver::HSolverLCAO(this->LOWF.ParaV); + this->phsol = new hsolver::HSolverLCAO(this->LOWF.ParaV); this->phsol->method = GlobalV::KS_SOLVER; } @@ -208,10 +188,10 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) // Initialize the potential. if (this->pelec->pot == nullptr) { - this->pelec->pot = new elecstate::Potential(pw_rho, + this->pelec->pot = new elecstate::Potential(this->pw_rho, &GlobalC::ucell, &(GlobalC::ppcell.vloc), - &(sf), + &(this->sf), &(this->pelec->f_en.etxc), &(this->pelec->f_en.vtxc)); } @@ -226,46 +206,33 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) } #endif - // Fix pelec->wg by ocp_kb + // Fix this->pelec->wg by ocp_kb if (GlobalV::ocp) { this->pelec->fixed_weights(GlobalV::ocp_kb); } } -void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) + template + void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) { - ESolver_KS::init_after_vc(inp, ucell); + ESolver_KS::init_after_vc(inp, ucell); if (GlobalV::md_prec_level == 2) { delete this->pelec; - if (GlobalV::GAMMA_ONLY_LOCAL) - { - this->pelec = new elecstate::ElecStateLCAO(&(chr), - &(kv), - kv.nks, - &(this->LOC), - &(this->UHM), - &(this->LOWF), - this->pw_rho, - pw_big); - dynamic_cast*>(this->pelec)->init_DM(&kv, this->LM.ParaV, GlobalV::NSPIN); - } - else if (!GlobalV::GAMMA_ONLY_LOCAL) - { - this->pelec = new elecstate::ElecStateLCAO>(&(chr), - &(kv), - kv.nks, + this->pelec = new elecstate::ElecStateLCAO(&(this->chr), + &(this->kv), + this->kv.nks, &(this->LOC), &(this->UHM), &(this->LOWF), this->pw_rho, - pw_big); - dynamic_cast>*>(this->pelec)->init_DM(&kv, this->LM.ParaV, GlobalV::NSPIN); - } + this->pw_big); + dynamic_cast*>(this->pelec)->init_DM(&this->kv, this->LM.ParaV, GlobalV::NSPIN); - GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, pw_rho); + + GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, this->pw_rho); this->pelec->charge->allocate(GlobalV::NSPIN); this->pelec->omega = GlobalC::ucell.omega; @@ -273,49 +240,50 @@ void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) // Initialize the potential. if (this->pelec->pot == nullptr) { - this->pelec->pot = new elecstate::Potential(pw_rho, + this->pelec->pot = new elecstate::Potential(this->pw_rho, &GlobalC::ucell, &(GlobalC::ppcell.vloc), - &(sf), + &(this->sf), &(this->pelec->f_en.etxc), &(this->pelec->f_en.vtxc)); } } } -double ESolver_KS_LCAO::cal_Energy() + template + double ESolver_KS_LCAO::cal_Energy() { return this->pelec->f_en.etot; } - -void ESolver_KS_LCAO::cal_Force(ModuleBase::matrix& force) + template + void ESolver_KS_LCAO::cal_Force(ModuleBase::matrix& force) { - Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); + Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); FSL.getForceStress(GlobalV::CAL_FORCE, - GlobalV::CAL_STRESS, - GlobalV::TEST_FORCE, - GlobalV::TEST_STRESS, - this->LOC, - this->pelec, - this->psid, - this->psi, - this->UHM, - force, - this->scs, - this->sf, - this->kv, - this->pw_rho, + GlobalV::CAL_STRESS, + GlobalV::TEST_FORCE, + GlobalV::TEST_STRESS, + this->LOC, + this->pelec, + this->psi, + this->UHM, + force, + this->scs, + this->sf, + this->kv, + this->pw_rho, #ifdef __EXX - *this->exx_lri_double, - *this->exx_lri_complex, + * this->exx_lri_double, + * this->exx_lri_complex, #endif - &this->symm); + & this->symm); // delete RA after cal_Force this->RA.delete_grid(); this->have_force = true; } -void ESolver_KS_LCAO::cal_Stress(ModuleBase::matrix& stress) + template + void ESolver_KS_LCAO::cal_Stress(ModuleBase::matrix& stress) { if (!this->have_force) { @@ -326,7 +294,8 @@ void ESolver_KS_LCAO::cal_Stress(ModuleBase::matrix& stress) this->have_force = false; } -void ESolver_KS_LCAO::postprocess() + template + void ESolver_KS_LCAO::postprocess() { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; GlobalV::ofs_running << std::setprecision(16); @@ -350,7 +319,7 @@ void ESolver_KS_LCAO::postprocess() // qianrui modify 2020-10-18 if (GlobalV::CALCULATION == "scf" || GlobalV::CALCULATION == "md" || GlobalV::CALCULATION == "relax") { - ModuleIO::write_istate_info(this->pelec->ekb, this->pelec->wg, kv, &(GlobalC::Pkpoints)); + ModuleIO::write_istate_info(this->pelec->ekb, this->pelec->wg, this->kv, &(GlobalC::Pkpoints)); } int nspin0 = (GlobalV::NSPIN == 2) ? 2 : 1; @@ -360,11 +329,11 @@ void ESolver_KS_LCAO::postprocess() int nks = 0; if (nspin0 == 1) { - nks = kv.nkstot; + nks = this->kv.nkstot; } else if (nspin0 == 2) { - nks = kv.nkstot / 2; + nks = this->kv.nkstot / 2; } for (int is = 0; is < nspin0; is++) @@ -372,24 +341,24 @@ void ESolver_KS_LCAO::postprocess() std::stringstream ss2; ss2 << GlobalV::global_out_dir << "BANDS_" << is + 1 << ".dat"; GlobalV::ofs_running << "\n Output bands in file: " << ss2.str() << std::endl; - ModuleIO::nscf_band(is, ss2.str(), nks, GlobalV::NBANDS, 0.0, this->pelec->ekb, kv, &(GlobalC::Pkpoints)); + ModuleIO::nscf_band(is, ss2.str(), nks, GlobalV::NBANDS, 0.0, this->pelec->ekb, this->kv, &(GlobalC::Pkpoints)); } } // out_band if (INPUT.out_proj_band) // Projeced band structure added by jiyy-2022-4-20 { - ModuleIO::write_proj_band_lcao(this->psid, - this->psi, - this->UHM, - this->pelec, - kv, - GlobalC::ucell, - this->p_hamilt); + ModuleIO::write_proj_band_lcao( + this->psi, + this->UHM, + this->pelec, + this->kv, + GlobalC::ucell, + this->p_hamilt); } if (INPUT.out_dos) { - ModuleIO::out_dos_nao(this->psid, + ModuleIO::out_dos_nao( this->psi, this->UHM, this->pelec->ekb, @@ -406,7 +375,8 @@ void ESolver_KS_LCAO::postprocess() } } -void ESolver_KS_LCAO::Init_Basis_lcao(ORB_control& orb_con, Input& inp, UnitCell& ucell) + template + void ESolver_KS_LCAO::Init_Basis_lcao(ORB_control& orb_con, Input& inp, UnitCell& ucell) { // autoset NB2D first if (GlobalV::NB2D == 0) @@ -499,7 +469,8 @@ void ESolver_KS_LCAO::Init_Basis_lcao(ORB_control& orb_con, Input& inp, UnitCell } } -void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) + template + void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) { if (iter == 1) this->p_chgmix->mix_reset(); @@ -511,7 +482,7 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) // first need to calculate the weight according to // electrons number. - if (wf.init_wfc == "file") + if (this->wf.init_wfc == "file") { if (iter == 1) { @@ -520,14 +491,7 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) // calculate the density matrix using read in wave functions // and the ncalculate the charge density on grid. - if (this->psi != nullptr) - { - this->pelec->psiToRho(this->psi[0]); - } - else - { - this->pelec->psiToRho(this->psid[0]); - } + this->pelec->psiToRho(this->psi[0]); // calculate the local potential(rho) again. // the grid integration will do in later grid integration. @@ -568,7 +532,7 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) if (GlobalV::dft_plus_u) { - GlobalC::dftu.cal_slater_UJ(pelec->charge->rho, pw_rho->nrxx); // Calculate U and J if Yukawa potential is used + GlobalC::dftu.cal_slater_UJ(this->pelec->charge->rho, this->pw_rho->nrxx); // Calculate U and J if Yukawa potential is used } #ifdef __DEEPKS @@ -592,25 +556,21 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) this->p_hamilt->refresh(); } } -void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) + + template + void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) { // save input rho - pelec->charge->save_rho_before_sum_band(); + this->pelec->charge->save_rho_before_sum_band(); - // using HSolverLCAO::solve() + // using HSolverLCAO::solve() if (this->phsol != nullptr) { // reset energy this->pelec->f_en.eband = 0.0; this->pelec->f_en.demet = 0.0; - if (this->psi != nullptr) - { - this->phsol->solve(this->p_hamilt, this->psi[0], this->pelec, GlobalV::KS_SOLVER); - } - else if (this->psid != nullptr) - { - this->phsol->solve(this->p_hamilt, this->psid[0], this->pelec, GlobalV::KS_SOLVER); - } + + this->phsol->solve(this->p_hamilt, this->psi[0], this->pelec, GlobalV::KS_SOLVER); if (GlobalV::out_bandgap) { @@ -630,7 +590,7 @@ void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) } // print ekb for each k point and each band - for (int ik = 0; ik < kv.nks; ++ik) + for (int ik = 0; ik < this->kv.nks; ++ik) { this->pelec->print_band(ik, INPUT.printe, iter); } @@ -648,16 +608,8 @@ void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) { if (GlobalC::dftu.omc != 2) { - if (GlobalV::GAMMA_ONLY_LOCAL) - { - const std::vector>& tmp_dm_gamma = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); - GlobalC::dftu.cal_occup_m_gamma(iter, tmp_dm_gamma, this->p_chgmix->get_mixing_beta()); - } - else - { - const std::vector>>& tmp_dm_k = dynamic_cast>*>(this->pelec)->get_DM()->get_DMK_vector(); - GlobalC::dftu.cal_occup_m_k(iter, tmp_dm_k, kv, this->p_chgmix->get_mixing_beta(), this->p_hamilt); - } + const std::vector>& tmp_dm = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); + this->dftu_cal_occup_m(iter, tmp_dm); } GlobalC::dftu.cal_energy_correction(istep); GlobalC::dftu.output(); @@ -667,19 +619,8 @@ void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) if (GlobalV::deepks_scf) { const Parallel_Orbitals* pv = this->LOWF.ParaV; - if (GlobalV::GAMMA_ONLY_LOCAL) - { - const std::vector>& dm_gamma - = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); - GlobalC::ld.cal_e_delta_band(dm_gamma); - } - else - { - const std::vector>>& dm_k - = dynamic_cast>*>(pelec)->get_DM()->get_DMK_vector(); - GlobalC::ld - .cal_e_delta_band_k(dm_k, kv.nks); - } + const std::vector>& dm = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); + this->dpks_cal_e_delta_band(dm); } #endif // (4) mohan add 2010-06-24 @@ -690,7 +631,7 @@ void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) Symmetry_rho srho; for (int is = 0; is < GlobalV::NSPIN; is++) { - srho.begin(is, *(pelec->charge), pw_rho, GlobalC::Pgrid, this->symm); + srho.begin(is, *(this->pelec->charge), this->pw_rho, GlobalC::Pgrid, this->symm); } // (6) compute magnetization, only for spin==2 @@ -702,18 +643,20 @@ void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) // (7) calculate delta energy this->pelec->f_en.deband = this->pelec->cal_delta_eband(); } -void ESolver_KS_LCAO::updatepot(const int istep, const int iter) + + template + void ESolver_KS_LCAO::updatepot(const int istep, const int iter) { // print Hamiltonian and Overlap matrix if (this->conv_elec) { - if (!GlobalV::GAMMA_ONLY_LOCAL && hsolver::HSolverLCAO::out_mat_hs) + if (!GlobalV::GAMMA_ONLY_LOCAL && hsolver::HSolverLCAO::out_mat_hs) { this->UHM.GK.renew(true); } - for (int ik = 0; ik < kv.nks; ++ik) + for (int ik = 0; ik < this->kv.nks; ++ik) { - if (hsolver::HSolverLCAO::out_mat_hs) + if (hsolver::HSolverLCAO::out_mat_hs) { this->p_hamilt->updateHk(ik); } @@ -721,24 +664,13 @@ void ESolver_KS_LCAO::updatepot(const int istep, const int iter) // if set bit = true, there would be error in soc-multi-core calculation, noted by zhengdy-soc if (this->psi != nullptr && (istep % GlobalV::out_interval == 0)) { - hamilt::MatrixBlock> h_mat, s_mat; + hamilt::MatrixBlock h_mat, s_mat; this->p_hamilt->matrix(h_mat, s_mat); ModuleIO::saving_HS(istep, h_mat.p, s_mat.p, bit, - hsolver::HSolverLCAO::out_mat_hs, - "data-" + std::to_string(ik), - this->LOWF.ParaV[0], - 1); // LiuXh, 2017-03-21 - } - else if (this->psid != nullptr && (istep % GlobalV::out_interval == 0)) - { // gamma_only case, Hloc and Sloc are correct H and S matrix - ModuleIO::saving_HS(istep, - this->LM.Hloc.data(), - this->LM.Sloc.data(), - bit, - hsolver::HSolverLCAO::out_mat_hs, + hsolver::HSolverLCAO::out_mat_hs, "data-" + std::to_string(ik), this->LOWF.ParaV[0], 1); // LiuXh, 2017-03-21 @@ -748,38 +680,19 @@ void ESolver_KS_LCAO::updatepot(const int istep, const int iter) if (this->conv_elec) { - if (GlobalV::GAMMA_ONLY_LOCAL && elecstate::ElecStateLCAO::out_wfc_lcao) - { - elecstate::ElecStateLCAO::out_wfc_flag = elecstate::ElecStateLCAO::out_wfc_lcao; - } - else if (!GlobalV::GAMMA_ONLY_LOCAL && elecstate::ElecStateLCAO>::out_wfc_lcao) - { - elecstate::ElecStateLCAO>::out_wfc_flag = elecstate::ElecStateLCAO>::out_wfc_lcao; - } - for (int ik = 0; ik < kv.nks; ik++) + if (elecstate::ElecStateLCAO::out_wfc_lcao) + elecstate::ElecStateLCAO::out_wfc_flag = elecstate::ElecStateLCAO::out_wfc_lcao; + + for (int ik = 0; ik < this->kv.nks; ik++) { if (istep % GlobalV::out_interval == 0) { - if (this->psi != nullptr) - { - this->psi[0].fix_k(ik); - this->pelec->print_psi(this->psi[0], istep); - } - else - { - this->psid[0].fix_k(ik); - this->pelec->print_psi(this->psid[0], istep); - } + this->psi[0].fix_k(ik); + this->pelec->print_psi(this->psi[0], istep); } } - if (GlobalV::GAMMA_ONLY_LOCAL && elecstate::ElecStateLCAO::out_wfc_lcao) - { - elecstate::ElecStateLCAO::out_wfc_flag = 0; - } - else if (!GlobalV::GAMMA_ONLY_LOCAL && elecstate::ElecStateLCAO>::out_wfc_lcao) - { - elecstate::ElecStateLCAO>::out_wfc_flag = 0; - } + if (elecstate::ElecStateLCAO::out_wfc_lcao) + elecstate::ElecStateLCAO::out_wfc_flag = 0; } // (9) Calculate new potential according to new Charge Density. @@ -803,7 +716,9 @@ void ESolver_KS_LCAO::updatepot(const int istep, const int iter) this->pelec->cal_converged(); } } -void ESolver_KS_LCAO::eachiterfinish(int iter) + + template + void ESolver_KS_LCAO::eachiterfinish(int iter) { //----------------------------------- // save charge density @@ -813,7 +728,7 @@ void ESolver_KS_LCAO::eachiterfinish(int iter) { for (int is = 0; is < GlobalV::NSPIN; ++is) { - GlobalC::restart.save_disk(*this->UHM.LM, "charge", is, pelec->charge->nrxx, pelec->charge->rho); + GlobalC::restart.save_disk(*this->UHM.LM, "charge", is, this->pelec->charge->nrxx, this->pelec->charge->rho); } } @@ -843,7 +758,8 @@ void ESolver_KS_LCAO::eachiterfinish(int iter) this->pelec->cal_energies(2); } -void ESolver_KS_LCAO::afterscf(const int istep) + template + void ESolver_KS_LCAO::afterscf(const int istep) { // save charge difference into files for charge extrapolation if (GlobalV::CALCULATION != "scf") @@ -906,38 +822,19 @@ void ESolver_KS_LCAO::afterscf(const int istep) #ifdef __DEEPKS std::shared_ptr ld_shared_ptr(&GlobalC::ld,[](LCAO_Deepks*){}); LCAO_Deepks_Interface LDI = LCAO_Deepks_Interface(ld_shared_ptr); - if (GlobalV::GAMMA_ONLY_LOCAL) - { - const std::vector>& dm_gamma - = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); - LDI.out_deepks_labels(this->pelec->f_en.etot, - this->pelec->klist->nks, - GlobalC::ucell.nat, - this->pelec->ekb, - this->pelec->klist->kvec_d, - GlobalC::ucell, - GlobalC::ORB, - GlobalC::GridD, - this->LOWF.ParaV, - *(this->psid), - dm_gamma); - } - else - { - const std::vector>>& dm_k - = dynamic_cast>*>(pelec)->get_DM()->get_DMK_vector(); + const std::vector>& dm + = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); LDI.out_deepks_labels(this->pelec->f_en.etot, - this->pelec->klist->nks, - GlobalC::ucell.nat, - this->pelec->ekb, - this->pelec->klist->kvec_d, - GlobalC::ucell, - GlobalC::ORB, - GlobalC::GridD, - this->LOWF.ParaV, - *(this->psi), - dm_k); - } + this->pelec->klist->nks, + GlobalC::ucell.nat, + this->pelec->ekb, + this->pelec->klist->kvec_d, + GlobalC::ucell, + GlobalC::ORB, + GlobalC::GridD, + this->LOWF.ParaV, + *(this->psi), + dm); #endif // 3. some outputs @@ -947,9 +844,9 @@ void ESolver_KS_LCAO::afterscf(const int istep) // ModuleRPA::DFT_RPA_interface rpa_interface(GlobalC::exx_info.info_global); // rpa_interface.rpa_exx_lcao().info.files_abfs = GlobalV::rpa_orbitals; // rpa_interface.out_for_RPA(*(this->LOWF.ParaV), *(this->psi), this->LOC, this->pelec); - RPA_LRI rpa_lri_double(GlobalC::exx_info.info_ri); - rpa_lri_double.cal_postSCF_exx(this->LOC, MPI_COMM_WORLD, kv, *this->LOWF.ParaV); - rpa_lri_double.init(MPI_COMM_WORLD, kv); + RPA_LRI rpa_lri_double(GlobalC::exx_info.info_ri); + rpa_lri_double.cal_postSCF_exx(this->LOC, MPI_COMM_WORLD, this->kv, *this->LOWF.ParaV); + rpa_lri_double.init(MPI_COMM_WORLD, this->kv); rpa_lri_double.out_for_RPA(*(this->LOWF.ParaV), *(this->psi), this->pelec); } #endif @@ -960,7 +857,7 @@ void ESolver_KS_LCAO::afterscf(const int istep) // GlobalV::mulliken charge analysis if (GlobalV::out_mul) { - ModuleIO::out_mulliken(istep, &this->LM, this->pelec, kv, this->p_hamilt); + ModuleIO::out_mulliken(istep, &this->LM, this->pelec, this->kv, this->p_hamilt); } // qifeng add 2019/9/10, jiyy modify 2023/2/27, liuyu move here 2023-04-18 } @@ -970,18 +867,20 @@ void ESolver_KS_LCAO::afterscf(const int istep) } } -bool ESolver_KS_LCAO::do_after_converge(int& iter) + template + bool ESolver_KS_LCAO::do_after_converge(int& iter) { #ifdef __EXX if (GlobalC::exx_info.info_ri.real_number) - return this->exd->exx_after_converge(*this->p_hamilt, this->LM, this->LOC, kv, iter); + return this->exd->exx_after_converge(*this->p_hamilt, this->LM, this->LOC, this->kv, iter); else - return this->exc->exx_after_converge(*this->p_hamilt, this->LM, this->LOC, kv, iter); + return this->exc->exx_after_converge(*this->p_hamilt, this->LM, this->LOC, this->kv, iter); #endif // __EXX return true; } -ModuleIO::Output_DM ESolver_KS_LCAO::create_Output_DM(int is, int iter) + template + ModuleIO::Output_DM ESolver_KS_LCAO::create_Output_DM(int is, int iter) { int precision = 3; @@ -997,29 +896,32 @@ ModuleIO::Output_DM ESolver_KS_LCAO::create_Output_DM(int is, int iter) GlobalV::GAMMA_ONLY_LOCAL); } -ModuleIO::Output_DM1 ESolver_KS_LCAO::create_Output_DM1(int istep) + template + ModuleIO::Output_DM1 ESolver_KS_LCAO::create_Output_DM1(int istep) { const elecstate::DensityMatrix,double>* DM = dynamic_cast>*>(this->pelec)->get_DM(); return ModuleIO::Output_DM1(GlobalV::NSPIN, istep, this->LOC, this->RA, this->kv, DM); } -ModuleIO::Output_Mat_Sparse ESolver_KS_LCAO::create_Output_Mat_Sparse(int istep) + template + ModuleIO::Output_Mat_Sparse ESolver_KS_LCAO::create_Output_Mat_Sparse(int istep) { - return ModuleIO::Output_Mat_Sparse(hsolver::HSolverLCAO::out_mat_hsR, - hsolver::HSolverLCAO::out_mat_dh, - hsolver::HSolverLCAO::out_mat_t, - INPUT.out_mat_r, - istep, - this->pelec->pot->get_effective_v(), - *this->LOWF.ParaV, - this->UHM, - this->LM, - this->kv, - this->p_hamilt); + return ModuleIO::Output_Mat_Sparse(hsolver::HSolverLCAO::out_mat_hsR, + hsolver::HSolverLCAO::out_mat_dh, + hsolver::HSolverLCAO::out_mat_t, + INPUT.out_mat_r, + istep, + this->pelec->pot->get_effective_v(), + *this->LOWF.ParaV, + this->UHM, + this->LM, + this->kv, + this->p_hamilt); } -bool ESolver_KS_LCAO::md_skip_out(std::string calculation, int istep, int interval) + template + bool ESolver_KS_LCAO::md_skip_out(std::string calculation, int istep, int interval) { if (calculation == "md") { @@ -1029,6 +931,8 @@ bool ESolver_KS_LCAO::md_skip_out(std::string calculation, int istep, int interv } } return false; -} - + } + template class ESolver_KS_LCAO; + template class ESolver_KS_LCAO, double>; + template class ESolver_KS_LCAO, std::complex>; } // namespace ModuleESolver diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index 85d396993da..ef6b92bf2ec 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -18,8 +18,8 @@ #include namespace ModuleESolver { - - class ESolver_KS_LCAO : public ESolver_KS> + template + class ESolver_KS_LCAO : public ESolver_KS { public: ESolver_KS_LCAO(); @@ -77,17 +77,25 @@ namespace ModuleESolver ModuleIO::Output_DM1 create_Output_DM1(int istep); /// @brief create ModuleIO::Output_Mat_Sparse object to output sparse density matrix of H, S, T, r - ModuleIO::Output_Mat_Sparse create_Output_Mat_Sparse(int istep); + ModuleIO::Output_Mat_Sparse create_Output_Mat_Sparse(int istep); /// @brief check if skip the corresponding output in md calculation bool md_skip_out(std::string calculation, int istep, int interval); #ifdef __EXX - std::shared_ptr> exd = nullptr; - std::shared_ptr>> exc = nullptr; + std::shared_ptr> exd = nullptr; + std::shared_ptr>> exc = nullptr; std::shared_ptr> exx_lri_double = nullptr; std::shared_ptr>> exx_lri_complex = nullptr; #endif + private: + // tmp interfaces before sub-modules are refactored + void dftu_cal_occup_m(const int& iter, const std::vector>& dm) const; +#ifdef __DEEPKS + void dpks_cal_e_delta_band(const std::vector>& dm) const; + void dpks_cal_projected_DM(const std::vector>& dm) const; +#endif + }; diff --git a/source/module_esolver/esolver_ks_lcao_elec.cpp b/source/module_esolver/esolver_ks_lcao_elec.cpp index da976a39df3..66fc53528f1 100644 --- a/source/module_esolver/esolver_ks_lcao_elec.cpp +++ b/source/module_esolver/esolver_ks_lcao_elec.cpp @@ -25,7 +25,8 @@ namespace ModuleESolver { - void ESolver_KS_LCAO::set_matrix_grid(Record_adj& ra) + template + void ESolver_KS_LCAO::set_matrix_grid(Record_adj& ra) { ModuleBase::TITLE("ESolver_KS_LCAO", "set_matrix_grid"); ModuleBase::timer::tick("ESolver_KS_LCAO", "set_matrix_grid"); @@ -49,9 +50,9 @@ namespace ModuleESolver //ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running,"SEARCH ADJACENT ATOMS"); // (3) Periodic condition search for each grid. - this->GridT.set_pbc_grid(pw_rho->nx, - pw_rho->ny, - pw_rho->nz, + this->GridT.set_pbc_grid(this->pw_rho->nx, + this->pw_rho->ny, + this->pw_rho->nz, this->pw_big->bx, this->pw_big->by, this->pw_big->bz, @@ -61,9 +62,9 @@ namespace ModuleESolver this->pw_big->nbxx, this->pw_big->nbzp_start, this->pw_big->nbzp, - pw_rho->ny, - pw_rho->nplane, - pw_rho->startz_current); + this->pw_rho->ny, + this->pw_rho->nplane, + this->pw_rho->startz_current); // (2)For each atom, calculate the adjacent atoms in different cells // and allocate the space for H(R) and S(R). @@ -81,8 +82,8 @@ namespace ModuleESolver return; } - - void ESolver_KS_LCAO::beforesolver(const int istep) + template + void ESolver_KS_LCAO::beforesolver(const int istep) { ModuleBase::TITLE("ESolver_KS_LCAO", "beforesolver"); ModuleBase::timer::tick("ESolver_KS_LCAO", "beforesolver"); @@ -98,43 +99,44 @@ namespace ModuleESolver // the force. // init psi - if (GlobalV::GAMMA_ONLY_LOCAL) + if (this->psi == nullptr) { - if(this->psid==nullptr) + int nsk; + int ncol; + if (GlobalV::GAMMA_ONLY_LOCAL) { - int ncol = this->LOWF.ParaV->ncol_bands; - if(GlobalV::KS_SOLVER=="genelpa" || GlobalV::KS_SOLVER=="lapack_gvx" + nsk = GlobalV::NSPIN; + ncol = this->LOWF.ParaV->ncol_bands; + if (GlobalV::KS_SOLVER == "genelpa" || GlobalV::KS_SOLVER == "lapack_gvx" #ifdef __CUSOLVER_LCAO - ||GlobalV::KS_SOLVER=="cusolver" + || GlobalV::KS_SOLVER == "cusolver" #endif - ) + ) { ncol = this->LOWF.ParaV->ncol; } - this->psid = new psi::Psi(GlobalV::NSPIN, ncol, this->LOWF.ParaV->nrow, nullptr); } - } - else - { - if(this->psi == nullptr) + else { - #ifdef __MPI - int ncol = this->LOWF.ParaV->ncol_bands; - #else - int ncol = GlobalV::NBANDS; - #endif + nsk = this->kv.nks; +#ifdef __MPI + ncol = this->LOWF.ParaV->ncol_bands; +#else + ncol = GlobalV::NBANDS; +#endif #ifdef __CUSOLVER_LCAO - if(GlobalV::KS_SOLVER=="cusolver") + if (GlobalV::KS_SOLVER == "cusolver") { ncol = this->LOWF.paraV->ncol; } #endif - this->psi = new psi::Psi>(this->kv.nks, ncol, this->LOWF.ParaV->nrow, nullptr); } + this->psi = new psi::Psi(nsk, ncol, this->LOWF.ParaV->nrow, nullptr); } - + + // prepare grid in Gint - this->UHM.grid_prepare(this->GridT, *pw_rho, *this->pw_big); + this->UHM.grid_prepare(this->GridT, *this->pw_rho, *this->pw_big); // init Hamiltonian if (this->p_hamilt != nullptr) @@ -142,55 +144,21 @@ namespace ModuleESolver delete this->p_hamilt; this->p_hamilt = nullptr; } - if(this->p_hamilt == nullptr) + if (this->p_hamilt == nullptr) { - // two cases for hamilt class - // Gamma_only case - if (GlobalV::GAMMA_ONLY_LOCAL) - { - elecstate::DensityMatrix* DM - = dynamic_cast*>(pelec)->get_DM(); - this->p_hamilt = new hamilt::HamiltLCAO(&(this->UHM.GG), - nullptr, - &(this->UHM.genH), - &(this->LM), - &(this->LOC), - this->pelec->pot, - this->kv, - DM); - } - // multi_k case - else - { - elecstate::DensityMatrix,double>* DM - = dynamic_cast>*>(pelec)->get_DM(); - if(GlobalV::NSPIN < 4) - { - this->p_hamilt = new hamilt::HamiltLCAO, double>(nullptr, - &(this->UHM.GK), - &(this->UHM.genH), - &(this->LM), - &(this->LOC), - this->pelec->pot, - this->kv, - DM); - } - else - { - this->p_hamilt = new hamilt::HamiltLCAO, std::complex>(nullptr, - &(this->UHM.GK), - &(this->UHM.genH), - &(this->LM), - &(this->LOC), - this->pelec->pot, - this->kv, - DM); - } - } + elecstate::DensityMatrix* DM + = dynamic_cast*>(this->pelec)->get_DM(); + this->p_hamilt = new hamilt::HamiltLCAO(GlobalV::GAMMA_ONLY_LOCAL ? &(this->UHM.GG) : nullptr, + GlobalV::GAMMA_ONLY_LOCAL ? nullptr : &(this->UHM.GK), + &(this->UHM.genH), + &(this->LM), + &(this->LOC), + this->pelec->pot, + this->kv, + DM); } - // init density kernel and wave functions. - this->LOC.allocate_dm_wfc(this->GridT, this->pelec, this->LOWF, this->psid, this->psi, this->kv); + this->LOC.allocate_dm_wfc(this->GridT, this->pelec, this->LOWF, this->psi, this->kv); //====================================== // do the charge extrapolation before the density matrix is regenerated. @@ -207,7 +175,7 @@ namespace ModuleESolver { for (int is = 0; is < GlobalV::NSPIN; is++) { - ModuleBase::GlobalFunc::ZEROS(pelec->charge->rho[is], pw_rho->nrxx); + ModuleBase::GlobalFunc::ZEROS(this->pelec->charge->rho[is], this->pw_rho->nrxx); std::stringstream ssd; ssd << GlobalV::global_out_dir << "SPIN" << is + 1 << "_DM"; // reading density matrix, @@ -228,35 +196,35 @@ namespace ModuleESolver // calculate the charge density if (GlobalV::GAMMA_ONLY_LOCAL) { - Gint_inout inout(this->LOC.DM, pelec->charge->rho, Gint_Tools::job_type::rho); + Gint_inout inout(this->LOC.DM, this->pelec->charge->rho, Gint_Tools::job_type::rho); this->UHM.GG.cal_gint(&inout); if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type()==5) { for(int is=0; ischarge->kin_r[0], pw_rho->nrxx); + ModuleBase::GlobalFunc::ZEROS(this->pelec->charge->kin_r[0], this->pw_rho->nrxx); } - Gint_inout inout1(this->LOC.DM, pelec->charge->kin_r, Gint_Tools::job_type::tau); + Gint_inout inout1(this->LOC.DM, this->pelec->charge->kin_r, Gint_Tools::job_type::tau); this->UHM.GG.cal_gint(&inout1); } } else { - Gint_inout inout(this->LOC.DM_R, pelec->charge->rho, Gint_Tools::job_type::rho); + Gint_inout inout(this->LOC.DM_R, this->pelec->charge->rho, Gint_Tools::job_type::rho); this->UHM.GK.cal_gint(&inout); if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type()==5) { for(int is=0; ischarge->kin_r[0], pw_rho->nrxx); + ModuleBase::GlobalFunc::ZEROS(this->pelec->charge->kin_r[0], this->pw_rho->nrxx); } - Gint_inout inout1(this->LOC.DM_R, pelec->charge->kin_r, Gint_Tools::job_type::tau); + Gint_inout inout1(this->LOC.DM_R, this->pelec->charge->kin_r, Gint_Tools::job_type::tau); this->UHM.GK.cal_gint(&inout1); } } // renormalize the charge density - pelec->charge->renormalize_rho(); + this->pelec->charge->renormalize_rho(); } #ifdef __DEEPKS @@ -286,7 +254,8 @@ namespace ModuleESolver } - void ESolver_KS_LCAO::beforescf(int istep) + template + void ESolver_KS_LCAO::beforescf(int istep) { ModuleBase::TITLE("ESolver_KS_LCAO", "beforescf"); ModuleBase::timer::tick("ESolver_KS_LCAO", "beforescf"); @@ -297,14 +266,14 @@ namespace ModuleESolver } if (GlobalC::ucell.ionic_position_updated) { - CE.update_all_dis(GlobalC::ucell); - CE.extrapolate_charge( + this->CE.update_all_dis(GlobalC::ucell); + this->CE.extrapolate_charge( #ifdef __MPI &(GlobalC::Pgrid), #endif GlobalC::ucell, - pelec->charge, - &(sf)); + this->pelec->charge, + & (this->sf)); } //---------------------------------------------------------- @@ -317,53 +286,41 @@ namespace ModuleESolver } this->beforesolver(istep); - this->pelec->init_scf(istep, sf.strucFac); + this->pelec->init_scf(istep, this->sf.strucFac); // initalize DMR // DMR should be same size with Hamiltonian(R) - if (GlobalV::GAMMA_ONLY_LOCAL) - { - dynamic_cast*>(this->pelec)->get_DM()->init_DMR( - *(dynamic_cast*>(this->p_hamilt)->getHR())); - } - else if (GlobalV::NSPIN != 4) - { - dynamic_cast>*>(this->pelec)->get_DM()->init_DMR( - *(dynamic_cast, double>*>(this->p_hamilt)->getHR())); - } - else - { - dynamic_cast>*>(this->pelec)->get_DM()->init_DMR( - *(dynamic_cast, std::complex>*>(this->p_hamilt)->getHR())); - } + dynamic_cast*>(this->pelec)->get_DM()->init_DMR( + *(dynamic_cast*>(this->p_hamilt)->getHR())); // the electron charge density should be symmetrized, // here is the initialization Symmetry_rho srho; for (int is = 0; is < GlobalV::NSPIN; is++) { - srho.begin(is, *(pelec->charge), pw_rho, GlobalC::Pgrid, this->symm); + srho.begin(is, *(this->pelec->charge), this->pw_rho, GlobalC::Pgrid, this->symm); } //Peize Lin add 2016-12-03 #ifdef __EXX if (GlobalC::exx_info.info_ri.real_number) - this->exd->exx_beforescf(kv, *this->p_chgmix); + this->exd->exx_beforescf(this->kv, *this->p_chgmix); else - this->exc->exx_beforescf(kv, *this->p_chgmix); + this->exc->exx_beforescf(this->kv, *this->p_chgmix); #endif // __EXX // 1. calculate ewald energy. // mohan update 2021-02-25 if(!GlobalV::test_skip_ewald) { - this->pelec->f_en.ewald_energy = H_Ewald_pw::compute_ewald(GlobalC::ucell, pw_rho, sf.strucFac); + this->pelec->f_en.ewald_energy = H_Ewald_pw::compute_ewald(GlobalC::ucell, this->pw_rho, this->sf.strucFac); } - p_hamilt->non_first_scf = istep; + this->p_hamilt->non_first_scf = istep; ModuleBase::timer::tick("ESolver_KS_LCAO", "beforescf"); return; } - void ESolver_KS_LCAO::othercalculation(const int istep) + template + void ESolver_KS_LCAO::othercalculation(const int istep) { ModuleBase::TITLE("ESolver_KS_LCAO", "othercalculation"); ModuleBase::timer::tick("ESolver_KS_LCAO", "othercalculation"); @@ -405,7 +362,7 @@ namespace ModuleESolver this->beforesolver(istep); //pelec should be initialized before these calculations - this->pelec->init_scf(istep, sf.strucFac); + this->pelec->init_scf(istep, this->sf.strucFac); // self consistent calculations for electronic ground state if (GlobalV::CALCULATION == "nscf") { @@ -413,21 +370,21 @@ namespace ModuleESolver } else if (GlobalV::CALCULATION == "get_pchg") { - IState_Charge ISC(this->psid, this->LOC); + IState_Charge ISC(this->psi, this->LOC); ISC.begin(this->UHM.GG, this->pelec, this->pw_rho, this->pw_big); } else if (GlobalV::CALCULATION == "get_wf") { IState_Envelope IEP(this->pelec); if (GlobalV::GAMMA_ONLY_LOCAL) - IEP.begin(this->psid, + IEP.begin(this->psi, this->pw_rho, this->pw_wfc, this->pw_big, this->LOWF, this->UHM.GG, INPUT.out_wfc_pw, - wf.out_wfc_r, + this->wf.out_wfc_r, this->kv); else IEP.begin(this->psi, @@ -437,27 +394,27 @@ namespace ModuleESolver this->LOWF, this->UHM.GK, INPUT.out_wfc_pw, - wf.out_wfc_r, + this->wf.out_wfc_r, this->kv); } else { - ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::othercalculation", "CALCULATION type not supported"); + ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::othercalculation", "CALCULATION type not supported"); } ModuleBase::timer::tick("ESolver_KS_LCAO", "othercalculation"); return; } - - void ESolver_KS_LCAO::get_S() + template <> + void ESolver_KS_LCAO::get_S() + { + ModuleBase::TITLE("ESolver_KS_LCAO", "get_S"); + ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::get_S", "not implemented for"); + } + template <> + void ESolver_KS_LCAO, double>::get_S() { ModuleBase::TITLE("ESolver_KS_LCAO", "get_S"); - if(GlobalV::GAMMA_ONLY_LOCAL) - { - ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::get_S", "not implemented for"); - } - else - { // (1) Find adjacent atoms for each atom. GlobalV::SEARCH_RADIUS = atom_arrange::set_sr_NL( GlobalV::ofs_running, @@ -478,22 +435,43 @@ namespace ModuleESolver this->UHM.genH.LM->ParaV = &this->orb_con.ParaV; if(this->p_hamilt == nullptr) { - if(GlobalV::NSPIN < 4) - { - this->p_hamilt = new hamilt::HamiltLCAO, double>(this->UHM.genH.LM, kv); - dynamic_cast, double>*>(this->p_hamilt->ops)->contributeHR(); - } - else - { - this->p_hamilt = new hamilt::HamiltLCAO, std::complex>(this->UHM.genH.LM, kv); - dynamic_cast, std::complex>*>(this->p_hamilt->ops)->contributeHR(); - } + this->p_hamilt = new hamilt::HamiltLCAO, double>(this->UHM.genH.LM, this->kv); + dynamic_cast, double>*>(this->p_hamilt->ops)->contributeHR(); } ModuleIO::output_S_R(this->UHM, this->p_hamilt, "SR.csr"); + } + template <> + void ESolver_KS_LCAO, std::complex>::get_S() + { + ModuleBase::TITLE("ESolver_KS_LCAO", "get_S"); + // (1) Find adjacent atoms for each atom. + GlobalV::SEARCH_RADIUS = atom_arrange::set_sr_NL( + GlobalV::ofs_running, + GlobalV::OUT_LEVEL, + GlobalC::ORB.get_rcutmax_Phi(), + GlobalC::ucell.infoNL.get_rcutmax_Beta(), + GlobalV::GAMMA_ONLY_LOCAL); + + atom_arrange::search( + GlobalV::SEARCH_PBC, + GlobalV::ofs_running, + GlobalC::GridD, + GlobalC::ucell, + GlobalV::SEARCH_RADIUS, + GlobalV::test_atom_input); + + this->RA.for_2d(this->orb_con.ParaV, GlobalV::GAMMA_ONLY_LOCAL); + this->UHM.genH.LM->ParaV = &this->orb_con.ParaV; + if (this->p_hamilt == nullptr) + { + this->p_hamilt = new hamilt::HamiltLCAO, std::complex>(this->UHM.genH.LM, this->kv); + dynamic_cast, std::complex>*>(this->p_hamilt->ops)->contributeHR(); } + ModuleIO::output_S_R(this->UHM, this->p_hamilt, "SR.csr"); } - void ESolver_KS_LCAO::nscf() + template + void ESolver_KS_LCAO::nscf() { ModuleBase::TITLE("ESolver_KS_LCAO", "nscf"); @@ -513,41 +491,12 @@ namespace ModuleESolver else this->exc->read_Hexxs(file_name_exx); - // This is a temporary fix - if (GlobalV::GAMMA_ONLY_LOCAL) - { - hamilt::HamiltLCAO* hamilt_lcao = dynamic_cast*>(p_hamilt); - hamilt::Operator* exx - = new hamilt::OperatorEXX>(&this->LM, - hamilt_lcao->getHR(), - &(hamilt_lcao->getHk(&this->LM)), - kv); - hamilt_lcao->getOperator()->add(exx); - } - else - { - hamilt::Operator>* exx; - if(GlobalV::NSPIN < 4) - { - hamilt::HamiltLCAO, double>* hamilt_lcao = - dynamic_cast, double>*>(p_hamilt); - exx = new hamilt::OperatorEXX, double>>(&this->LM, - hamilt_lcao->getHR(), - &(hamilt_lcao->getHk(&this->LM)), - kv); - hamilt_lcao->getOperator()->add(exx); - } - else - { - hamilt::HamiltLCAO, std::complex>* hamilt_lcao = - dynamic_cast, std::complex>*>(p_hamilt); - exx = new hamilt::OperatorEXX, std::complex>>(&this->LM, - hamilt_lcao->getHR(), - &(hamilt_lcao->getHk(&this->LM)), - kv); - hamilt_lcao->getOperator()->add(exx); - } - } + hamilt::HamiltLCAO* hamilt_lcao = dynamic_cast*>(this->p_hamilt); + auto exx = new hamilt::OperatorEXX>(&this->LM, + hamilt_lcao->getHR(), + &(hamilt_lcao->getHk(&this->LM)), + this->kv); + hamilt_lcao->getOperator()->add(exx); } #endif // __MPI #endif // __EXX @@ -559,14 +508,7 @@ namespace ModuleESolver int istep = 0; if(this->phsol != nullptr) { - if(this->psi != nullptr) - { - this->phsol->solve(this->p_hamilt, this->psi[0], this->pelec, GlobalV::KS_SOLVER, true); - } - else if(this->psid != nullptr) - { - this->phsol->solve(this->p_hamilt, this->psid[0], this->pelec, GlobalV::KS_SOLVER, true); - } + this->phsol->solve(this->p_hamilt, this->psi[0], this->pelec, GlobalV::KS_SOLVER, true); } else { @@ -653,26 +595,9 @@ namespace ModuleESolver const Parallel_Orbitals* pv = this->LOWF.ParaV; if (GlobalV::deepks_out_labels || GlobalV::deepks_scf) { - if (GlobalV::GAMMA_ONLY_LOCAL) - { - const std::vector>& dm_gamma = - dynamic_cast*> (this->pelec)->get_DM()->get_DMK_vector(); - GlobalC::ld.cal_projected_DM(dm_gamma, //this->LOC.dm_gamma, - GlobalC::ucell, - GlobalC::ORB, - GlobalC::GridD); - } - else - { - const std::vector>>& dm_k = - dynamic_cast>*> (this->pelec)->get_DM()->get_DMK_vector(); - GlobalC::ld.cal_projected_DM_k(dm_k, //this->LOC.dm_k, - GlobalC::ucell, - GlobalC::ORB, - GlobalC::GridD, - this->kv.nks, - this->kv.kvec_d); - } + const std::vector>& dm = + dynamic_cast*> (this->pelec)->get_DM()->get_DMK_vector(); + this->dpks_cal_projected_DM(dm); GlobalC::ld.cal_descriptor(); // final descriptor GlobalC::ld.cal_gedm(GlobalC::ucell.nat); } @@ -680,4 +605,7 @@ namespace ModuleESolver return; } + template class ESolver_KS_LCAO; + template class ESolver_KS_LCAO, double>; + template class ESolver_KS_LCAO, std::complex>; } diff --git a/source/module_esolver/esolver_ks_lcao_tddft.cpp b/source/module_esolver/esolver_ks_lcao_tddft.cpp index 9af001f1d4d..6737d98e399 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/module_esolver/esolver_ks_lcao_tddft.cpp @@ -107,7 +107,7 @@ void ESolver_KS_LCAO_TDDFT::Init(Input& inp, UnitCell& ucell) // init Psi, HSolver, ElecState, Hamilt if (this->phsol == nullptr) { - this->phsol = new hsolver::HSolverLCAO(this->LOWF.ParaV); + this->phsol = new hsolver::HSolverLCAO>(this->LOWF.ParaV); this->phsol->method = GlobalV::KS_SOLVER; } @@ -168,7 +168,7 @@ void ESolver_KS_LCAO_TDDFT::hamilt2density(int istep, int iter, double ethr) kv.nks); this->pelec_td->psiToRho_td(this->psi[0]); } - // using HSolverLCAO::solve() + // using HSolverLCAO>::solve() else if (this->phsol != nullptr) { // reset energy @@ -178,10 +178,6 @@ void ESolver_KS_LCAO_TDDFT::hamilt2density(int istep, int iter, double ethr) { this->phsol->solve(this->p_hamilt, this->psi[0], this->pelec_td, GlobalV::KS_SOLVER); } - else if (this->psid != nullptr) - { - this->phsol->solve(this->p_hamilt, this->psid[0], this->pelec_td, GlobalV::KS_SOLVER); - } } else { @@ -251,7 +247,7 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) } for (int ik = 0; ik < kv.nks; ++ik) { - if (hsolver::HSolverLCAO::out_mat_hs) + if (hsolver::HSolverLCAO>::out_mat_hs) { this->p_hamilt->updateHk(ik); } @@ -265,20 +261,7 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) h_mat.p, s_mat.p, bit, - hsolver::HSolverLCAO::out_mat_hs, - "data-" + std::to_string(ik), - this->LOWF.ParaV[0], - 1); // LiuXh, 2017-03-21 - } - else if (this->psid != nullptr && (istep % GlobalV::out_interval == 0)) - { - hamilt::MatrixBlock h_mat, s_mat; - this->p_hamilt->matrix(h_mat, s_mat); - ModuleIO::saving_HS(istep, - h_mat.p, - s_mat.p, - bit, - hsolver::HSolverLCAO::out_mat_hs, + hsolver::HSolverLCAO>::out_mat_hs, "data-" + std::to_string(ik), this->LOWF.ParaV[0], 1); // LiuXh, 2017-03-21 @@ -297,16 +280,8 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) { if (istep % GlobalV::out_interval == 0) { - if (this->psi != nullptr) - { this->psi[0].fix_k(ik); this->pelec->print_psi(this->psi[0], istep); - } - else - { - this->psid[0].fix_k(ik); - this->pelec->print_psi(this->psid[0], istep); - } } } elecstate::ElecStateLCAO>::out_wfc_flag = 0; @@ -423,7 +398,7 @@ void ESolver_KS_LCAO_TDDFT::afterscf(const int istep) } } - ESolver_KS_LCAO::afterscf(istep); + ESolver_KS_LCAO, double>::afterscf(istep); } // use the original formula (Hamiltonian matrix) to calculate energy density matrix diff --git a/source/module_esolver/esolver_ks_lcao_tddft.h b/source/module_esolver/esolver_ks_lcao_tddft.h index 3a992adbe28..090e804b540 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.h +++ b/source/module_esolver/esolver_ks_lcao_tddft.h @@ -14,7 +14,7 @@ namespace ModuleESolver { -class ESolver_KS_LCAO_TDDFT : public ESolver_KS_LCAO + class ESolver_KS_LCAO_TDDFT : public ESolver_KS_LCAO, double> { public: ESolver_KS_LCAO_TDDFT(); diff --git a/source/module_esolver/esolver_ks_lcao_tmpfunc.cpp b/source/module_esolver/esolver_ks_lcao_tmpfunc.cpp new file mode 100644 index 00000000000..f5449e0e3ab --- /dev/null +++ b/source/module_esolver/esolver_ks_lcao_tmpfunc.cpp @@ -0,0 +1,67 @@ +#include "esolver_ks_lcao.h" +#include "module_hamilt_lcao/module_dftu/dftu.h" +#include "module_hamilt_lcao/module_deepks/LCAO_deepks.h" +namespace ModuleESolver +{ + template <> + void ESolver_KS_LCAO::dftu_cal_occup_m(const int& iter, const std::vector>& dm)const + { + GlobalC::dftu.cal_occup_m_gamma(iter, dm, this->p_chgmix->get_mixing_beta()); + } + + template <> + void ESolver_KS_LCAO, double>::dftu_cal_occup_m(const int& iter, const std::vector>>& dm)const + { + GlobalC::dftu.cal_occup_m_k(iter, dm, this->kv, this->p_chgmix->get_mixing_beta(), this->p_hamilt); + } + template <> + void ESolver_KS_LCAO, std::complex>::dftu_cal_occup_m(const int& iter, const std::vector>>& dm)const + { + GlobalC::dftu.cal_occup_m_k(iter, dm, this->kv, this->p_chgmix->get_mixing_beta(), this->p_hamilt); + } +#ifdef __DEEPKS + template<> + void ESolver_KS_LCAO::dpks_cal_e_delta_band(const std::vector>& dm)const + { + GlobalC::ld.cal_e_delta_band(dm); + } + template<> + void ESolver_KS_LCAO, double>::dpks_cal_e_delta_band(const std::vector>>& dm)const + { + GlobalC::ld.cal_e_delta_band_k(dm, this->kv.nks); + } + template<> + void ESolver_KS_LCAO, std::complex>::dpks_cal_e_delta_band(const std::vector>>& dm)const + { + GlobalC::ld.cal_e_delta_band_k(dm, this->kv.nks); + } + template<> + void ESolver_KS_LCAO::dpks_cal_projected_DM(const std::vector>& dm)const + { + GlobalC::ld.cal_projected_DM(dm, //this->LOC.dm_gamma, + GlobalC::ucell, + GlobalC::ORB, + GlobalC::GridD); + } + template<> + void ESolver_KS_LCAO, double>::dpks_cal_projected_DM(const std::vector>>& dm)const + { + GlobalC::ld.cal_projected_DM_k(dm, //this->LOC.dm_k, + GlobalC::ucell, + GlobalC::ORB, + GlobalC::GridD, + this->kv.nks, + this->kv.kvec_d); + } + template<> + void ESolver_KS_LCAO, std::complex>::dpks_cal_projected_DM(const std::vector>>& dm)const + { + GlobalC::ld.cal_projected_DM_k(dm, //this->LOC.dm_k, + GlobalC::ucell, + GlobalC::ORB, + GlobalC::GridD, + this->kv.nks, + this->kv.kvec_d); + } +#endif +} \ No newline at end of file diff --git a/source/module_esolver/esolver_ks_pw.h b/source/module_esolver/esolver_ks_pw.h index 78441086da4..5be3dd84555 100644 --- a/source/module_esolver/esolver_ks_pw.h +++ b/source/module_esolver/esolver_ks_pw.h @@ -87,6 +87,8 @@ namespace ModuleESolver void allocate_psi_init(); /// @brief initialize psi void initialize_psi(); + protected: + psi::Psi, psi::DEVICE_CPU>* psi = nullptr; //hide the psi in ESolver_KS for tmp use private: psi_initializer* psi_init = nullptr; Device * ctx = {}; diff --git a/source/module_esolver/esolver_of.cpp b/source/module_esolver/esolver_of.cpp index b13b5ca757e..bb79ef4023a 100644 --- a/source/module_esolver/esolver_of.cpp +++ b/source/module_esolver/esolver_of.cpp @@ -510,7 +510,7 @@ void ESolver_OF::updateV() { this->normdLdphi += this->inner_product(this->pdLdphi[is], this->pdLdphi[is], this->nrxx, 1); } - Parallel_Reduce::reduce_double_all(this->normdLdphi); + Parallel_Reduce::reduce_all(this->normdLdphi); this->normdLdphi = sqrt(this->normdLdphi/this->pw_rho->nxyz/GlobalV::NSPIN); } @@ -618,7 +618,7 @@ void ESolver_OF::solveV() // eKE = this->kineticEnergy(); // ePP = this->inner_product(this->pelec->pot->get_fixed_v(), ptempRho->rho[0], this->nrxx, this->dV); // // ePP = this->inner_product(GlobalC::pot.vltot, ptempRho[0], this->nrxx, this->dV); - // Parallel_Reduce::reduce_double_all(ePP); + // Parallel_Reduce::reduce_all(ePP); // E += eKE + ePP; // GlobalV::ofs_warning << i << " " << dEdtheta[0] << " " << E << endl; // if (this->theta[0] == 0) cout << "dEdtheta " << dEdtheta[0]<< endl; @@ -641,7 +641,7 @@ void ESolver_OF::solveV() E = this->pelec->f_en.etot; eKE = this->kineticEnergy(); ePP = this->inner_product(this->pelec->pot->get_fixed_v(), this->ptempRho->rho[0], this->nrxx, this->dV); - Parallel_Reduce::reduce_double_all(ePP); + Parallel_Reduce::reduce_all(ePP); E += eKE + ePP; // line search to update theta[0] @@ -732,7 +732,7 @@ void ESolver_OF::solveV() // for (int is = 0; is < GlobalV::NSPIN; ++is) { // ePP += this->inner_product(GlobalC::pot.vltot, ptempRho[is], this->nrxx, this->dV); // } - // Parallel_Reduce::reduce_double_all(ePP); + // Parallel_Reduce::reduce_all(ePP); // E += eKE + ePP; // this->opt_dcsrch.dcSrch(E, dEdalpha, thetaAlpha, this->task); // numDC++; @@ -815,19 +815,19 @@ void ESolver_OF::getNextDirect() // (1) make direction orthogonal to phi // |d'> = |d0> - |phi>/nelec double innerPhiDir = this->inner_product(this->pdirect[0], this->pphi[0], this->nrxx, this->dV); - Parallel_Reduce::reduce_double_all(innerPhiDir); + Parallel_Reduce::reduce_all(innerPhiDir); for (int i = 0; i < this->nrxx; ++i) { tempTheta += pow(this->pdirect[0][i] + this->pphi[0][i], 2); this->pdirect[0][i] = this->pdirect[0][i] - this->pphi[0][i] * innerPhiDir / this->nelec[0]; } - Parallel_Reduce::reduce_double_all(tempTheta); + Parallel_Reduce::reduce_all(tempTheta); tempTheta = sqrt(tempTheta); // (2) renormalize direction // |d> = |d'> * \sqrt(nelec) / double normDir = this->inner_product(this->pdirect[0], this->pdirect[0], this->nrxx, this->dV); - Parallel_Reduce::reduce_double_all(normDir); + Parallel_Reduce::reduce_all(normDir); normDir = sqrt(normDir); for (int i = 0; i < this->nrxx; ++i) { @@ -844,7 +844,7 @@ void ESolver_OF::getNextDirect() // (1) make direction orthogonal to phi // |d'> = |d0> - |phi>/nelec double innerPhiDir = this->inner_product(this->pdirect[is], this->pphi[is], this->nrxx, this->dV); - Parallel_Reduce::reduce_double_all(innerPhiDir); + Parallel_Reduce::reduce_all(innerPhiDir); for (int i = 0; i < this->nrxx; ++i) { this->pdirect[is][i] = this->pdirect[is][i] - this->pphi[is][i] * innerPhiDir / this->nelec[is]; @@ -853,7 +853,7 @@ void ESolver_OF::getNextDirect() // (2) renormalize direction // |d> = |d'> * \sqrt(nelec) / double normDir = this->inner_product(this->pdirect[is], this->pdirect[is], this->nrxx, this->dV); - Parallel_Reduce::reduce_double_all(normDir); + Parallel_Reduce::reduce_all(normDir); normDir = sqrt(normDir); for (int i = 0; i < this->nrxx; ++i) { @@ -911,8 +911,8 @@ void ESolver_OF::updateRho() // this->pw_rho->recip2real(this->precipDir[is], this->pdeltaRhoHar); // this->deltaRhoG = this->inner_product(this->pdeltaRho[is], this->pdeltaRhoHar, this->nrxx, this->dV); // } - // Parallel_Reduce::reduce_double_all(this->deltaRhoR); - // Parallel_Reduce::reduce_double_all(this->deltaRhoG); + // Parallel_Reduce::reduce_all(this->deltaRhoR); + // Parallel_Reduce::reduce_all(this->deltaRhoG); // this->deltaRhoR *= this->dV; // this->deltaRhoG /= 2.; } @@ -1193,7 +1193,7 @@ void ESolver_OF::caldEdtheta(double **ptempPhi, Charge* tempRho, double *ptheta, pdPhidTheta[ir] = - this->pphi[is][ir] * sin(ptheta[is]) + this->pdirect[is][ir] * cos(ptheta[is]); } rdEdtheta[is] = this->inner_product(this->pdEdphi[is], pdPhidTheta, this->nrxx, this->dV); - Parallel_Reduce::reduce_double_all(rdEdtheta[is]); + Parallel_Reduce::reduce_all(rdEdtheta[is]); } delete[] pdPhidTheta; } @@ -1205,7 +1205,7 @@ void ESolver_OF::caldEdtheta(double **ptempPhi, Charge* tempRho, double *ptheta, double ESolver_OF::cal_mu(double *pphi, double *pdEdphi, double nelec) { double mu = this->inner_product(pphi, pdEdphi, this->nrxx, this->dV); - Parallel_Reduce::reduce_double_all(mu); + Parallel_Reduce::reduce_all(mu); mu = mu / (2.0*nelec); return mu; } @@ -1223,7 +1223,7 @@ double ESolver_OF::cal_Energy() { ePP += this->inner_product(this->pelec->pot->get_fixed_v(), pelec->charge->rho[is], this->nrxx, this->dV); } - Parallel_Reduce::reduce_double_all(ePP); + Parallel_Reduce::reduce_all(ePP); this->pelec->f_en.etot += eKE + ePP; return this->pelec->f_en.etot; } diff --git a/source/module_hamilt_general/hamilt.h b/source/module_hamilt_general/hamilt.h index 72a3dac77c6..95ca5b6909f 100644 --- a/source/module_hamilt_general/hamilt.h +++ b/source/module_hamilt_general/hamilt.h @@ -25,7 +25,7 @@ class Hamilt /// core function: for solving eigenvalues of Hamiltonian with iterative method virtual void hPsi(const T* psi_in, T* hpsi, const size_t size) const{return;} - virtual void sPsi(const T* psi_in, T* spsi, const size_t size) const{return;} + virtual void sPsi(const T* psi_in, T* spsi, const size_t size) const { syncmem_op()(this->ctx, this->ctx, spsi, psi_in, size); } /// core function: return H(k) and S(k) matrixs for direct solving eigenvalues. virtual void matrix(MatrixBlock> &hk_in, MatrixBlock> &sk_in){return;} @@ -37,8 +37,9 @@ class Hamilt /// first node operator, add operations from each operators Operator* ops = nullptr; - Operator* opsd = nullptr; - +protected: + Device* ctx = {}; + using syncmem_op = psi::memory::synchronize_memory_op; }; } // namespace hamilt diff --git a/source/module_hamilt_general/module_ewald/H_Ewald_pw.cpp b/source/module_hamilt_general/module_ewald/H_Ewald_pw.cpp index 27694df2d84..443ec0b52fc 100644 --- a/source/module_hamilt_general/module_ewald/H_Ewald_pw.cpp +++ b/source/module_hamilt_general/module_ewald/H_Ewald_pw.cpp @@ -182,7 +182,7 @@ double H_Ewald_pw::compute_ewald(const UnitCell& cell, ewalds = 0.50 * ModuleBase::e2 * (ewaldg + ewaldr); // mohan fix bug 2010-07-26 - Parallel_Reduce::reduce_double_pool( ewalds ); + Parallel_Reduce::reduce_pool(ewalds); if (GlobalV::test_energy>1) { diff --git a/source/module_hamilt_general/module_surchem/corrected_energy.cpp b/source/module_hamilt_general/module_surchem/corrected_energy.cpp index 8b3e8272ee3..e0f4494261e 100644 --- a/source/module_hamilt_general/module_surchem/corrected_energy.cpp +++ b/source/module_hamilt_general/module_surchem/corrected_energy.cpp @@ -7,7 +7,7 @@ double surchem::cal_Ael(const UnitCell &cell, const int& nrxx, const int& nxyz) { Ael -= TOTN_real[ir] * delta_phi[ir]; } - Parallel_Reduce::reduce_double_pool(Ael); + Parallel_Reduce::reduce_pool(Ael); Ael = Ael * cell.omega / nxyz; // cout << "Ael: " << Ael << endl; return Ael; @@ -18,7 +18,7 @@ double surchem::cal_Acav(const UnitCell &cell, const int& nxyz) double Acav = 0.0; Acav = GlobalV::tau * qs; Acav = Acav * cell.omega / nxyz; // unit Ry - Parallel_Reduce::reduce_double_pool(Acav); + Parallel_Reduce::reduce_pool(Acav); // cout << "Acav: " << Acav << endl; return Acav; } \ No newline at end of file diff --git a/source/module_hamilt_general/module_surchem/sol_force.cpp b/source/module_hamilt_general/module_surchem/sol_force.cpp index d63b8a555cf..491a9b331b8 100644 --- a/source/module_hamilt_general/module_surchem/sol_force.cpp +++ b/source/module_hamilt_general/module_surchem/sol_force.cpp @@ -171,7 +171,7 @@ void surchem::cal_force_sol(const UnitCell& cell, const ModulePW::PW_Basis* rho_ } } - Parallel_Reduce::reduce_double_pool(forcesol.c, forcesol.nr * forcesol.nc); + Parallel_Reduce::reduce_pool(forcesol.c, forcesol.nr * forcesol.nc); ModuleBase::timer::tick("surchem", "cal_force_sol"); return; } \ No newline at end of file diff --git a/source/module_hamilt_general/module_xc/test/test_xc5.cpp b/source/module_hamilt_general/module_xc/test/test_xc5.cpp index ed718a85a23..ec9ac075edb 100644 --- a/source/module_hamilt_general/module_xc/test/test_xc5.cpp +++ b/source/module_hamilt_general/module_xc/test/test_xc5.cpp @@ -15,7 +15,8 @@ // v_xc_libxc, called by v_xc, when we use functionals from LIBXC // v_xc_meta, unified interface of mGGA functionals -void Parallel_Reduce::reduce_double_pool(double &object) +template<> +void Parallel_Reduce::reduce_pool(double& object) { #ifdef __MPI double swap = object; diff --git a/source/module_hamilt_general/module_xc/xc_functional_vxc.cpp b/source/module_hamilt_general/module_xc/xc_functional_vxc.cpp index 4b91b8e668e..70a7990e92a 100644 --- a/source/module_hamilt_general/module_xc/xc_functional_vxc.cpp +++ b/source/module_hamilt_general/module_xc/xc_functional_vxc.cpp @@ -164,8 +164,8 @@ std::tuple XC_Functional::v_xc( // parallel code : collect vtxc,etxc // mohan add 2008-06-01 #ifdef __MPI - Parallel_Reduce::reduce_double_pool( etxc ); - Parallel_Reduce::reduce_double_pool( vtxc ); + Parallel_Reduce::reduce_pool(etxc); + Parallel_Reduce::reduce_pool(vtxc); #endif etxc *= ucell->omega / chr->rhopw->nxyz; vtxc *= ucell->omega / chr->rhopw->nxyz; @@ -417,8 +417,8 @@ std::tuple XC_Functional::v_xc_libxc( // Peiz // for MPI, reduce the exchange-correlation energy //------------------------------------------------- #ifdef __MPI - Parallel_Reduce::reduce_double_pool( etxc ); - Parallel_Reduce::reduce_double_pool( vtxc ); + Parallel_Reduce::reduce_pool(etxc); + Parallel_Reduce::reduce_pool(vtxc); #endif etxc *= omega / chr->rhopw->nxyz; @@ -759,8 +759,8 @@ std::tuple XC_Functional::v // for MPI, reduce the exchange-correlation energy //------------------------------------------------- #ifdef __MPI - Parallel_Reduce::reduce_double_pool( etxc ); - Parallel_Reduce::reduce_double_pool( vtxc ); + Parallel_Reduce::reduce_pool(etxc); + Parallel_Reduce::reduce_pool(vtxc); #endif etxc *= omega / chr->rhopw->nxyz; diff --git a/source/module_hamilt_general/operator.cpp b/source/module_hamilt_general/operator.cpp index 256208897bd..8c7108057d5 100644 --- a/source/module_hamilt_general/operator.cpp +++ b/source/module_hamilt_general/operator.cpp @@ -38,7 +38,6 @@ Operator::~Operator() template typename Operator::hpsi_info Operator::hPsi(hpsi_info& input) const { - ModuleBase::timer::tick("Operator", "hPsi"); using syncmem_op = psi::memory::synchronize_memory_op; auto psi_input = std::get<0>(input); std::tuple psi_info = psi_input->to_range(std::get<1>(input)); @@ -51,17 +50,6 @@ typename Operator::hpsi_info Operator::hPsi(hpsi_info& inp { ModuleBase::WARNING_QUIT("Operator", "please choose correct range of psi for hPsi()!"); } - - this->act(nbands, psi_input->get_nbasis(), psi_input->npol, tmpsi_in, tmhpsi, psi_input->get_ngk(this->ik)); - Operator* node((Operator*)this->next_op); - while (node != nullptr) - { - node->act(nbands, psi_input->get_nbasis(), psi_input->npol, tmpsi_in, tmhpsi, psi_input->get_ngk(node->ik)); - node = (Operator*)(node->next_op); - } - - ModuleBase::timer::tick("Operator", "hPsi"); - //if in_place, copy temporary hpsi to target hpsi_pointer, then delete hpsi and new a wrapper for return T* hpsi_pointer = std::get<2>(input); if (this->in_place) @@ -71,9 +59,33 @@ typename Operator::hpsi_info Operator::hPsi(hpsi_info& inp delete this->hpsi; this->hpsi = new psi::Psi(hpsi_pointer, *psi_input, 1, nbands / psi_input->npol); } + + auto call_act = [&, this](const Operator* op) -> void { + switch (act_type) + { + case 2: + op->act(*psi_input, *this->hpsi); + break; + default: + op->act(nbands, psi_input->get_nbasis(), psi_input->npol, tmpsi_in, this->hpsi->get_pointer(), psi_input->get_ngk(op->ik)); + break; + } + }; + + ModuleBase::timer::tick("Operator", "hPsi"); + call_act(this); + Operator* node((Operator*)this->next_op); + while (node != nullptr) + { + call_act(node); + node = (Operator*)(node->next_op); + } + ModuleBase::timer::tick("Operator", "hPsi"); + return hpsi_info(this->hpsi, psi::Range(1, 0, 0, nbands / psi_input->npol), hpsi_pointer); } + template void Operator::init(const int ik_in) { diff --git a/source/module_hamilt_general/operator.h b/source/module_hamilt_general/operator.h index ed2aa8bf0da..81f12c5b878 100644 --- a/source/module_hamilt_general/operator.h +++ b/source/module_hamilt_general/operator.h @@ -54,6 +54,7 @@ class Operator ///do operation : |hpsi_choosed> = V|psi_choosed> ///V is the target operator act on choosed psi, the consequence should be added to choosed hpsi + /// interface type 1: pointer-only (default) virtual void act(const int nbands, const int nbasis, const int npol, @@ -61,13 +62,17 @@ class Operator T* tmhpsi, const int ngk_ik = 0)const {}; - /// an developer-friendly interface for act() function - virtual psi::Psi act(const psi::Psi& psi_in) const { return psi_in; }; + /// developer-friendly interfaces for act() function + /// interface type 2: input and change the Psi-type HPsi + virtual void act(const psi::Psi& psi_in, psi::Psi& psi_out) const {}; + /// interface type 3: return a Psi-type HPsi + // virtual psi::Psi act(const psi::Psi& psi_in) const { return psi_in; }; Operator* next_op = nullptr; - protected: +protected: int ik = 0; + int act_type = 1; ///< determine which act() interface would be called in hPsi() mutable bool in_place = false; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp index 778ef77a54d..165616f05ad 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp @@ -14,35 +14,37 @@ #include "module_elecstate/elecstate_lcao.h" #endif -double Force_Stress_LCAO::force_invalid_threshold_ev = 0.00; -double Force_Stress_LCAO::output_acc = 1.0e-8; - -Force_Stress_LCAO::Force_Stress_LCAO(Record_adj& ra, const int nat_in) : RA(&ra), f_pw(nat_in), nat(nat_in) +template +double Force_Stress_LCAO::force_invalid_threshold_ev = 0.00; +template +double Force_Stress_LCAO::output_acc = 1.0e-8; +template +Force_Stress_LCAO::Force_Stress_LCAO(Record_adj& ra, const int nat_in) : RA(&ra), f_pw(nat_in), nat(nat_in) { } -Force_Stress_LCAO::~Force_Stress_LCAO() +template +Force_Stress_LCAO::~Force_Stress_LCAO() { } - -void Force_Stress_LCAO::getForceStress(const bool isforce, - const bool isstress, - const bool istestf, - const bool istests, - Local_Orbital_Charge& loc, - const elecstate::ElecState* pelec, - const psi::Psi* psid, - const psi::Psi>* psi, - LCAO_Hamilt& uhm, - ModuleBase::matrix& fcs, - ModuleBase::matrix& scs, - const Structure_Factor& sf, - const K_Vectors& kv, - ModulePW::PW_Basis* rhopw, +template +void Force_Stress_LCAO::getForceStress(const bool isforce, + const bool isstress, + const bool istestf, + const bool istests, + Local_Orbital_Charge& loc, + const elecstate::ElecState* pelec, + const psi::Psi* psi, + LCAO_Hamilt& uhm, + ModuleBase::matrix& fcs, + ModuleBase::matrix& scs, + const Structure_Factor& sf, + const K_Vectors& kv, + ModulePW::PW_Basis* rhopw, #ifdef __EXX - Exx_LRI& exx_lri_double, - Exx_LRI>& exx_lri_complex, + Exx_LRI& exx_lri_double, + Exx_LRI>& exx_lri_complex, #endif - ModuleSymmetry::Symmetry* symm) + ModuleSymmetry::Symmetry* symm) { ModuleBase::TITLE("Force_Stress_LCAO", "getForceStress"); ModuleBase::timer::tick("Force_Stress_LCAO", "getForceStress"); @@ -137,27 +139,26 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, // implement four terms which needs integration //-------------------------------------------------------- this->calForceStressIntegralPart(GlobalV::GAMMA_ONLY_LOCAL, - isforce, - isstress, - loc, - pelec, - psid, - psi, - foverlap, - ftvnl_dphi, - fvnl_dbeta, - fvl_dphi, - soverlap, - stvnl_dphi, - svnl_dbeta, + isforce, + isstress, + loc, + pelec, + psi, + foverlap, + ftvnl_dphi, + fvnl_dbeta, + fvl_dphi, + soverlap, + stvnl_dphi, + svnl_dbeta, #ifdef __DEEPKS - svl_dphi, - svnl_dalpha, + svl_dphi, + svnl_dalpha, #else - svl_dphi, + svl_dphi, #endif - uhm, - kv); + uhm, + kv); // implement vdw force or stress here // Peize Lin add 2014-04-04, update 2021-03-09 // jiyy add 2019-05-18, update 2021-05-02 @@ -665,7 +666,8 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, } // local pseudopotential, ewald, core correction, scc terms in force -void Force_Stress_LCAO::calForcePwPart(ModuleBase::matrix& fvl_dvl, +template +void Force_Stress_LCAO::calForcePwPart(ModuleBase::matrix& fvl_dvl, ModuleBase::matrix& fewalds, ModuleBase::matrix& fcc, ModuleBase::matrix& fscc, @@ -699,53 +701,73 @@ void Force_Stress_LCAO::calForcePwPart(ModuleBase::matrix& fvl_dvl, } // overlap, kinetic, nonlocal pseudopotential, Local potential terms in force and stress -void Force_Stress_LCAO::calForceStressIntegralPart(const bool isGammaOnly, - const bool isforce, - const bool isstress, - Local_Orbital_Charge& loc, - const elecstate::ElecState* pelec, - const psi::Psi* psid, - const psi::Psi>* psi, - ModuleBase::matrix& foverlap, - ModuleBase::matrix& ftvnl_dphi, - ModuleBase::matrix& fvnl_dbeta, - ModuleBase::matrix& fvl_dphi, - ModuleBase::matrix& soverlap, - ModuleBase::matrix& stvnl_dphi, - ModuleBase::matrix& svnl_dbeta, +template<> +void Force_Stress_LCAO::calForceStressIntegralPart(const bool isGammaOnly, + const bool isforce, + const bool isstress, + Local_Orbital_Charge& loc, + const elecstate::ElecState* pelec, + const psi::Psi* psi, + ModuleBase::matrix& foverlap, + ModuleBase::matrix& ftvnl_dphi, + ModuleBase::matrix& fvnl_dbeta, + ModuleBase::matrix& fvl_dphi, + ModuleBase::matrix& soverlap, + ModuleBase::matrix& stvnl_dphi, + ModuleBase::matrix& svnl_dbeta, #if __DEEPKS - ModuleBase::matrix& svl_dphi, - ModuleBase::matrix& svnl_dalpha, + ModuleBase::matrix& svl_dphi, + ModuleBase::matrix& svnl_dalpha, #else - ModuleBase::matrix& svl_dphi, + ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, - const K_Vectors& kv) + LCAO_Hamilt& uhm, + const K_Vectors& kv) { - if (isGammaOnly) - { - flk.ftable_gamma(isforce, - isstress, - psid, - loc, - pelec, - foverlap, - ftvnl_dphi, - fvnl_dbeta, - fvl_dphi, - soverlap, - stvnl_dphi, - svnl_dbeta, + flk.ftable_gamma(isforce, + isstress, + psi, + loc, + pelec, + foverlap, + ftvnl_dphi, + fvnl_dbeta, + fvl_dphi, + soverlap, + stvnl_dphi, + svnl_dbeta, #if __DEEPKS - svl_dphi, - svnl_dalpha, + svl_dphi, + svnl_dalpha, #else - svl_dphi, + svl_dphi, #endif - uhm); - } - else - { + uhm); + return; +} +template<> +void Force_Stress_LCAO>::calForceStressIntegralPart(const bool isGammaOnly, + const bool isforce, + const bool isstress, + Local_Orbital_Charge& loc, + const elecstate::ElecState* pelec, + const psi::Psi>* psi, + ModuleBase::matrix& foverlap, + ModuleBase::matrix& ftvnl_dphi, + ModuleBase::matrix& fvnl_dbeta, + ModuleBase::matrix& fvl_dphi, + ModuleBase::matrix& soverlap, + ModuleBase::matrix& stvnl_dphi, + ModuleBase::matrix& svnl_dbeta, +#if __DEEPKS + ModuleBase::matrix& svl_dphi, + ModuleBase::matrix& svnl_dalpha, +#else + ModuleBase::matrix& svl_dphi, +#endif + LCAO_Hamilt& uhm, + const K_Vectors& kv) +{ flk.ftable_k(isforce, isstress, *this->RA, @@ -766,14 +788,13 @@ void Force_Stress_LCAO::calForceStressIntegralPart(const bool isGammaOnly, svl_dphi, #endif uhm, - kv); - } - + kv); return; } // vlocal, hartree, ewald, core correction, exchange-correlation terms in stress -void Force_Stress_LCAO::calStressPwPart(ModuleBase::matrix& sigmadvl, +template +void Force_Stress_LCAO::calStressPwPart(ModuleBase::matrix& sigmadvl, ModuleBase::matrix& sigmahar, ModuleBase::matrix& sigmaewa, ModuleBase::matrix& sigmacc, @@ -820,7 +841,8 @@ void Force_Stress_LCAO::calStressPwPart(ModuleBase::matrix& sigmadvl, #include "module_base/mathzone.h" // do symmetry for total force -void Force_Stress_LCAO::forceSymmetry(ModuleBase::matrix& fcs, ModuleSymmetry::Symmetry* symm) +template +void Force_Stress_LCAO::forceSymmetry(ModuleBase::matrix& fcs, ModuleSymmetry::Symmetry* symm) { double d1, d2, d3; for (int iat = 0; iat < GlobalC::ucell.nat; iat++) @@ -870,3 +892,6 @@ void Force_Stress_LCAO::forceSymmetry(ModuleBase::matrix& fcs, ModuleSymmetry::S } return; } + +template class Force_Stress_LCAO; +template class Force_Stress_LCAO>; \ No newline at end of file diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h index f76913ef2fe..590be8a49cf 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h @@ -14,6 +14,7 @@ #include "module_ri/Exx_LRI.h" #endif +template class Force_Stress_LCAO { // mohan add 2021-02-09 @@ -26,24 +27,23 @@ class Force_Stress_LCAO ~Force_Stress_LCAO(); void getForceStress(const bool isforce, - const bool isstress, - const bool istestf, - const bool istests, - Local_Orbital_Charge& loc, - const elecstate::ElecState* pelec, - const psi::Psi* psid, - const psi::Psi>* psi, - LCAO_Hamilt& uhm, - ModuleBase::matrix& fcs, - ModuleBase::matrix& scs, - const Structure_Factor& sf, - const K_Vectors& kv, - ModulePW::PW_Basis* rhopw, + const bool isstress, + const bool istestf, + const bool istests, + Local_Orbital_Charge& loc, + const elecstate::ElecState* pelec, + const psi::Psi* psi, + LCAO_Hamilt& uhm, + ModuleBase::matrix& fcs, + ModuleBase::matrix& scs, + const Structure_Factor& sf, + const K_Vectors& kv, + ModulePW::PW_Basis* rhopw, #ifdef __EXX - Exx_LRI& exx_lri_double, - Exx_LRI>& exx_lri_complex, + Exx_LRI& exx_lri_double, + Exx_LRI>& exx_lri_complex, #endif - ModuleSymmetry::Symmetry* symm); + ModuleSymmetry::Symmetry* symm); private: int nat; @@ -70,27 +70,26 @@ class Force_Stress_LCAO const Structure_Factor& sf); void calForceStressIntegralPart(const bool isGammaOnly, - const bool isforce, - const bool isstress, - Local_Orbital_Charge& loc, - const elecstate::ElecState* pelec, - const psi::Psi* psid, - const psi::Psi>* psi, - ModuleBase::matrix& foverlap, - ModuleBase::matrix& ftvnl_dphi, - ModuleBase::matrix& fvnl_dbeta, - ModuleBase::matrix& fvl_dphi, - ModuleBase::matrix& soverlap, - ModuleBase::matrix& stvnl_dphi, - ModuleBase::matrix& svnl_dbeta, + const bool isforce, + const bool isstress, + Local_Orbital_Charge& loc, + const elecstate::ElecState* pelec, + const psi::Psi* psi, + ModuleBase::matrix& foverlap, + ModuleBase::matrix& ftvnl_dphi, + ModuleBase::matrix& fvnl_dbeta, + ModuleBase::matrix& fvl_dphi, + ModuleBase::matrix& soverlap, + ModuleBase::matrix& stvnl_dphi, + ModuleBase::matrix& svnl_dbeta, #if __DEEPKS - ModuleBase::matrix& svl_dphi, - ModuleBase::matrix& svnl_dalpha, + ModuleBase::matrix& svl_dphi, + ModuleBase::matrix& svnl_dalpha, #else - ModuleBase::matrix& svl_dphi, + ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, - const K_Vectors& kv); + LCAO_Hamilt& uhm, + const K_Vectors& kv); void calStressPwPart(ModuleBase::matrix& sigmadvl, ModuleBase::matrix& sigmahar, diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp index 106739491f7..2962c376bbb 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp @@ -77,10 +77,10 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, GlobalC::ld .cal_f_delta_gamma(dm_gamma, GlobalC::ucell, GlobalC::ORB, GlobalC::GridD, isstress, svnl_dalpha); #ifdef __MPI - Parallel_Reduce::reduce_double_all(GlobalC::ld.F_delta.c, GlobalC::ld.F_delta.nr * GlobalC::ld.F_delta.nc); + Parallel_Reduce::reduce_all(GlobalC::ld.F_delta.c, GlobalC::ld.F_delta.nr * GlobalC::ld.F_delta.nc); if (isstress) { - Parallel_Reduce::reduce_double_pool(svnl_dalpha.c, svnl_dalpha.nr * svnl_dalpha.nc); + Parallel_Reduce::reduce_pool(svnl_dalpha.c, svnl_dalpha.nr * svnl_dalpha.nc); } #endif if (GlobalV::deepks_out_unittest) @@ -104,17 +104,17 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, if (isforce) { - Parallel_Reduce::reduce_double_pool(foverlap.c, foverlap.nr * foverlap.nc); - Parallel_Reduce::reduce_double_pool(ftvnl_dphi.c, ftvnl_dphi.nr * ftvnl_dphi.nc); - Parallel_Reduce::reduce_double_pool(fvnl_dbeta.c, fvnl_dbeta.nr * fvnl_dbeta.nc); - Parallel_Reduce::reduce_double_pool(fvl_dphi.c, fvl_dphi.nr * fvl_dphi.nc); + Parallel_Reduce::reduce_pool(foverlap.c, foverlap.nr * foverlap.nc); + Parallel_Reduce::reduce_pool(ftvnl_dphi.c, ftvnl_dphi.nr * ftvnl_dphi.nc); + Parallel_Reduce::reduce_pool(fvnl_dbeta.c, fvnl_dbeta.nr * fvnl_dbeta.nc); + Parallel_Reduce::reduce_pool(fvl_dphi.c, fvl_dphi.nr * fvl_dphi.nc); } if (isstress) { - Parallel_Reduce::reduce_double_pool(soverlap.c, soverlap.nr * soverlap.nc); - Parallel_Reduce::reduce_double_pool(stvnl_dphi.c, stvnl_dphi.nr * stvnl_dphi.nc); - Parallel_Reduce::reduce_double_pool(svnl_dbeta.c, svnl_dbeta.nr * svnl_dbeta.nc); - Parallel_Reduce::reduce_double_pool(svl_dphi.c, svl_dphi.nr * svl_dphi.nc); + Parallel_Reduce::reduce_pool(soverlap.c, soverlap.nr * soverlap.nc); + Parallel_Reduce::reduce_pool(stvnl_dphi.c, stvnl_dphi.nr * stvnl_dphi.nc); + Parallel_Reduce::reduce_pool(svnl_dbeta.c, svnl_dbeta.nr * svnl_dbeta.nc); + Parallel_Reduce::reduce_pool(svl_dphi.c, svl_dphi.nr * svl_dphi.nc); } // delete DSloc_x, DSloc_y, DSloc_z diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h index 82099d6c7a6..e9efd88b425 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h @@ -12,7 +12,8 @@ class Force_LCAO_gamma { - public: +public: + template friend class Force_Stress_LCAO; Force_LCAO_gamma(); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp index 1da03e06676..af861f5f26e 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp @@ -98,10 +98,10 @@ void Force_LCAO_k::ftable_k(const bool isforce, isstress, svnl_dalpha); #ifdef __MPI - Parallel_Reduce::reduce_double_all(GlobalC::ld.F_delta.c, GlobalC::ld.F_delta.nr * GlobalC::ld.F_delta.nc); + Parallel_Reduce::reduce_all(GlobalC::ld.F_delta.c, GlobalC::ld.F_delta.nr * GlobalC::ld.F_delta.nc); if (isstress) { - Parallel_Reduce::reduce_double_pool(svnl_dalpha.c, svnl_dalpha.nr * svnl_dalpha.nc); + Parallel_Reduce::reduce_pool(svnl_dalpha.c, svnl_dalpha.nr * svnl_dalpha.nc); } #endif if (GlobalV::deepks_out_unittest) @@ -131,17 +131,17 @@ void Force_LCAO_k::ftable_k(const bool isforce, //---------------------------------------------------------------- if (isforce) { - Parallel_Reduce::reduce_double_pool(foverlap.c, foverlap.nr * foverlap.nc); - Parallel_Reduce::reduce_double_pool(ftvnl_dphi.c, ftvnl_dphi.nr * ftvnl_dphi.nc); - Parallel_Reduce::reduce_double_pool(fvnl_dbeta.c, fvnl_dbeta.nr * fvnl_dbeta.nc); - Parallel_Reduce::reduce_double_pool(fvl_dphi.c, fvl_dphi.nr * fvl_dphi.nc); + Parallel_Reduce::reduce_pool(foverlap.c, foverlap.nr * foverlap.nc); + Parallel_Reduce::reduce_pool(ftvnl_dphi.c, ftvnl_dphi.nr * ftvnl_dphi.nc); + Parallel_Reduce::reduce_pool(fvnl_dbeta.c, fvnl_dbeta.nr * fvnl_dbeta.nc); + Parallel_Reduce::reduce_pool(fvl_dphi.c, fvl_dphi.nr * fvl_dphi.nc); } if (isstress) { - Parallel_Reduce::reduce_double_pool(soverlap.c, soverlap.nr * soverlap.nc); - Parallel_Reduce::reduce_double_pool(stvnl_dphi.c, stvnl_dphi.nr * stvnl_dphi.nc); - Parallel_Reduce::reduce_double_pool(svnl_dbeta.c, svnl_dbeta.nr * svnl_dbeta.nc); - Parallel_Reduce::reduce_double_pool(svl_dphi.c, svl_dphi.nr * svl_dphi.nc); + Parallel_Reduce::reduce_pool(soverlap.c, soverlap.nr * soverlap.nc); + Parallel_Reduce::reduce_pool(stvnl_dphi.c, stvnl_dphi.nr * stvnl_dphi.nc); + Parallel_Reduce::reduce_pool(svnl_dbeta.c, svnl_dbeta.nr * svnl_dbeta.nc); + Parallel_Reduce::reduce_pool(svl_dphi.c, svl_dphi.nr * svl_dphi.nc); } ModuleBase::timer::tick("Force_LCAO_k", "ftable_k"); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h index f22bb74b6bd..0deb189aa56 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h @@ -12,7 +12,8 @@ class Force_LCAO_k : public Force_LCAO_gamma { - public: +public: + template friend class Force_Stress_LCAO; Force_LCAO_k(); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp index b510ea70a0f..94d7408c9f6 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp @@ -508,7 +508,7 @@ void LCAO_Hamilt::calculat_HR_dftu_sparse(const int ¤t_spin, const double count++; } - Parallel_Reduce::reduce_int_all(nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(nonzero_num, total_R_num); double *HR_tmp = new double[this->LM->ParaV->nloc]; double *SR_tmp = new double[this->LM->ParaV->nloc]; @@ -621,7 +621,7 @@ void LCAO_Hamilt::calculat_HR_dftu_soc_sparse(const int ¤t_spin, const dou count++; } - Parallel_Reduce::reduce_int_all(nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(nonzero_num, total_R_num); std::complex *HR_soc_tmp = new std::complex[this->LM->ParaV->nloc]; std::complex *SR_soc_tmp = new std::complex[this->LM->ParaV->nloc]; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.cpp index 38eaddca199..9c7e8309d8f 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.cpp @@ -102,7 +102,7 @@ HamiltLCAO::HamiltLCAO( } } - // Gamma_only case to initialize HamiltLCAO, opsd will be used + // Gamma_only case to initialize HamiltLCAO // // code block to construct Operator Chains if(std::is_same::value) @@ -365,39 +365,18 @@ void HamiltLCAO::updateHk(const int ik) ModuleBase::timer::tick("HamiltLCAO", "updateHk"); } -template <> -void HamiltLCAO::refresh() -{ - dynamic_cast*>(this->opsd)->set_hr_done(false); -} -template <> -void HamiltLCAO, double>::refresh() -{ - dynamic_cast, double>*>(this->ops)->set_hr_done(false); -} -template <> -void HamiltLCAO, std::complex>::refresh() +template +void HamiltLCAO::refresh() { - dynamic_cast, std::complex>*>(this->ops)->set_hr_done(false); + dynamic_cast*>(this->ops)->set_hr_done(false); } // get Operator base class pointer -template <> -Operator*& HamiltLCAO::getOperator() -{ - return this->opsd; -} -template <> -Operator>*& HamiltLCAO, double>::getOperator() -{ - return this->ops; -} -template <> -Operator>*& HamiltLCAO, std::complex>::getOperator() +template +Operator*& HamiltLCAO::getOperator() { return this->ops; } - // getHk template <> std::vector& HamiltLCAO::getHk(LCAO_Matrix* LM) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h b/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h index 6802cd4c0d4..1cbd1deb185 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h @@ -19,7 +19,7 @@ namespace hamilt // template first for type of k space H matrix elements // template second for type of temporary matrix, gamma_only fix-gamma-matrix + S-gamma, multi-k fix-Real + S-Real template -class HamiltLCAO : public Hamilt> +class HamiltLCAO : public Hamilt { public: /** @@ -45,15 +45,11 @@ class HamiltLCAO : public Hamilt> { delete this->ops; } - if (this->opsd != nullptr) - { - delete this->opsd; - } delete this->hR; delete this->sR; }; - /// get pointer of Operator , the return will be opsd or ops + /// get pointer of Operator ops Operator*& getOperator(); /// get hk-pointer of std::vector, the return will be LM->Hloc or LM->Hloc2 std::vector& getHk(LCAO_Matrix* LM); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.cpp index 57eb7919b6f..c71d3042807 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.cpp @@ -57,29 +57,33 @@ Local_Orbital_Charge::~Local_Orbital_Charge() } } +void Local_Orbital_Charge::allocate_dm_wfc(const Grid_Technique& gt, + elecstate::ElecState* pelec, + Local_Orbital_wfc& lowf, + psi::Psi* psi, + const K_Vectors& kv) +{ + ModuleBase::TITLE("Local_Orbital_Charge", "allocate_dm_wfc"); + this->LOWF = &lowf; + this->LOWF->gridt = > + // here we reset the density matrix dimension. + this->allocate_gamma(gt.lgd, psi, pelec, kv.nks); + return; +} void Local_Orbital_Charge::allocate_dm_wfc(const Grid_Technique >, - elecstate::ElecState *pelec, - Local_Orbital_wfc &lowf, - psi::Psi *psid, - psi::Psi> *psi, - const K_Vectors& kv) + elecstate::ElecState* pelec, + Local_Orbital_wfc& lowf, + psi::Psi>* psi, + const K_Vectors& kv) { ModuleBase::TITLE("Local_Orbital_Charge", "allocate_dm_wfc"); this->LOWF = &lowf; this->LOWF->gridt = > - if (GlobalV::GAMMA_ONLY_LOCAL) - { - // here we reset the density matrix dimension. - this->allocate_gamma(gt.lgd, psid, pelec, kv.nks); - } - else - { - lowf.allocate_k(gt.lgd, psi, pelec, kv.nks, kv.nkstot, kv.kvec_c); - this->allocate_DM_k(kv.nks, gt.nnrg); - } - + // here we reset the density matrix dimension. + lowf.allocate_k(gt.lgd, psi, pelec, kv.nks, kv.nkstot, kv.kvec_c); + this->allocate_DM_k(kv.nks, gt.nnrg); return; } diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h index 8c5005de165..c818d9ac875 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h @@ -24,10 +24,13 @@ class Local_Orbital_Charge void allocate_dm_wfc(const Grid_Technique& gt, elecstate::ElecState* pelec, Local_Orbital_wfc &lowf, - psi::Psi* psid, + psi::Psi* psi, + const K_Vectors& kv); + void allocate_dm_wfc(const Grid_Technique& gt, + elecstate::ElecState* pelec, + Local_Orbital_wfc& lowf, psi::Psi>* psi, const K_Vectors& kv); - //----------------- // in DM_gamma.cpp //----------------- diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/operator_lcao.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/operator_lcao.cpp index 80b1a0ebf09..098d559ca16 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/operator_lcao.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/operator_lcao.cpp @@ -16,7 +16,7 @@ void OperatorLCAO::get_hs_pointers() { ModuleBase::timer::tick("OperatorLCAO", "get_hs_pointers"); this->hmatrix_k = this->LM->Hloc.data(); - if ((this->new_e_iteration && ik == 0) || hsolver::HSolverLCAO::out_mat_hs) + if ((this->new_e_iteration && ik == 0) || hsolver::HSolverLCAO::out_mat_hs) { if (this->smatrix_k == nullptr) { @@ -26,7 +26,7 @@ void OperatorLCAO::get_hs_pointers() const int inc = 1; BlasConnector::copy(this->LM->Sloc.size(), this->LM->Sloc.data(), inc, this->smatrix_k, inc); #ifdef __ELPA - hsolver::DiagoElpa::DecomposedState = 0; + hsolver::DiagoElpa::DecomposedState = 0; #endif this->new_e_iteration = false; } diff --git a/source/module_hamilt_lcao/module_deepks/LCAO_deepks_mpi.cpp b/source/module_hamilt_lcao/module_deepks/LCAO_deepks_mpi.cpp index 7e8f820c4d8..3be7413ac4d 100644 --- a/source/module_hamilt_lcao/module_deepks/LCAO_deepks_mpi.cpp +++ b/source/module_hamilt_lcao/module_deepks/LCAO_deepks_mpi.cpp @@ -15,7 +15,7 @@ void LCAO_Deepks::allsum_deepks( { for(int inl=0;inl> } } } - Parallel_Reduce::reduce_double_all(this->o_delta(0,hl)); + Parallel_Reduce::reduce_all(this->o_delta(0, hl)); } return; } @@ -75,7 +75,7 @@ void LCAO_Deepks::cal_o_delta_k(const std::vectoro_delta(ik,hl) = o_delta_k.real(); }// end hl }// end nks diff --git a/source/module_hamilt_lcao/module_deepks/LCAO_deepks_torch.cpp b/source/module_hamilt_lcao/module_deepks/LCAO_deepks_torch.cpp index 3adddab38b2..33801990835 100644 --- a/source/module_hamilt_lcao/module_deepks/LCAO_deepks_torch.cpp +++ b/source/module_hamilt_lcao/module_deepks/LCAO_deepks_torch.cpp @@ -518,7 +518,7 @@ void LCAO_Deepks::cal_orbital_precalc(const std::vectorinlmax; inl++) { - Parallel_Reduce::reduce_double_all(this->orbital_pdm_shell[0][hl][inl],(2 * this->lmaxd + 1) * (2 * this->lmaxd + 1)); + Parallel_Reduce::reduce_all(this->orbital_pdm_shell[0][hl][inl], (2 * this->lmaxd + 1) * (2 * this->lmaxd + 1)); } } #endif @@ -701,7 +701,7 @@ void LCAO_Deepks::cal_orbital_precalc_k(const std::vectorinlmax; inl++) { - Parallel_Reduce::reduce_double_all(this->orbital_pdm_shell[iks][hl][inl],(2 * this->lmaxd + 1) * (2 * this->lmaxd + 1)); + Parallel_Reduce::reduce_all(this->orbital_pdm_shell[iks][hl][inl], (2 * this->lmaxd + 1)* (2 * this->lmaxd + 1)); } } } diff --git a/source/module_hamilt_lcao/module_deepks/LCAO_deepks_vdelta.cpp b/source/module_hamilt_lcao/module_deepks/LCAO_deepks_vdelta.cpp index 39bf45e121e..38adb30bab8 100644 --- a/source/module_hamilt_lcao/module_deepks/LCAO_deepks_vdelta.cpp +++ b/source/module_hamilt_lcao/module_deepks/LCAO_deepks_vdelta.cpp @@ -395,7 +395,7 @@ void LCAO_Deepks::cal_e_delta_band(const std::vector>& dm) } } #ifdef __MPI - Parallel_Reduce::reduce_double_all(this->e_delta_band); + Parallel_Reduce::reduce_all(this->e_delta_band); #endif return; } @@ -436,7 +436,7 @@ void LCAO_Deepks::cal_e_delta_band_k(const std::vectore_delta_band = e_delta_band_k.real(); #ifdef __MPI - Parallel_Reduce::reduce_double_all(this->e_delta_band); + Parallel_Reduce::reduce_all(this->e_delta_band); #endif return; } diff --git a/source/module_hamilt_lcao/module_dftu/dftu_force.cpp b/source/module_hamilt_lcao/module_dftu/dftu_force.cpp index abc572d196c..47295735191 100644 --- a/source/module_hamilt_lcao/module_dftu/dftu_force.cpp +++ b/source/module_hamilt_lcao/module_dftu/dftu_force.cpp @@ -145,14 +145,14 @@ void DFTU::force_stress(const elecstate::ElecState* pelec, #ifdef __MPI if (GlobalV::CAL_FORCE) { - Parallel_Reduce::reduce_double_pool(force_dftu.c, force_dftu.nr * force_dftu.nc); + Parallel_Reduce::reduce_pool(force_dftu.c, force_dftu.nr * force_dftu.nc); } #endif if (GlobalV::CAL_STRESS) { #ifdef __MPI - Parallel_Reduce::reduce_double_pool(stress_dftu.c, stress_dftu.nr * stress_dftu.nc); + Parallel_Reduce::reduce_pool(stress_dftu.c, stress_dftu.nr * stress_dftu.nc); #endif for (int i = 0; i < 3; i++) diff --git a/source/module_hamilt_lcao/module_gint/gint_k_pvpr.cpp b/source/module_hamilt_lcao/module_gint/gint_k_pvpr.cpp index ecdcf0cc561..ca672bcfbb9 100644 --- a/source/module_hamilt_lcao/module_gint/gint_k_pvpr.cpp +++ b/source/module_hamilt_lcao/module_gint/gint_k_pvpr.cpp @@ -370,7 +370,7 @@ void Gint_k::folding_vl_k(const int &ik, { #endif // collect the matrix after folding. - Parallel_Reduce::reduce_complex_double_pool( tmp.data(), tmp.size() ); + Parallel_Reduce::reduce_pool(tmp.data(), tmp.size()); #ifdef _OPENMP } #endif diff --git a/source/module_hamilt_lcao/module_gint/gint_k_sparse.cpp b/source/module_hamilt_lcao/module_gint/gint_k_sparse.cpp index e95137fd3e6..a3b77194a3e 100644 --- a/source/module_hamilt_lcao/module_gint/gint_k_sparse.cpp +++ b/source/module_hamilt_lcao/module_gint/gint_k_sparse.cpp @@ -51,10 +51,10 @@ void Gint_k::distribute_pvpR_sparseMatrix( count++; } - Parallel_Reduce::reduce_int_all(nonzero_num, total_R_num); - Parallel_Reduce::reduce_int_all(minus_nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(minus_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(minus_nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(minus_nonzero_num, total_R_num); double* tmp = nullptr; tmp = new double[GlobalV::NLOCAL]; @@ -108,7 +108,7 @@ void Gint_k::distribute_pvpR_sparseMatrix( } } - Parallel_Reduce::reduce_double_pool(tmp, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(tmp, GlobalV::NLOCAL); if (LM->ParaV->global2local_row(row) >= 0) { @@ -186,10 +186,10 @@ void Gint_k::distribute_pvpR_soc_sparseMatrix( count++; } - Parallel_Reduce::reduce_int_all(nonzero_num, total_R_num); - Parallel_Reduce::reduce_int_all(minus_nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(minus_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(minus_nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(minus_nonzero_num, total_R_num); std::complex* tmp_soc = nullptr; tmp_soc = new std::complex[GlobalV::NLOCAL]; @@ -242,7 +242,7 @@ void Gint_k::distribute_pvpR_soc_sparseMatrix( } } - Parallel_Reduce::reduce_complex_double_pool(tmp_soc, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(tmp_soc, GlobalV::NLOCAL); if (LM->ParaV->global2local_row(row) >= 0) { diff --git a/source/module_hamilt_lcao/module_gint/gint_k_sparse1.cpp b/source/module_hamilt_lcao/module_gint/gint_k_sparse1.cpp index 32e20fb2064..8207a8a2c4b 100644 --- a/source/module_hamilt_lcao/module_gint/gint_k_sparse1.cpp +++ b/source/module_hamilt_lcao/module_gint/gint_k_sparse1.cpp @@ -51,10 +51,10 @@ void Gint_k::distribute_pvdpR_sparseMatrix( count++; } - Parallel_Reduce::reduce_int_all(nonzero_num, total_R_num); - Parallel_Reduce::reduce_int_all(minus_nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(minus_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(minus_nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(minus_nonzero_num, total_R_num); double* tmp = nullptr; tmp = new double[GlobalV::NLOCAL]; @@ -108,7 +108,7 @@ void Gint_k::distribute_pvdpR_sparseMatrix( } } - Parallel_Reduce::reduce_double_pool(tmp, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(tmp, GlobalV::NLOCAL); if (LM->ParaV->global2local_row(row) >= 0) { @@ -208,10 +208,10 @@ void Gint_k::distribute_pvdpR_soc_sparseMatrix( count++; } - Parallel_Reduce::reduce_int_all(nonzero_num, total_R_num); - Parallel_Reduce::reduce_int_all(minus_nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(nonzero_num, total_R_num); - // Parallel_Reduce::reduce_int_pool(minus_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(minus_nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(nonzero_num, total_R_num); + // Parallel_Reduce::reduce_pool(minus_nonzero_num, total_R_num); std::complex* tmp_soc = nullptr; tmp_soc = new std::complex[GlobalV::NLOCAL]; @@ -264,7 +264,7 @@ void Gint_k::distribute_pvdpR_soc_sparseMatrix( } } - Parallel_Reduce::reduce_complex_double_pool(tmp_soc, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(tmp_soc, GlobalV::NLOCAL); if (LM->ParaV->global2local_row(row) >= 0) { diff --git a/source/module_hamilt_lcao/module_gint/grid_technique.cpp b/source/module_hamilt_lcao/module_gint/grid_technique.cpp index 1077941c075..b3f9b70bde6 100644 --- a/source/module_hamilt_lcao/module_gint/grid_technique.cpp +++ b/source/module_hamilt_lcao/module_gint/grid_technique.cpp @@ -257,7 +257,7 @@ void Grid_Technique::init_atoms_on_grid(const int& ny, const int& nplane, const GlobalV::ofs_running << " No atoms on this sub-FFT-mesh." << std::endl; stop = 1; } - Parallel_Reduce::reduce_int_all( stop ); + Parallel_Reduce::reduce_all(stop); if(stop) { ModuleBase::WARNING("Grid_Technique::init_atoms_on_grid","No atom on this sub-FFT-mesh."); diff --git a/source/module_hamilt_lcao/module_tddft/evolve_elec.h b/source/module_hamilt_lcao/module_tddft/evolve_elec.h index 5ad0123e5fa..c5af348f650 100644 --- a/source/module_hamilt_lcao/module_tddft/evolve_elec.h +++ b/source/module_hamilt_lcao/module_tddft/evolve_elec.h @@ -22,7 +22,7 @@ class Evolve_elec { friend class ELEC_scf; - friend class ModuleESolver::ESolver_KS_LCAO; + friend class ModuleESolver::ESolver_KS_LCAO, double>; friend class ModuleESolver::ESolver_KS_LCAO_TDDFT; public: diff --git a/source/module_hamilt_pw/hamilt_ofdft/kedf_lkt.cpp b/source/module_hamilt_pw/hamilt_ofdft/kedf_lkt.cpp index 3e655204994..e75292a8776 100644 --- a/source/module_hamilt_pw/hamilt_ofdft/kedf_lkt.cpp +++ b/source/module_hamilt_pw/hamilt_ofdft/kedf_lkt.cpp @@ -39,7 +39,7 @@ double KEDF_LKT::get_energy(const double *const *prho, ModulePW::PW_Basis *pw_rh // Waiting for update } this->LKTenergy = energy; - Parallel_Reduce::reduce_double_all(this->LKTenergy); + Parallel_Reduce::reduce_all(this->LKTenergy); delete[] as; for (int i = 0; i < 3; ++i) @@ -124,7 +124,7 @@ void KEDF_LKT::lkt_potential(const double *const *prho, ModulePW::PW_Basis *pw_r } this->LKTenergy *= this->cTF * this->dV; - Parallel_Reduce::reduce_double_all(this->LKTenergy); + Parallel_Reduce::reduce_all(this->LKTenergy); } else if (GlobalV::NSPIN == 2) { @@ -180,7 +180,7 @@ void KEDF_LKT::get_stress(const double cell_vol, const double *const *prho, Modu integral_term += 1.0 / 3.0 * as[ir] * std::pow(prho[0][ir], 5.0 / 3.0) * coef; } } - Parallel_Reduce::reduce_double_all(integral_term); + Parallel_Reduce::reduce_all(integral_term); integral_term *= this->cTF * this->dV / cell_vol; this->stress(alpha, beta) += integral_term; diff --git a/source/module_hamilt_pw/hamilt_ofdft/kedf_tf.cpp b/source/module_hamilt_pw/hamilt_ofdft/kedf_tf.cpp index 3bfd9c43f54..2948dd61adf 100644 --- a/source/module_hamilt_pw/hamilt_ofdft/kedf_tf.cpp +++ b/source/module_hamilt_pw/hamilt_ofdft/kedf_tf.cpp @@ -37,7 +37,7 @@ double KEDF_TF::get_energy(const double *const *prho) energy *= 0.5 * this->dV * this->cTF * this->tf_weight; } this->TFenergy = energy; - Parallel_Reduce::reduce_double_all(this->TFenergy); + Parallel_Reduce::reduce_all(this->TFenergy); return energy; } diff --git a/source/module_hamilt_pw/hamilt_ofdft/kedf_vw.cpp b/source/module_hamilt_pw/hamilt_ofdft/kedf_vw.cpp index 752af9b5d11..777276d5d11 100644 --- a/source/module_hamilt_pw/hamilt_ofdft/kedf_vw.cpp +++ b/source/module_hamilt_pw/hamilt_ofdft/kedf_vw.cpp @@ -53,7 +53,7 @@ double KEDF_vW::get_energy(double **pphi, ModulePW::PW_Basis *pw_rho) energy *= 0.5 * this->dV * 0.5 * this->vw_weight * 2.; // vw_weight * 2 to convert Hartree to Ry } this->vWenergy = energy; - Parallel_Reduce::reduce_double_all(this->vWenergy); + Parallel_Reduce::reduce_all(this->vWenergy); for (int is = 0; is < GlobalV::NSPIN; ++is) { @@ -160,7 +160,7 @@ void KEDF_vW::vW_potential(const double *const *pphi, ModulePW::PW_Basis *pw_rho energy *= 0.5 * this->dV * 0.5 * this->vw_weight * 2.; // vw_weight * 2 to convert Hartree to Ry } this->vWenergy = energy; - Parallel_Reduce::reduce_double_all(this->vWenergy); + Parallel_Reduce::reduce_all(this->vWenergy); for (int is = 0; is < GlobalV::NSPIN; ++is) { @@ -216,7 +216,7 @@ void KEDF_vW::get_stress(const double *const *pphi, ModulePW::PW_Basis *pw_rho, this->stress(alpha, beta) += tempPhi[is][ir] * ggPhi[ir]; } } - Parallel_Reduce::reduce_double_all(this->stress(alpha, beta)); + Parallel_Reduce::reduce_all(this->stress(alpha, beta)); this->stress(alpha, beta) *= -1. * this->vw_weight * 2. / pw_rho->nxyz; // vw_weight * 2 to convert Hartree to Ry } diff --git a/source/module_hamilt_pw/hamilt_ofdft/kedf_wt.cpp b/source/module_hamilt_pw/hamilt_ofdft/kedf_wt.cpp index 34b86808dbf..29b12a18a95 100644 --- a/source/module_hamilt_pw/hamilt_ofdft/kedf_wt.cpp +++ b/source/module_hamilt_pw/hamilt_ofdft/kedf_wt.cpp @@ -65,7 +65,7 @@ double KEDF_WT::get_energy(const double * const * prho, ModulePW::PW_Basis *pw_r // energy *= 0.5 * this->dV * 0.5; } this->WTenergy = energy; - Parallel_Reduce::reduce_double_all(this->WTenergy); + Parallel_Reduce::reduce_all(this->WTenergy); for (int is = 0; is < GlobalV::NSPIN; ++is) { @@ -140,7 +140,7 @@ void KEDF_WT::WT_potential(const double * const *prho, ModulePW::PW_Basis *pw_rh // energy *= 0.5 * this->dV * 0.5; } this->WTenergy = energy; - Parallel_Reduce::reduce_double_all(this->WTenergy); + Parallel_Reduce::reduce_all(this->WTenergy); for (int is = 0; is < GlobalV::NSPIN; ++is) { @@ -221,7 +221,7 @@ void KEDF_WT::get_stress(double cellVol, const double * const * prho, ModulePW:: { for (int b = a; b < 3; ++b) { - Parallel_Reduce::reduce_double_all(this->stress(a,b)); + Parallel_Reduce::reduce_all(this->stress(a, b)); if (GlobalV::GAMMA_ONLY_PW) { diff --git a/source/module_hamilt_pw/hamilt_pwdft/forces.cpp b/source/module_hamilt_pw/hamilt_pwdft/forces.cpp index d538e730771..2918fd952b7 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/forces.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/forces.cpp @@ -478,7 +478,7 @@ void Forces::cal_force_loc(ModuleBase::matrix& forcelc, } // this->print(GlobalV::ofs_running, "local forces", forcelc); - Parallel_Reduce::reduce_double_pool(forcelc.c, forcelc.nr * forcelc.nc); + Parallel_Reduce::reduce_pool(forcelc.c, forcelc.nr * forcelc.nc); delete[] aux; ModuleBase::timer::tick("Forces", "cal_force_loc"); return; @@ -701,7 +701,7 @@ void Forces::cal_force_ew(ModuleBase::matrix& forceion, } #endif - Parallel_Reduce::reduce_double_pool(forceion.c, forceion.nr * forceion.nc); +Parallel_Reduce::reduce_pool(forceion.c, forceion.nr* forceion.nc); // this->print(GlobalV::ofs_running, "ewald forces", forceion); @@ -865,7 +865,7 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc, delete[] rhocg; delete[] psiv; // mohan fix bug 2012-03-22 - Parallel_Reduce::reduce_double_pool(forcecc.c, forcecc.nr * forcecc.nc); // qianrui fix a bug for kpar > 1 + Parallel_Reduce::reduce_pool(forcecc.c, forcecc.nr * forcecc.nc); // qianrui fix a bug for kpar > 1 ModuleBase::timer::tick("Forces", "cal_force_cc"); return; } @@ -989,13 +989,13 @@ void Forces::cal_force_nl(ModuleBase::matrix& forcenl, std::complex* h_becp = nullptr; resmem_complex_h_op()(this->cpu_ctx, h_becp, GlobalV::NBANDS * nkb); syncmem_complex_d2h_op()(this->cpu_ctx, this->ctx, h_becp, becp, GlobalV::NBANDS * nkb); - Parallel_Reduce::reduce_complex_double_pool(h_becp, GlobalV::NBANDS * nkb); + Parallel_Reduce::reduce_pool(h_becp, GlobalV::NBANDS * nkb); syncmem_complex_h2d_op()(this->ctx, this->cpu_ctx, becp, h_becp, GlobalV::NBANDS * nkb); delmem_complex_h_op()(this->cpu_ctx, h_becp); } else { - Parallel_Reduce::reduce_complex_double_pool(becp, GlobalV::NBANDS * nkb); + Parallel_Reduce::reduce_pool(becp, GlobalV::NBANDS * nkb); } // out.printcm_real("becp",becp,1.0e-4); // Calculate the derivative of beta, @@ -1034,7 +1034,7 @@ void Forces::cal_force_nl(ModuleBase::matrix& forcenl, // don't need to reduce here, keep dbecp different in each processor, // and at last sum up all the forces. - // Parallel_Reduce::reduce_complex_double_pool( dbecp.ptr, dbecp.ndata); + // Parallel_Reduce::reduce_pool( dbecp.ptr, dbecp.ndata); cal_force_nl_op()(this->ctx, GlobalC::ppcell.multi_proj, nbands_occ, @@ -1063,7 +1063,7 @@ void Forces::cal_force_nl(ModuleBase::matrix& forcenl, syncmem_var_d2h_op()(this->cpu_ctx, this->ctx, forcenl.c, force, forcenl.nr * forcenl.nc); } // sum up forcenl from all processors - Parallel_Reduce::reduce_double_all(forcenl.c, forcenl.nr * forcenl.nc); + Parallel_Reduce::reduce_all(forcenl.c, forcenl.nr* forcenl.nc); delete[] h_atom_nh; delete[] h_atom_na; @@ -1210,7 +1210,7 @@ void Forces::cal_force_scc(ModuleBase::matrix& forcescc, } } - Parallel_Reduce::reduce_double_pool(forcescc.c, forcescc.nr * forcescc.nc); + Parallel_Reduce::reduce_pool(forcescc.c, forcescc.nr* forcescc.nc); delete[] psic; // mohan fix bug 2012-03-22 delete[] rhocgnt; // mohan fix bug 2012-03-22 diff --git a/source/module_hamilt_pw/hamilt_pwdft/forces.h b/source/module_hamilt_pw/hamilt_pwdft/forces.h index a0feac2bcf9..dc55e2001f5 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/forces.h +++ b/source/module_hamilt_pw/hamilt_pwdft/forces.h @@ -17,7 +17,8 @@ template class Forces { - public: +public: + template friend class Force_Stress_LCAO; /* This routine is a driver routine which compute the forces * acting on the atoms, the complete forces in plane waves @@ -65,7 +66,7 @@ class Forces Device* ctx = {}; psi::DEVICE_CPU* cpu_ctx = {}; psi::AbacusDevice_t device = {}; - using gemm_op = hsolver::gemm_op; + using gemm_op = hsolver::gemm_op, Device>; using cal_vkb1_nl_op = hamilt::cal_vkb1_nl_op; using cal_force_nl_op = hamilt::cal_force_nl_op; diff --git a/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.cpp b/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.cpp index 7e642cd5898..a6a35146555 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.cpp @@ -123,19 +123,6 @@ void HamiltPW::updateHk(const int ik) ModuleBase::TITLE("HamiltPW","updateHk"); } -template -void HamiltPW::sPsi -( - const T *psi, - T *spsi, - size_t size -) const -{ - // ModuleBase::GlobalFunc::COPYARRAY(psi, spsi, size); - // denghui replaced at 2022.11.04 - syncmem_complex_op()(this->ctx, this->ctx, spsi, psi, size); -} - template template HamiltPW::HamiltPW(const HamiltPW *hamilt) diff --git a/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.h b/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.h index 08c88323fff..c85ae107a0e 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.h +++ b/source/module_hamilt_pw/hamilt_pwdft/hamilt_pw.h @@ -25,14 +25,6 @@ class HamiltPW : public Hamilt // for target K point, update consequence of hPsi() and matrix() void updateHk(const int ik) override; - - // core function: for solving eigenvalues of Hamiltonian with iterative method - virtual void sPsi(const T *psi_in, T *spsi, const size_t size) const override; - - private: - - Device *ctx = {}; - using syncmem_complex_op = psi::memory::synchronize_memory_op; }; } // namespace hamilt diff --git a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/meta_pw.h b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/meta_pw.h index 3e0e716d937..50e97e02c48 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/meta_pw.h +++ b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/meta_pw.h @@ -80,7 +80,7 @@ class Meta> : public OperatorPW psi::DEVICE_CPU* cpu_ctx = {}; T *porter = nullptr; using meta_op = meta_pw_op; - using vector_mul_vector_op = hsolver::vector_mul_vector_op; + using vector_mul_vector_op = hsolver::vector_mul_vector_op; using resmem_complex_op = psi::memory::resize_memory_op; using delmem_complex_op = psi::memory::delete_memory_op; }; diff --git a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.cpp b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.cpp index 5fedf2c1c96..313af44b162 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.cpp @@ -276,7 +276,7 @@ void Nonlocal>::act( ); } - Parallel_Reduce::reduce_complex_double_pool(becp, nkb * nbands); + Parallel_Reduce::reduce_pool(becp, nkb * nbands); this->add_nonlocal_pp(tmhpsi, becp, nbands); } diff --git a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.h b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.h index 78c21d36d01..7ae39ea1fd1 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.h +++ b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/nonlocal_pw.h @@ -76,8 +76,8 @@ class Nonlocal> : public OperatorPW Real * deeq = nullptr; T * deeq_nc = nullptr; // using nonlocal_op = nonlocal_pw_op; - using gemv_op = hsolver::gemv_op; - using gemm_op = hsolver::gemm_op; + using gemv_op = hsolver::gemv_op; + using gemm_op = hsolver::gemm_op; using nonlocal_op = nonlocal_pw_op; using setmem_complex_op = psi::memory::set_memory_op; using resmem_complex_op = psi::memory::resize_memory_op; diff --git a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/velocity_pw.cpp b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/velocity_pw.cpp index 75805c7a128..d941160390d 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/operator_pw/velocity_pw.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/operator_pw/velocity_pw.cpp @@ -115,8 +115,8 @@ void Velocity::act &ModuleBase::ONE, this->ppcell->gradvkb.ptr, &max_npw, psi0, &max_npw, &ModuleBase::ZERO, becp2.c, &nkb3); } - Parallel_Reduce::reduce_complex_double_pool(becp1.c, nkb * n_npwx); - Parallel_Reduce::reduce_complex_double_pool(becp2.c, nkb3 * n_npwx); + Parallel_Reduce::reduce_pool(becp1.c, nkb * n_npwx); + Parallel_Reduce::reduce_pool(becp2.c, nkb3 * n_npwx); //2. <\beta \psi>; + using gemm_op = hsolver::gemm_op, Device>; using cal_stress_nl_op = hamilt::cal_stress_nl_op; using cal_dbecp_noevc_nl_op = hamilt::cal_dbecp_noevc_nl_op; diff --git a/source/module_hamilt_pw/hamilt_pwdft/stress_func_cc.cpp b/source/module_hamilt_pw/hamilt_pwdft/stress_func_cc.cpp index 6f5e8b21bc8..beae11ee4a7 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/stress_func_cc.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/stress_func_cc.cpp @@ -180,7 +180,7 @@ void Stress_Func::stress_cc(ModuleBase::matrix& sigma, { for (int m = 0;m< 3;m++) { - Parallel_Reduce::reduce_double_pool( sigma(l,m) ); + Parallel_Reduce::reduce_pool(sigma(l, m)); } } diff --git a/source/module_hamilt_pw/hamilt_pwdft/stress_func_ewa.cpp b/source/module_hamilt_pw/hamilt_pwdft/stress_func_ewa.cpp index b5e0fc8fae3..6a15f35b3a8 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/stress_func_ewa.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/stress_func_ewa.cpp @@ -187,7 +187,7 @@ void Stress_Func::stress_ewa(ModuleBase::matrix& sigma, ModulePW for(int m=0;m -void Stress_Func::stress_gga(ModuleBase::matrix& sigma, - ModulePW::PW_Basis* rho_basis, - const Charge* const chr) -{ - ModuleBase::TITLE("Stress_Func","stress_gga"); - ModuleBase::timer::tick("Stress_Func","stress_gga"); - - int func_type = XC_Functional::get_func_type(); - if (func_type == 0 || func_type == 1) - { - ModuleBase::timer::tick("Stress_Func","stress_gga"); - return; - } - - FPTYPE sigma_gradcorr[3][3]; - std::vector stress_gga; - FPTYPE dum1, dum2; - ModuleBase::matrix dum3; - // call gradcorr to evaluate gradient correction to stress - // the first three terms are etxc, vtxc and v, which - // is not used here, so dummy variables are used. - XC_Functional::gradcorr(dum1, dum2, dum3, chr, rho_basis, &GlobalC::ucell, stress_gga, 1); - - for(int l = 0;l< 3;l++) - { - for(int m = 0;m< l+1;m++) - { - int ind = l*3 + m; - sigma_gradcorr[l][m] = stress_gga [ind]; - sigma_gradcorr[m][l] = sigma_gradcorr[l][m]; - } - } - - for(int l = 0;l<3;l++) - { - for(int m = 0;m<3;m++) - { - Parallel_Reduce::reduce_double_pool( sigma_gradcorr[l][m] ); - } - } - - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - sigma(i, j) += sigma_gradcorr[i][j] / rho_basis->nxyz; - } - } - - ModuleBase::timer::tick("Stress_Func","stress_gga"); - return; -} - -template class Stress_Func; -#if ((defined __CUDA) || (defined __ROCM)) -template class Stress_Func; +#include "stress_func.h" +#include "module_hamilt_general/module_xc/xc_functional.h" +#include "module_base/timer.h" +#include "module_hamilt_pw/hamilt_pwdft/global.h" + +//calculate the GGA stress correction in PW and LCAO +template +void Stress_Func::stress_gga(ModuleBase::matrix& sigma, + ModulePW::PW_Basis* rho_basis, + const Charge* const chr) +{ + ModuleBase::TITLE("Stress_Func","stress_gga"); + ModuleBase::timer::tick("Stress_Func","stress_gga"); + + int func_type = XC_Functional::get_func_type(); + if (func_type == 0 || func_type == 1) + { + ModuleBase::timer::tick("Stress_Func","stress_gga"); + return; + } + + FPTYPE sigma_gradcorr[3][3]; + std::vector stress_gga; + FPTYPE dum1, dum2; + ModuleBase::matrix dum3; + // call gradcorr to evaluate gradient correction to stress + // the first three terms are etxc, vtxc and v, which + // is not used here, so dummy variables are used. + XC_Functional::gradcorr(dum1, dum2, dum3, chr, rho_basis, &GlobalC::ucell, stress_gga, 1); + + for(int l = 0;l< 3;l++) + { + for(int m = 0;m< l+1;m++) + { + int ind = l*3 + m; + sigma_gradcorr[l][m] = stress_gga [ind]; + sigma_gradcorr[m][l] = sigma_gradcorr[l][m]; + } + } + + for(int l = 0;l<3;l++) + { + for(int m = 0;m<3;m++) + { + Parallel_Reduce::reduce_pool(sigma_gradcorr[l][m]); + } + } + + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + sigma(i, j) += sigma_gradcorr[i][j] / rho_basis->nxyz; + } + } + + ModuleBase::timer::tick("Stress_Func","stress_gga"); + return; +} + +template class Stress_Func; +#if ((defined __CUDA) || (defined __ROCM)) +template class Stress_Func; #endif \ No newline at end of file diff --git a/source/module_hamilt_pw/hamilt_pwdft/stress_func_har.cpp b/source/module_hamilt_pw/hamilt_pwdft/stress_func_har.cpp index e10708c4e03..c12e3fc8203 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/stress_func_har.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/stress_func_har.cpp @@ -91,11 +91,11 @@ void Stress_Func::stress_har(ModuleBase::matrix& sigma, ModulePW { for(int m=0;m::stress_kin(ModuleBase::matrix& sigma, { for(int m=0;m<3;m++) { - Parallel_Reduce::reduce_double_all( s_kin[l][m] ); //qianrui fix a bug for kpar > 1 + Parallel_Reduce::reduce_all(s_kin[l][m]); //qianrui fix a bug for kpar > 1 } } diff --git a/source/module_hamilt_pw/hamilt_pwdft/stress_func_loc.cpp b/source/module_hamilt_pw/hamilt_pwdft/stress_func_loc.cpp index 33c561f8553..9051ba8b15d 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/stress_func_loc.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/stress_func_loc.cpp @@ -146,7 +146,7 @@ void Stress_Func::stress_loc(ModuleBase::matrix& sigma, { for(int m=0;m -void Stress_Func::stress_mgga(ModuleBase::matrix& sigma, - const ModuleBase::matrix& wg, - const ModuleBase::matrix& v_ofk, - const Charge* const chr, - K_Vectors* p_kv, - ModulePW::PW_Basis_K* wfc_basis, - const psi::Psi>* psi_in) -{ - ModuleBase::timer::tick("Stress_Func", "stress_mgga"); - - if (GlobalV::NSPIN == 4) - ModuleBase::WARNING_QUIT("stress_mgga", "noncollinear stress + mGGA not implemented"); - - int current_spin = 0; - const int nrxx = wfc_basis->nrxx; - - std::complex* psi; - int ipol2xy[3][3]; - FPTYPE sigma_mgga[3][3]; - - std::complex* gradwfc = new std::complex[nrxx * 3]; - ModuleBase::GlobalFunc::ZEROS(gradwfc, nrxx * 3); - - FPTYPE** crosstaus = new FPTYPE*[GlobalV::NSPIN]; - for (int is = 0; is < GlobalV::NSPIN; ++is) - { - crosstaus[is] = new FPTYPE[nrxx * 6]; - ModuleBase::GlobalFunc::ZEROS(crosstaus[is], 6*nrxx); - } - - for (int ik = 0; ik < p_kv->nks; ik++) - { - if (GlobalV::NSPIN == 2) - current_spin = p_kv->isk[ik]; - const int npw = p_kv->ngk[ik]; - psi = new complex[npw]; - - for (int ibnd = 0; ibnd < GlobalV::NBANDS; ibnd++) - { - const FPTYPE w1 = wg(ik, ibnd) / GlobalC::ucell.omega; - const std::complex* ppsi = nullptr; - ppsi = &(psi_in[0](ik, ibnd, 0)); - for (int ig = 0; ig < npw; ig++) - { - psi[ig] = ppsi[ig]; - } - XC_Functional::grad_wfc(psi, ik, gradwfc, wfc_basis, GlobalC::ucell.tpiba); - - int ipol = 0; - for (int ix = 0; ix < 3; ix++) - { - for (int iy = 0; iy < ix + 1; iy++) - { - ipol2xy[ix][iy] = ipol; - ipol2xy[iy][ix] = ipol; - for (int ir = 0; ir < nrxx; ir++) - { - crosstaus[current_spin][ipol*nrxx + ir] += 2.0 * w1 - * (gradwfc[ix*nrxx + ir].real() * gradwfc[iy*nrxx + ir].real() - + gradwfc[ix*nrxx + ir].imag() * gradwfc[iy*nrxx + ir].imag()); - } - ipol += 1; - } - } - } // band loop - delete[] psi; - } // k loop - -#ifdef __MPI - for (int is = 0; is < GlobalV::NSPIN; ++is) - { - for (int ipol = 0; ipol < 6; ++ipol) - { - chr->reduce_diff_pools(crosstaus[is] + ipol * nrxx); - } - } -#endif - - delete[] gradwfc; - - for (int is = 0; is < GlobalV::NSPIN; is++) - { - for (int ix = 0; ix < 3; ix++) - { - for (int iy = 0; iy < 3; iy++) - { - FPTYPE delta = 0.0; - if (ix == iy) - delta = 1.0; - sigma_mgga[ix][iy] = 0.0; - for (int ir = 0; ir < nrxx; ir++) - { - FPTYPE x - = v_ofk(is, ir) * (chr->kin_r[is][ir] * delta + crosstaus[is][ipol2xy[ix][iy] * nrxx + ir]); - sigma_mgga[ix][iy] += x; - } - } - } - } - - for (int is = 0; is < GlobalV::NSPIN; is++) - { - delete[] crosstaus[is]; - } - delete[] crosstaus; - -#ifdef __MPI - for (int l = 0; l < 3; l++) - { - for (int m = 0; m < 3; m++) - { - Parallel_Reduce::reduce_double_pool(sigma_mgga[l][m]); - } - } -#endif - for (int i = 0; i < 3; i++) - { - for (int j = 0; j < 3; j++) - { - sigma(i, j) += sigma_mgga[i][j] / wfc_basis->nxyz; - } - } - ModuleBase::timer::tick("Stress_Func", "stress_mgga"); - return; -} - -template class Stress_Func; -#if ((defined __CUDA) || (defined __ROCM)) -template class Stress_Func; +#include "module_base/timer.h" +#include "module_hamilt_general/module_xc/xc_functional.h" +#include "module_hamilt_pw/hamilt_pwdft/global.h" +#include "stress_func.h" + +// calculate the Pulay term of mGGA stress correction in PW +template +void Stress_Func::stress_mgga(ModuleBase::matrix& sigma, + const ModuleBase::matrix& wg, + const ModuleBase::matrix& v_ofk, + const Charge* const chr, + K_Vectors* p_kv, + ModulePW::PW_Basis_K* wfc_basis, + const psi::Psi>* psi_in) +{ + ModuleBase::timer::tick("Stress_Func", "stress_mgga"); + + if (GlobalV::NSPIN == 4) + ModuleBase::WARNING_QUIT("stress_mgga", "noncollinear stress + mGGA not implemented"); + + int current_spin = 0; + const int nrxx = wfc_basis->nrxx; + + std::complex* psi; + int ipol2xy[3][3]; + FPTYPE sigma_mgga[3][3]; + + std::complex* gradwfc = new std::complex[nrxx * 3]; + ModuleBase::GlobalFunc::ZEROS(gradwfc, nrxx * 3); + + FPTYPE** crosstaus = new FPTYPE*[GlobalV::NSPIN]; + for (int is = 0; is < GlobalV::NSPIN; ++is) + { + crosstaus[is] = new FPTYPE[nrxx * 6]; + ModuleBase::GlobalFunc::ZEROS(crosstaus[is], 6*nrxx); + } + + for (int ik = 0; ik < p_kv->nks; ik++) + { + if (GlobalV::NSPIN == 2) + current_spin = p_kv->isk[ik]; + const int npw = p_kv->ngk[ik]; + psi = new complex[npw]; + + for (int ibnd = 0; ibnd < GlobalV::NBANDS; ibnd++) + { + const FPTYPE w1 = wg(ik, ibnd) / GlobalC::ucell.omega; + const std::complex* ppsi = nullptr; + ppsi = &(psi_in[0](ik, ibnd, 0)); + for (int ig = 0; ig < npw; ig++) + { + psi[ig] = ppsi[ig]; + } + XC_Functional::grad_wfc(psi, ik, gradwfc, wfc_basis, GlobalC::ucell.tpiba); + + int ipol = 0; + for (int ix = 0; ix < 3; ix++) + { + for (int iy = 0; iy < ix + 1; iy++) + { + ipol2xy[ix][iy] = ipol; + ipol2xy[iy][ix] = ipol; + for (int ir = 0; ir < nrxx; ir++) + { + crosstaus[current_spin][ipol*nrxx + ir] += 2.0 * w1 + * (gradwfc[ix*nrxx + ir].real() * gradwfc[iy*nrxx + ir].real() + + gradwfc[ix*nrxx + ir].imag() * gradwfc[iy*nrxx + ir].imag()); + } + ipol += 1; + } + } + } // band loop + delete[] psi; + } // k loop + +#ifdef __MPI + for (int is = 0; is < GlobalV::NSPIN; ++is) + { + for (int ipol = 0; ipol < 6; ++ipol) + { + chr->reduce_diff_pools(crosstaus[is] + ipol * nrxx); + } + } +#endif + + delete[] gradwfc; + + for (int is = 0; is < GlobalV::NSPIN; is++) + { + for (int ix = 0; ix < 3; ix++) + { + for (int iy = 0; iy < 3; iy++) + { + FPTYPE delta = 0.0; + if (ix == iy) + delta = 1.0; + sigma_mgga[ix][iy] = 0.0; + for (int ir = 0; ir < nrxx; ir++) + { + FPTYPE x + = v_ofk(is, ir) * (chr->kin_r[is][ir] * delta + crosstaus[is][ipol2xy[ix][iy] * nrxx + ir]); + sigma_mgga[ix][iy] += x; + } + } + } + } + + for (int is = 0; is < GlobalV::NSPIN; is++) + { + delete[] crosstaus[is]; + } + delete[] crosstaus; + +#ifdef __MPI + for (int l = 0; l < 3; l++) + { + for (int m = 0; m < 3; m++) + { + Parallel_Reduce::reduce_pool(sigma_mgga[l][m]); + } + } +#endif + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + sigma(i, j) += sigma_mgga[i][j] / wfc_basis->nxyz; + } + } + ModuleBase::timer::tick("Stress_Func", "stress_mgga"); + return; +} + +template class Stress_Func; +#if ((defined __CUDA) || (defined __ROCM)) +template class Stress_Func; #endif \ No newline at end of file diff --git a/source/module_hamilt_pw/hamilt_pwdft/stress_func_nl.cpp b/source/module_hamilt_pw/hamilt_pwdft/stress_func_nl.cpp index 72db2f6f90d..cb0cfa1c0f4 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/stress_func_nl.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/stress_func_nl.cpp @@ -159,13 +159,13 @@ void Stress_Func::stress_nl(ModuleBase::matrix &sigma, std::complex *h_becp = nullptr; resmem_complex_h_op()(this->cpu_ctx, h_becp, GlobalV::NBANDS * nkb); syncmem_complex_d2h_op()(this->cpu_ctx, this->ctx, h_becp, becp, GlobalV::NBANDS * nkb); - Parallel_Reduce::reduce_complex_double_pool(h_becp, GlobalV::NBANDS * nkb); + Parallel_Reduce::reduce_pool(h_becp, GlobalV::NBANDS * nkb); syncmem_complex_h2d_op()(this->ctx, this->cpu_ctx, becp, h_becp, GlobalV::NBANDS * nkb); delmem_complex_h_op()(this->cpu_ctx, h_becp); } else { - Parallel_Reduce::reduce_complex_double_pool(becp, GlobalV::NBANDS * nkb); + Parallel_Reduce::reduce_pool(becp, GlobalV::NBANDS * nkb); } for (int i = 0; i < 3; i++) { @@ -268,11 +268,11 @@ void Stress_Func::stress_nl(ModuleBase::matrix &sigma, { sigmanlc[l * 3 + m] = sigmanlc[m * 3 + l]; } - Parallel_Reduce::reduce_double_all( sigmanlc[l * 3 + m] ); //qianrui fix a bug for kpar > 1 + Parallel_Reduce::reduce_all(sigmanlc[l * 3 + m]); //qianrui fix a bug for kpar > 1 } } -// Parallel_Reduce::reduce_double_all(sigmanl.c, sigmanl.nr * sigmanl.nc); + // Parallel_Reduce::reduce_all(sigmanl.c, sigmanl.nr * sigmanl.nc); for (int ipol = 0; ipol<3; ipol++) { diff --git a/source/module_hamilt_pw/hamilt_pwdft/wavefunc.cpp b/source/module_hamilt_pw/hamilt_pwdft/wavefunc.cpp index 819343629df..288e098417c 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/wavefunc.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/wavefunc.cpp @@ -467,7 +467,7 @@ void diago_PAO_in_pw_k2(const psi::DEVICE_GPU *ctx, { assert(nbands <= wfcatom.nr); // replace by haozhihan 2022-11-23 - hsolver::matrixSetToAnother()( + hsolver::matrixSetToAnother, psi::DEVICE_GPU>()( gpu_ctx, nbands, c_wfcatom, @@ -560,7 +560,7 @@ void diago_PAO_in_pw_k2(const psi::DEVICE_GPU *ctx, { assert(nbands <= wfcatom.nr); // replace by haozhihan 2022-11-23 - hsolver::matrixSetToAnother()( + hsolver::matrixSetToAnother, psi::DEVICE_GPU>()( gpu_ctx, nbands, z_wfcatom, diff --git a/source/module_hamilt_pw/hamilt_stodft/sto_forces.cpp b/source/module_hamilt_pw/hamilt_stodft/sto_forces.cpp index b99de773630..295db9c79fa 100644 --- a/source/module_hamilt_pw/hamilt_stodft/sto_forces.cpp +++ b/source/module_hamilt_pw/hamilt_stodft/sto_forces.cpp @@ -221,7 +221,7 @@ void Sto_Forces::cal_sto_force_nl(ModuleBase::matrix& forcenl, stowf.shchi[ik].c,&npwx, &ModuleBase::ZERO,&becp(nksbands,0),&nkb); - Parallel_Reduce::reduce_complex_double_pool( becp.c, becp.size); + Parallel_Reduce::reduce_pool(becp.c, becp.size); //out.printcm_real("becp",becp,1.0e-4); // Calculate the derivative of beta, @@ -328,7 +328,7 @@ void Sto_Forces::cal_sto_force_nl(ModuleBase::matrix& forcenl, }// end ik // sum up forcenl from all processors - Parallel_Reduce::reduce_double_all(forcenl.c, forcenl.nr * forcenl.nc); + Parallel_Reduce::reduce_all(forcenl.c, forcenl.nr* forcenl.nc); ModuleBase::timer::tick("Sto_Forces","cal_force_nl"); return; diff --git a/source/module_hamilt_pw/hamilt_stodft/sto_hchi.cpp b/source/module_hamilt_pw/hamilt_stodft/sto_hchi.cpp index aac7fb11607..1bb37dedab9 100644 --- a/source/module_hamilt_pw/hamilt_stodft/sto_hchi.cpp +++ b/source/module_hamilt_pw/hamilt_stodft/sto_hchi.cpp @@ -104,7 +104,7 @@ void Stochastic_hchi:: hchi(complex *chig, complex *hchig, const { zgemm_(&transc,&transn,&nkb,&npm,&npw,&ModuleBase::ONE,GlobalC::ppcell.vkb.c,&npwx,chig,&npwx,&ModuleBase::ZERO,becp,&nkb); } - Parallel_Reduce::reduce_complex_double_pool( becp, nkb * GlobalV::NPOL * m); + Parallel_Reduce::reduce_pool(becp, nkb * GlobalV::NPOL * m); complex *Ps = new complex [nkb * GlobalV::NPOL * m]; ModuleBase::GlobalFunc::ZEROS( Ps, GlobalV::NPOL * m * nkb); diff --git a/source/module_hamilt_pw/hamilt_stodft/sto_iter.cpp b/source/module_hamilt_pw/hamilt_stodft/sto_iter.cpp index 4817e55f23b..8aeea5e1748 100644 --- a/source/module_hamilt_pw/hamilt_stodft/sto_iter.cpp +++ b/source/module_hamilt_pw/hamilt_stodft/sto_iter.cpp @@ -97,7 +97,7 @@ void Stochastic_Iter::orthog(const int& ik, psi::Psi>& psi, //sum(b zgemm_(&transC, &transN, &GlobalV::NBANDS, &nchipk, &npw, &ModuleBase::ONE, &psi(ik,0,0), &npwx, wfgout, &npwx, &ModuleBase::ZERO, sum, &GlobalV::NBANDS); - Parallel_Reduce::reduce_complex_double_pool(sum, GlobalV::NBANDS * nchipk); + Parallel_Reduce::reduce_pool(sum, GlobalV::NBANDS * nchipk); //psi -= psi * sum zgemm_(&transN, &transN, &npw, &nchipk, &GlobalV::NBANDS, &ModuleBase::NEG_ONE, diff --git a/source/module_hamilt_pw/hamilt_stodft/sto_stress_pw.cpp b/source/module_hamilt_pw/hamilt_stodft/sto_stress_pw.cpp index 964cc4af64f..e5ef71682a1 100644 --- a/source/module_hamilt_pw/hamilt_stodft/sto_stress_pw.cpp +++ b/source/module_hamilt_pw/hamilt_stodft/sto_stress_pw.cpp @@ -1,439 +1,439 @@ -#include "sto_stress_pw.h" - -#include "module_base/timer.h" -#include "module_hamilt_pw/hamilt_pwdft/global.h" -#include "module_hamilt_pw/hamilt_pwdft/structure_factor.h" - -void Sto_Stress_PW::cal_stress(ModuleBase::matrix& sigmatot, - const elecstate::ElecState& elec, - ModulePW::PW_Basis* rho_basis, - ModuleSymmetry::Symmetry* p_symm, - Structure_Factor* p_sf, - K_Vectors* p_kv, - ModulePW::PW_Basis_K* wfc_basis, - const psi::Psi>* psi_in, - Stochastic_WF& stowf, - const Charge* const chr) -{ - ModuleBase::TITLE("Sto_Stress_PW", "cal_stress"); - ModuleBase::timer::tick("Sto_Stress_PW", "cal_stress"); - const ModuleBase::matrix& wg = elec.wg; - sigmatot.create(3, 3); - ModuleBase::matrix sigmaxc(3, 3); - ModuleBase::matrix sigmahar(3, 3); - ModuleBase::matrix sigmakin(3, 3); - ModuleBase::matrix sigmaloc(3,3); - ModuleBase::matrix sigmanl(3,3); - ModuleBase::matrix sigmaewa(3,3); - ModuleBase::matrix sigmaxcc(3,3); - - //kinetic contribution - sto_stress_kin(sigmakin, wg, p_symm, p_kv, wfc_basis, psi_in, stowf); - - // hartree contribution - stress_har(sigmahar, rho_basis, 1, chr); - - // ewald contribution - stress_ewa(sigmaewa, rho_basis, 1); - - // xc contribution: add gradient corrections(non diagonal) - for (int i = 0; i < 3; ++i) - { - sigmaxc(i, i) = -(elec.f_en.etxc - elec.f_en.vtxc) / GlobalC::ucell.omega; - } - stress_gga(sigmaxc, rho_basis, chr); - - // local contribution - stress_loc(sigmaloc, rho_basis, p_sf, 1, chr); - - // nlcc - stress_cc(sigmaxcc, rho_basis, p_sf, 1, chr); - - // nonlocal - sto_stress_nl(sigmanl, wg, p_sf, p_symm, p_kv, wfc_basis, psi_in, stowf); - - for(int ipol=0;ipol<3;++ipol) - { - for(int jpol=0;jpol<3;++jpol) - { - sigmatot(ipol,jpol) = sigmakin(ipol,jpol) - + sigmahar(ipol,jpol) - + sigmanl(ipol,jpol) - + sigmaxc(ipol,jpol) - + sigmaxcc(ipol,jpol) - + sigmaewa(ipol,jpol) - + sigmaloc(ipol,jpol); - } - } - - if(ModuleSymmetry::Symmetry::symm_flag == 1) - { - p_symm->symmetrize_mat3(sigmatot, GlobalC::ucell); - } - - bool ry = false; - this->printstress_total(sigmatot, ry); - - if(GlobalV::TEST_STRESS) - { - GlobalV::ofs_running << "\n PARTS OF STRESS: " << std::endl; - GlobalV::ofs_running << setiosflags(std::ios::showpos); - GlobalV::ofs_running << setiosflags(std::ios::fixed) << std::setprecision(10) << std::endl; - this->print_stress("KINETIC STRESS",sigmakin,GlobalV::TEST_STRESS,ry); - this->print_stress("LOCAL STRESS",sigmaloc,GlobalV::TEST_STRESS,ry); - this->print_stress("HARTREE STRESS",sigmahar,GlobalV::TEST_STRESS,ry); - this->print_stress("NON-LOCAL STRESS",sigmanl,GlobalV::TEST_STRESS,ry); - this->print_stress("XC STRESS",sigmaxc,GlobalV::TEST_STRESS,ry); - this->print_stress("EWALD STRESS",sigmaewa,GlobalV::TEST_STRESS,ry); - this->print_stress("NLCC STRESS",sigmaxcc,GlobalV::TEST_STRESS,ry); - this->print_stress("TOTAL STRESS",sigmatot,GlobalV::TEST_STRESS,ry); - } - ModuleBase::timer::tick("Sto_Stress_PW","cal_stress"); - return; -} - -void Sto_Stress_PW::sto_stress_kin(ModuleBase::matrix& sigma, - const ModuleBase::matrix& wg, - ModuleSymmetry::Symmetry* p_symm, - K_Vectors* p_kv, - ModulePW::PW_Basis_K* wfc_basis, - const psi::Psi>* psi_in, - Stochastic_WF& stowf) -{ - ModuleBase::TITLE("Sto_Stress_PW","cal_stress"); - ModuleBase::timer::tick("Sto_Stress_PW","cal_stress"); - double **gk; - gk=new double* [3]; - ModuleBase::matrix s_kin(3,3,true); - - - const int npwx = wfc_basis->npwk_max; - const int nks = wfc_basis->nks; - gk[0]= new double[npwx]; - gk[1]= new double[npwx]; - gk[2]= new double[npwx]; - double tpiba = ModuleBase::TWO_PI / GlobalC::ucell.lat0; - double twobysqrtpi = 2.0 / std::sqrt(ModuleBase::PI); - double* kfac = new double[npwx]; - int nksbands = psi_in->get_nbands(); - if (GlobalV::MY_STOGROUP != 0) - nksbands = 0; - - for (int ik = 0; ik < nks; ++ik) - { - const int nstobands = stowf.nchip[ik]; - const int nbandstot = nstobands + nksbands; - const int npw = wfc_basis->npwk[ik]; - for (int i = 0; i < npw; ++i) - { - gk[0][i] = wfc_basis->getgpluskcar(ik, i)[0] * tpiba; - gk[1][i] = wfc_basis->getgpluskcar(ik, i)[1] * tpiba; - gk[2][i] = wfc_basis->getgpluskcar(ik, i)[2] * tpiba; - if (wfc_basis->erf_height > 0) - { - double gk2 = gk[0][i] * gk[0][i] + gk[1][i] * gk[1][i] + gk[2][i] * gk[2][i]; - double arg = (gk2 - wfc_basis->erf_ecut) / wfc_basis->erf_sigma; - kfac[i] = 1.0 + wfc_basis->erf_height / wfc_basis->erf_sigma * twobysqrtpi * std::exp(-arg * arg); - } - else - { - kfac[i] = 1.0; - } - } - - // kinetic contribution - - for (int l = 0; l < 3; ++l) - { - for (int m = 0; m < l + 1; ++m) - { - for (int ibnd = 0; ibnd < nbandstot; ++ibnd) - { - if (ibnd < nksbands) - { - for (int i = 0; i < npw; ++i) - { - std::complex p = psi_in->operator()(ik, ibnd, i); - double np = p.real() * p.real() + p.imag() * p.imag(); - s_kin(l, m) += wg(ik, ibnd) * gk[l][i] * gk[m][i] * kfac[i] * np; - } - } - else - { - for (int i = 0; i < npw; ++i) - { - std::complex p = stowf.shchi[ik](ibnd - nksbands, i); - double np = p.real() * p.real() + p.imag() * p.imag(); - s_kin(l, m) += p_kv->wk[ik] * gk[l][i] * gk[m][i] * kfac[i] * np; - } - } - } - } - } - } - - for(int l=0;l<3;++l) - { - for(int m=0;msymmetrize_mat3(sigma, GlobalC::ucell); - } - delete[] gk[0]; - delete[] gk[1]; - delete[] gk[2]; - delete[] gk; - ModuleBase::timer::tick("Sto_Stress_PW","cal_stress"); - - return; -} - -void Sto_Stress_PW::sto_stress_nl(ModuleBase::matrix& sigma, - const ModuleBase::matrix& wg, - Structure_Factor* p_sf, - ModuleSymmetry::Symmetry* p_symm, - K_Vectors* p_kv, - ModulePW::PW_Basis_K* wfc_basis, - const psi::Psi>* psi_in, - Stochastic_WF& stowf) -{ - ModuleBase::TITLE("Sto_Stress_Func","stres_nl"); - ModuleBase::timer::tick("Sto_Stress_Func","stres_nl"); - - const int nkb = GlobalC::ppcell.nkb; - if(nkb == 0) - { - ModuleBase::timer::tick("Stress_Func","stres_nl"); - return; - } - - ModuleBase::matrix sigmanlc(3,3,true); - int* nchip = stowf.nchip; - const int npwx = wfc_basis->npwk_max; - int nksbands = psi_in->get_nbands(); - if(GlobalV::MY_STOGROUP != 0) nksbands = 0; - - - // vkb1: |Beta(nkb,npw)> - ModuleBase::ComplexMatrix vkb1( nkb, npwx ); - ModuleBase::ComplexMatrix vkb0[3]; - for(int i=0;i<3;++i){ - vkb0[i].create(nkb, npwx); - } - ModuleBase::ComplexMatrix vkb2( nkb, npwx ); - - for (int ik = 0; ik < p_kv->nks; ik++) - { - const int nstobands = stowf.nchip[ik]; - const int nbandstot = nstobands + nksbands; - const int npw = p_kv->ngk[ik]; - // dbecp: conj( -iG * ) - ModuleBase::ComplexMatrix dbecp(nbandstot, nkb); - ModuleBase::ComplexMatrix becp(nbandstot, nkb); - - if (GlobalV::NSPIN == 2) - GlobalV::CURRENT_SPIN = p_kv->isk[ik]; - // generate vkb - if (GlobalC::ppcell.nkb > 0) - { - GlobalC::ppcell.getvnl(ik, GlobalC::ppcell.vkb); - } - - // get becp according to wave functions and vkb - // important here ! becp must set zero!! - // vkb: Beta(nkb,npw) - // becp(nkb,nbnd): - becp.zero_out(); - char transa = 'C'; - char transb = 'N'; - psi_in[0].fix_k(ik); - //KS orbitals - int npmks = GlobalV::NPOL * nksbands; - zgemm_(&transa,&transb,&nkb,&npmks,&npw,&ModuleBase::ONE, - GlobalC::ppcell.vkb.c,&npwx, - psi_in->get_pointer(),&npwx, - &ModuleBase::ZERO,becp.c,&nkb); - //stochastic orbitals - int npmsto = GlobalV::NPOL * nstobands; - zgemm_(&transa,&transb,&nkb,&npmsto,&npw,&ModuleBase::ONE, - GlobalC::ppcell.vkb.c,&npwx, - stowf.shchi[ik].c,&npwx, - &ModuleBase::ZERO,&becp(nksbands,0),&nkb); - - Parallel_Reduce::reduce_complex_double_pool( becp.c, becp.size); - - for (int i = 0; i < 3; ++i) - { - get_dvnl1(vkb0[i], ik, i, p_sf, wfc_basis); - } - - get_dvnl2(vkb2, ik, p_sf, wfc_basis); - - ModuleBase::Vector3 qvec; - double* qvec0[3]; - qvec0[0] = &(qvec.x); - qvec0[1] = &(qvec.y); - qvec0[2] = &(qvec.z); - - for (int ipol = 0; ipol < 3; ++ipol) - { - for (int jpol = 0; jpol < ipol + 1; ++jpol) - { - dbecp.zero_out(); - vkb1.zero_out(); - for (int i = 0;i < nkb;++i) - { - std::complex* pvkb0i = &vkb0[ipol](i, 0); - std::complex* pvkb0j = &vkb0[jpol](i, 0); - std::complex* pvkb1 = &vkb1(i, 0); - // third term of dbecp_noevc - for (int ig = 0; ig < npw; ++ig) - { - qvec = wfc_basis->getgpluskcar(ik, ig); - pvkb1[ig] += 0.5 * qvec0[ipol][0] * pvkb0j[ig] + - 0.5 * qvec0[jpol][0] * pvkb0i[ig]; - } // end ig - }//end nkb - - - ModuleBase::ComplexMatrix dbecp_noevc(nkb, npwx, true); - for (int i = 0; i < nkb; ++i) - { - std::complex* pdbecp_noevc = &dbecp_noevc(i, 0); - std::complex* pvkb = &vkb1(i, 0); - // first term - for (int ig = 0; ig < npw;++ig) - { - pdbecp_noevc[ig] -= 2.0 * pvkb[ig]; - } - // second termi - if (ipol == jpol) - { - pvkb = &GlobalC::ppcell.vkb(i, 0); - for (int ig = 0; ig < npw;++ig) - { - pdbecp_noevc[ig] -= pvkb[ig]; - } - } - // third term - pvkb = &vkb2(i,0); - for (int ig = 0; ig < npw;++ig) - { - qvec = wfc_basis->getgpluskcar(ik, ig); - double qm1; - if(qvec.norm2() > 1e-16) qm1 = 1.0 / qvec.norm(); - else qm1 = 0; - pdbecp_noevc[ig] -= 2.0 * pvkb[ig] * qvec0[ipol][0] * - qvec0[jpol][0] * qm1 * GlobalC::ucell.tpiba; - } // end ig - } // end i - -// //KS orbitals - zgemm_(&transa,&transb,&nkb,&npmks,&npw,&ModuleBase::ONE, - dbecp_noevc.c,&npwx, - psi_in->get_pointer(),&npwx, - &ModuleBase::ZERO,dbecp.c,&nkb); - //stochastic orbitals - zgemm_(&transa,&transb,&nkb,&npmsto,&npw,&ModuleBase::ONE, - dbecp_noevc.c,&npwx, - stowf.shchi[ik].c,&npwx, - &ModuleBase::ZERO,&dbecp(nksbands, 0),&nkb); - - for (int ib=0; ibwk[ik]; - int iat = 0; - int sum = 0; - for (int it=0; it>* psi_in, + Stochastic_WF& stowf, + const Charge* const chr) +{ + ModuleBase::TITLE("Sto_Stress_PW", "cal_stress"); + ModuleBase::timer::tick("Sto_Stress_PW", "cal_stress"); + const ModuleBase::matrix& wg = elec.wg; + sigmatot.create(3, 3); + ModuleBase::matrix sigmaxc(3, 3); + ModuleBase::matrix sigmahar(3, 3); + ModuleBase::matrix sigmakin(3, 3); + ModuleBase::matrix sigmaloc(3,3); + ModuleBase::matrix sigmanl(3,3); + ModuleBase::matrix sigmaewa(3,3); + ModuleBase::matrix sigmaxcc(3,3); + + //kinetic contribution + sto_stress_kin(sigmakin, wg, p_symm, p_kv, wfc_basis, psi_in, stowf); + + // hartree contribution + stress_har(sigmahar, rho_basis, 1, chr); + + // ewald contribution + stress_ewa(sigmaewa, rho_basis, 1); + + // xc contribution: add gradient corrections(non diagonal) + for (int i = 0; i < 3; ++i) + { + sigmaxc(i, i) = -(elec.f_en.etxc - elec.f_en.vtxc) / GlobalC::ucell.omega; + } + stress_gga(sigmaxc, rho_basis, chr); + + // local contribution + stress_loc(sigmaloc, rho_basis, p_sf, 1, chr); + + // nlcc + stress_cc(sigmaxcc, rho_basis, p_sf, 1, chr); + + // nonlocal + sto_stress_nl(sigmanl, wg, p_sf, p_symm, p_kv, wfc_basis, psi_in, stowf); + + for(int ipol=0;ipol<3;++ipol) + { + for(int jpol=0;jpol<3;++jpol) + { + sigmatot(ipol,jpol) = sigmakin(ipol,jpol) + + sigmahar(ipol,jpol) + + sigmanl(ipol,jpol) + + sigmaxc(ipol,jpol) + + sigmaxcc(ipol,jpol) + + sigmaewa(ipol,jpol) + + sigmaloc(ipol,jpol); + } + } + + if(ModuleSymmetry::Symmetry::symm_flag == 1) + { + p_symm->symmetrize_mat3(sigmatot, GlobalC::ucell); + } + + bool ry = false; + this->printstress_total(sigmatot, ry); + + if(GlobalV::TEST_STRESS) + { + GlobalV::ofs_running << "\n PARTS OF STRESS: " << std::endl; + GlobalV::ofs_running << setiosflags(std::ios::showpos); + GlobalV::ofs_running << setiosflags(std::ios::fixed) << std::setprecision(10) << std::endl; + this->print_stress("KINETIC STRESS",sigmakin,GlobalV::TEST_STRESS,ry); + this->print_stress("LOCAL STRESS",sigmaloc,GlobalV::TEST_STRESS,ry); + this->print_stress("HARTREE STRESS",sigmahar,GlobalV::TEST_STRESS,ry); + this->print_stress("NON-LOCAL STRESS",sigmanl,GlobalV::TEST_STRESS,ry); + this->print_stress("XC STRESS",sigmaxc,GlobalV::TEST_STRESS,ry); + this->print_stress("EWALD STRESS",sigmaewa,GlobalV::TEST_STRESS,ry); + this->print_stress("NLCC STRESS",sigmaxcc,GlobalV::TEST_STRESS,ry); + this->print_stress("TOTAL STRESS",sigmatot,GlobalV::TEST_STRESS,ry); + } + ModuleBase::timer::tick("Sto_Stress_PW","cal_stress"); + return; +} + +void Sto_Stress_PW::sto_stress_kin(ModuleBase::matrix& sigma, + const ModuleBase::matrix& wg, + ModuleSymmetry::Symmetry* p_symm, + K_Vectors* p_kv, + ModulePW::PW_Basis_K* wfc_basis, + const psi::Psi>* psi_in, + Stochastic_WF& stowf) +{ + ModuleBase::TITLE("Sto_Stress_PW","cal_stress"); + ModuleBase::timer::tick("Sto_Stress_PW","cal_stress"); + double **gk; + gk=new double* [3]; + ModuleBase::matrix s_kin(3,3,true); + + + const int npwx = wfc_basis->npwk_max; + const int nks = wfc_basis->nks; + gk[0]= new double[npwx]; + gk[1]= new double[npwx]; + gk[2]= new double[npwx]; + double tpiba = ModuleBase::TWO_PI / GlobalC::ucell.lat0; + double twobysqrtpi = 2.0 / std::sqrt(ModuleBase::PI); + double* kfac = new double[npwx]; + int nksbands = psi_in->get_nbands(); + if (GlobalV::MY_STOGROUP != 0) + nksbands = 0; + + for (int ik = 0; ik < nks; ++ik) + { + const int nstobands = stowf.nchip[ik]; + const int nbandstot = nstobands + nksbands; + const int npw = wfc_basis->npwk[ik]; + for (int i = 0; i < npw; ++i) + { + gk[0][i] = wfc_basis->getgpluskcar(ik, i)[0] * tpiba; + gk[1][i] = wfc_basis->getgpluskcar(ik, i)[1] * tpiba; + gk[2][i] = wfc_basis->getgpluskcar(ik, i)[2] * tpiba; + if (wfc_basis->erf_height > 0) + { + double gk2 = gk[0][i] * gk[0][i] + gk[1][i] * gk[1][i] + gk[2][i] * gk[2][i]; + double arg = (gk2 - wfc_basis->erf_ecut) / wfc_basis->erf_sigma; + kfac[i] = 1.0 + wfc_basis->erf_height / wfc_basis->erf_sigma * twobysqrtpi * std::exp(-arg * arg); + } + else + { + kfac[i] = 1.0; + } + } + + // kinetic contribution + + for (int l = 0; l < 3; ++l) + { + for (int m = 0; m < l + 1; ++m) + { + for (int ibnd = 0; ibnd < nbandstot; ++ibnd) + { + if (ibnd < nksbands) + { + for (int i = 0; i < npw; ++i) + { + std::complex p = psi_in->operator()(ik, ibnd, i); + double np = p.real() * p.real() + p.imag() * p.imag(); + s_kin(l, m) += wg(ik, ibnd) * gk[l][i] * gk[m][i] * kfac[i] * np; + } + } + else + { + for (int i = 0; i < npw; ++i) + { + std::complex p = stowf.shchi[ik](ibnd - nksbands, i); + double np = p.real() * p.real() + p.imag() * p.imag(); + s_kin(l, m) += p_kv->wk[ik] * gk[l][i] * gk[m][i] * kfac[i] * np; + } + } + } + } + } + } + + for(int l=0;l<3;++l) + { + for(int m=0;msymmetrize_mat3(sigma, GlobalC::ucell); - } - - // this->print(ofs_running, "nonlocal stress", stresnl); - ModuleBase::timer::tick("Sto_Stress_Func","stres_nl"); - return; -} + } + delete[] gk[0]; + delete[] gk[1]; + delete[] gk[2]; + delete[] gk; + ModuleBase::timer::tick("Sto_Stress_PW","cal_stress"); + + return; +} + +void Sto_Stress_PW::sto_stress_nl(ModuleBase::matrix& sigma, + const ModuleBase::matrix& wg, + Structure_Factor* p_sf, + ModuleSymmetry::Symmetry* p_symm, + K_Vectors* p_kv, + ModulePW::PW_Basis_K* wfc_basis, + const psi::Psi>* psi_in, + Stochastic_WF& stowf) +{ + ModuleBase::TITLE("Sto_Stress_Func","stres_nl"); + ModuleBase::timer::tick("Sto_Stress_Func","stres_nl"); + + const int nkb = GlobalC::ppcell.nkb; + if(nkb == 0) + { + ModuleBase::timer::tick("Stress_Func","stres_nl"); + return; + } + + ModuleBase::matrix sigmanlc(3,3,true); + int* nchip = stowf.nchip; + const int npwx = wfc_basis->npwk_max; + int nksbands = psi_in->get_nbands(); + if(GlobalV::MY_STOGROUP != 0) nksbands = 0; + + + // vkb1: |Beta(nkb,npw)> + ModuleBase::ComplexMatrix vkb1( nkb, npwx ); + ModuleBase::ComplexMatrix vkb0[3]; + for(int i=0;i<3;++i){ + vkb0[i].create(nkb, npwx); + } + ModuleBase::ComplexMatrix vkb2( nkb, npwx ); + + for (int ik = 0; ik < p_kv->nks; ik++) + { + const int nstobands = stowf.nchip[ik]; + const int nbandstot = nstobands + nksbands; + const int npw = p_kv->ngk[ik]; + // dbecp: conj( -iG * ) + ModuleBase::ComplexMatrix dbecp(nbandstot, nkb); + ModuleBase::ComplexMatrix becp(nbandstot, nkb); + + if (GlobalV::NSPIN == 2) + GlobalV::CURRENT_SPIN = p_kv->isk[ik]; + // generate vkb + if (GlobalC::ppcell.nkb > 0) + { + GlobalC::ppcell.getvnl(ik, GlobalC::ppcell.vkb); + } + + // get becp according to wave functions and vkb + // important here ! becp must set zero!! + // vkb: Beta(nkb,npw) + // becp(nkb,nbnd): + becp.zero_out(); + char transa = 'C'; + char transb = 'N'; + psi_in[0].fix_k(ik); + //KS orbitals + int npmks = GlobalV::NPOL * nksbands; + zgemm_(&transa,&transb,&nkb,&npmks,&npw,&ModuleBase::ONE, + GlobalC::ppcell.vkb.c,&npwx, + psi_in->get_pointer(),&npwx, + &ModuleBase::ZERO,becp.c,&nkb); + //stochastic orbitals + int npmsto = GlobalV::NPOL * nstobands; + zgemm_(&transa,&transb,&nkb,&npmsto,&npw,&ModuleBase::ONE, + GlobalC::ppcell.vkb.c,&npwx, + stowf.shchi[ik].c,&npwx, + &ModuleBase::ZERO,&becp(nksbands,0),&nkb); + + Parallel_Reduce::reduce_pool( becp.c, becp.size); + + for (int i = 0; i < 3; ++i) + { + get_dvnl1(vkb0[i], ik, i, p_sf, wfc_basis); + } + + get_dvnl2(vkb2, ik, p_sf, wfc_basis); + + ModuleBase::Vector3 qvec; + double* qvec0[3]; + qvec0[0] = &(qvec.x); + qvec0[1] = &(qvec.y); + qvec0[2] = &(qvec.z); + + for (int ipol = 0; ipol < 3; ++ipol) + { + for (int jpol = 0; jpol < ipol + 1; ++jpol) + { + dbecp.zero_out(); + vkb1.zero_out(); + for (int i = 0;i < nkb;++i) + { + std::complex* pvkb0i = &vkb0[ipol](i, 0); + std::complex* pvkb0j = &vkb0[jpol](i, 0); + std::complex* pvkb1 = &vkb1(i, 0); + // third term of dbecp_noevc + for (int ig = 0; ig < npw; ++ig) + { + qvec = wfc_basis->getgpluskcar(ik, ig); + pvkb1[ig] += 0.5 * qvec0[ipol][0] * pvkb0j[ig] + + 0.5 * qvec0[jpol][0] * pvkb0i[ig]; + } // end ig + }//end nkb + + + ModuleBase::ComplexMatrix dbecp_noevc(nkb, npwx, true); + for (int i = 0; i < nkb; ++i) + { + std::complex* pdbecp_noevc = &dbecp_noevc(i, 0); + std::complex* pvkb = &vkb1(i, 0); + // first term + for (int ig = 0; ig < npw;++ig) + { + pdbecp_noevc[ig] -= 2.0 * pvkb[ig]; + } + // second termi + if (ipol == jpol) + { + pvkb = &GlobalC::ppcell.vkb(i, 0); + for (int ig = 0; ig < npw;++ig) + { + pdbecp_noevc[ig] -= pvkb[ig]; + } + } + // third term + pvkb = &vkb2(i,0); + for (int ig = 0; ig < npw;++ig) + { + qvec = wfc_basis->getgpluskcar(ik, ig); + double qm1; + if(qvec.norm2() > 1e-16) qm1 = 1.0 / qvec.norm(); + else qm1 = 0; + pdbecp_noevc[ig] -= 2.0 * pvkb[ig] * qvec0[ipol][0] * + qvec0[jpol][0] * qm1 * GlobalC::ucell.tpiba; + } // end ig + } // end i + +// //KS orbitals + zgemm_(&transa,&transb,&nkb,&npmks,&npw,&ModuleBase::ONE, + dbecp_noevc.c,&npwx, + psi_in->get_pointer(),&npwx, + &ModuleBase::ZERO,dbecp.c,&nkb); + //stochastic orbitals + zgemm_(&transa,&transb,&nkb,&npmsto,&npw,&ModuleBase::ONE, + dbecp_noevc.c,&npwx, + stowf.shchi[ik].c,&npwx, + &ModuleBase::ZERO,&dbecp(nksbands, 0),&nkb); + + for (int ib=0; ibwk[ik]; + int iat = 0; + int sum = 0; + for (int it=0; it *phm_in, psi::Psi &psi, Real *eigenvalue_in) = 0; - virtual void diag(hamilt::Hamilt *phm_in, psi::Psi &psi, Real *eigenvalue_in) { - return; - } }; } // namespace hsolver diff --git a/source/module_hsolver/diago_blas.cpp b/source/module_hsolver/diago_blas.cpp index 3676fee82d2..1b9183520f9 100644 --- a/source/module_hsolver/diago_blas.cpp +++ b/source/module_hsolver/diago_blas.cpp @@ -20,8 +20,8 @@ typedef hamilt::MatrixBlock> matcd; namespace hsolver { - -void DiagoBlas::diag(hamilt::Hamilt> *phm_in, psi::Psi &psi, double *eigenvalue_in) + template<> + void DiagoBlas::diag(hamilt::Hamilt* phm_in, psi::Psi& psi, Real* eigenvalue_in) { ModuleBase::TITLE("DiagoElpa", "diag"); matd h_mat, s_mat; @@ -32,8 +32,8 @@ void DiagoBlas::diag(hamilt::Hamilt> *phm_in, psi::Psi> *phm_in, psi::Psi> &psi, double *eigenvalue_in) + template<> + void DiagoBlas>::diag(hamilt::Hamilt>* phm_in, psi::Psi>& psi, Real* eigenvalue_in) { ModuleBase::TITLE("DiagoElpa", "diag"); matcd h_mat, s_mat; @@ -45,7 +45,8 @@ void DiagoBlas::diag(hamilt::Hamilt> *phm_in, psi::Psi> DiagoBlas::pdsygvx_once(const int *const desc, + template + std::pair> DiagoBlas::pdsygvx_once(const int* const desc, const int ncol, const int nrow, const double *const h_mat, @@ -167,8 +168,8 @@ std::pair> DiagoBlas::pdsygvx_once(const int *const desc, + ModuleBase::GlobalFunc::TO_STRING(__FILE__) + " line " + ModuleBase::GlobalFunc::TO_STRING(__LINE__)); } - -std::pair> DiagoBlas::pzhegvx_once(const int *const desc, + template + std::pair> DiagoBlas::pzhegvx_once(const int* const desc, const int ncol, const int nrow, const std::complex *const h_mat, @@ -301,8 +302,8 @@ std::pair> DiagoBlas::pzhegvx_once(const int *const desc, + ModuleBase::GlobalFunc::TO_STRING(__FILE__) + " line " + ModuleBase::GlobalFunc::TO_STRING(__LINE__)); } - -void DiagoBlas::pdsygvx_diag(const int *const desc, + template + void DiagoBlas::pdsygvx_diag(const int* const desc, const int ncol, const int nrow, const double *const h_mat, @@ -319,7 +320,8 @@ void DiagoBlas::pdsygvx_diag(const int *const desc, } } -void DiagoBlas::pzhegvx_diag(const int *const desc, + template + void DiagoBlas ::pzhegvx_diag(const int* const desc, const int ncol, const int nrow, const std::complex *const h_mat, @@ -336,7 +338,8 @@ void DiagoBlas::pzhegvx_diag(const int *const desc, } } -void DiagoBlas::post_processing(const int info, const std::vector &vec) + template + void DiagoBlas::post_processing(const int info, const std::vector& vec) { const std::string str_info = "info = " + ModuleBase::GlobalFunc::TO_STRING(info) + ".\n"; const std::string str_FILE diff --git a/source/module_hsolver/diago_blas.h b/source/module_hsolver/diago_blas.h index 8076443902b..b445f0cc126 100644 --- a/source/module_hsolver/diago_blas.h +++ b/source/module_hsolver/diago_blas.h @@ -19,14 +19,13 @@ namespace hsolver { - -class DiagoBlas : public DiagH> + template + class DiagoBlas : public DiagH { - +private: + using Real = typename GetTypeReal::type; public: - void diag(hamilt::Hamilt> *phm_in, psi::Psi &psi, double *eigenvalue_in) override; - - void diag(hamilt::Hamilt> *phm_in, psi::Psi> &psi, double *eigenvalue_in) override; + void diag(hamilt::Hamilt* phm_in, psi::Psi& psi, Real* eigenvalue_in) override; private: void pdsygvx_diag(const int *const desc, diff --git a/source/module_hsolver/diago_cg.cpp b/source/module_hsolver/diago_cg.cpp index 7bf91f363cd..7b0e45810d9 100644 --- a/source/module_hsolver/diago_cg.cpp +++ b/source/module_hsolver/diago_cg.cpp @@ -122,7 +122,7 @@ void DiagoCG::diag_mock(hamilt::Hamilt *phm_in, psi::Psiops->hPsi(cg_hpsi_in); this->eigenvalue[m] = - zdot_real_op()( + dot_real_op()( this->ctx, this->dim, this->phi_m->get_pointer(), @@ -224,19 +224,19 @@ void DiagoCG::calculate_gradient() // denghui replace this at 20221106 // TODO: use GPU precondition to initialize CG class if (this->device == psi::GpuDevice) { - vector_div_vector_op()(this->ctx, this->dim, this->gradient, this->hphi, this->d_precondition); - vector_div_vector_op()(this->ctx, this->dim, this->pphi, this->sphi, this->d_precondition); + vector_div_vector_op()(this->ctx, this->dim, this->gradient, this->hphi, this->d_precondition); + vector_div_vector_op()(this->ctx, this->dim, this->pphi, this->sphi, this->d_precondition); } else { - vector_div_vector_op()(this->ctx, this->dim, this->gradient, this->hphi, this->precondition); - vector_div_vector_op()(this->ctx, this->dim, this->pphi, this->sphi, this->precondition); + vector_div_vector_op()(this->ctx, this->dim, this->gradient, this->hphi, this->precondition); + vector_div_vector_op()(this->ctx, this->dim, this->pphi, this->sphi, this->precondition); } // Update lambda ! // (4) - const Real eh = hsolver::zdot_real_op()(this->ctx, this->dim, this->sphi, this->gradient); + const Real eh = hsolver::dot_real_op()(this->ctx, this->dim, this->sphi, this->gradient); // (5) - const Real es = hsolver::zdot_real_op()(this->ctx, this->dim, this->sphi, this->pphi); + const Real es = hsolver::dot_real_op()(this->ctx, this->dim, this->sphi, this->pphi); const Real lambda = eh / es; // Update g! @@ -265,7 +265,7 @@ void DiagoCG::orthogonal_gradient(hamilt::Hamilt *phm_in, // int inc = 1; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan replace 2022-10-07 - gemv_op()( + gemv_op()( this->ctx, 'C', this->dim, @@ -279,12 +279,12 @@ void DiagoCG::orthogonal_gradient(hamilt::Hamilt *phm_in, this->lagrange, 1); - Parallel_Reduce::reduce_complex_double_pool(this->lagrange, m); + Parallel_Reduce::reduce_pool(this->lagrange, m); // (3) orthogonal |g> and |scg> to all states (0~m-1) //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan replace 2022-10-07 - gemv_op()( + gemv_op()( this->ctx, 'N', this->dim, @@ -298,7 +298,7 @@ void DiagoCG::orthogonal_gradient(hamilt::Hamilt *phm_in, this->gradient, 1); - gemv_op()( + gemv_op()( this->ctx, 'N', this->dim, @@ -328,7 +328,7 @@ void DiagoCG::calculate_gamma_cg(const int iter, Real &gg_last, const // gg_inter = // Attention : the 'g' in g0 is getted last time gg_inter - = hsolver::zdot_real_op()(this->ctx, this->dim, this->gradient, this->g0); // b means before + = hsolver::dot_real_op()(this->ctx, this->dim, this->gradient, this->g0); // b means before } // (2) Update for g0! @@ -343,15 +343,15 @@ void DiagoCG::calculate_gamma_cg(const int iter, Real &gg_last, const // denghui replace this 20221106 // TODO: use GPU precondition instead if (this->device == psi::GpuDevice) { - vector_mul_vector_op()(this->ctx, this->dim, this->g0, this->scg, this->d_precondition); + vector_mul_vector_op()(this->ctx, this->dim, this->g0, this->scg, this->d_precondition); } else { - vector_mul_vector_op()(this->ctx, this->dim, this->g0, this->scg, this->precondition); + vector_mul_vector_op()(this->ctx, this->dim, this->g0, this->scg, this->precondition); } // (3) Update gg_now! // gg_now = < g|P|scg > = < g|g0 > - const Real gg_now = hsolver::zdot_real_op()(this->ctx, this->dim, this->gradient, this->g0); + const Real gg_now = hsolver::dot_real_op()(this->ctx, this->dim, this->gradient, this->g0); if (iter == 0) { @@ -398,7 +398,7 @@ bool DiagoCG::update_psi(Real &cg_norm, Real &theta, Real &eigenvalue { if (test_cg == 1) ModuleBase::TITLE("DiagoCG", "update_psi"); - cg_norm = sqrt(hsolver::zdot_real_op()(this->ctx, this->dim, this->cg->get_pointer(), this->scg)); + cg_norm = sqrt(hsolver::dot_real_op()(this->ctx, this->dim, this->cg->get_pointer(), this->scg)); if (cg_norm < 1.0e-10) return 1; @@ -406,9 +406,9 @@ bool DiagoCG::update_psi(Real &cg_norm, Real &theta, Real &eigenvalue T* phi_m_pointer = this->phi_m->get_pointer(); const Real a0 - = hsolver::zdot_real_op()(this->ctx, this->dim, phi_m_pointer, this->pphi) * 2.0 / cg_norm; + = hsolver::dot_real_op()(this->ctx, this->dim, phi_m_pointer, this->pphi) * 2.0 / cg_norm; const Real b0 - = hsolver::zdot_real_op()(this->ctx, this->dim, this->cg->get_pointer(), this->pphi) / (cg_norm * cg_norm); + = hsolver::dot_real_op()(this->ctx, this->dim, this->cg->get_pointer(), this->pphi) / (cg_norm * cg_norm); const Real e0 = eigenvalue; theta = atan(a0 / (e0 - b0)) / 2.0; @@ -482,7 +482,7 @@ void DiagoCG::schmit_orth( //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan replace 2022-10-6 int inc = 1; - gemv_op()( + gemv_op()( this->ctx, 'C', this->dim, @@ -497,7 +497,7 @@ void DiagoCG::schmit_orth( inc); // be careful , here reduce m+1 - Parallel_Reduce::reduce_complex_double_pool(lagrange_so, m + 1); + Parallel_Reduce::reduce_pool(lagrange_so, m + 1); T var(0, 0); syncmem_complex_d2h_op()(this->cpu_ctx, this->ctx, &var, lagrange_so + m, 1); @@ -505,7 +505,7 @@ void DiagoCG::schmit_orth( //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan replace 2022-10-6 - gemv_op()( + gemv_op()( this->ctx, 'N', this->dim, @@ -529,7 +529,7 @@ void DiagoCG::schmit_orth( psi_norm -= ( conj(lagrange[j]) * lagrange[j] ).real(); }*/ //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - psi_norm -= hsolver::zdot_real_op()(this->ctx, m, lagrange_so, lagrange_so, false); + psi_norm -= hsolver::dot_real_op()(this->ctx, m, lagrange_so, lagrange_so, false); if (psi_norm <= 0.0) { @@ -555,7 +555,7 @@ void DiagoCG::schmit_orth( // { // pphi_m[ig] /= psi_norm; // } - vector_div_constant_op()(this->ctx, this->dim, pphi_m, pphi_m, psi_norm); + vector_div_constant_op()(this->ctx, this->dim, pphi_m, pphi_m, psi_norm); // ModuleBase::timer::tick("DiagoCG","schmit_orth"); delmem_complex_op()(this->ctx, lagrange_so); diff --git a/source/module_hsolver/diago_cg.h b/source/module_hsolver/diago_cg.h index 427b3fdf9cf..36fe4b6fc43 100644 --- a/source/module_hsolver/diago_cg.h +++ b/source/module_hsolver/diago_cg.h @@ -98,7 +98,7 @@ class DiagoCG : public DiagH void diag_mock(hamilt::Hamilt *phm_in, psi::Psi &phi, Real *eigenvalue_in); using hpsi_info = typename hamilt::Operator::hpsi_info; - using zdot_real_op = hsolver::zdot_real_op; + using dot_real_op = hsolver::dot_real_op; using setmem_complex_op = psi::memory::set_memory_op; using delmem_complex_op = psi::memory::delete_memory_op; diff --git a/source/module_hsolver/diago_david.cpp b/source/module_hsolver/diago_david.cpp index dc8f43162ce..820e8a7f81e 100644 --- a/source/module_hsolver/diago_david.cpp +++ b/source/module_hsolver/diago_david.cpp @@ -17,15 +17,51 @@ using namespace hsolver; +template class consts; +template class consts>; +template class consts>; + +template<> consts::consts() +{ + zero = 0.0; + one = 1.0; + neg_one = -1.0; +} +template<> consts>::consts() +{ + zero = std::complex(0.0, 0.0); + one = std::complex(1.0, 0.0); + neg_one = std::complex(-1.0, 0.0); +} +template<> consts>::consts() +{ + zero = std::complex(0.0, 0.0); + one = std::complex(1.0, 0.0); + neg_one = std::complex(-1.0, 0.0); +} + +inline double get_real(const double& x) +{ + return x; +} +inline double get_real(const std::complex& x) +{ + return x.real(); +} +inline float get_real(const std::complex& x) +{ + return x.real(); +} + template DiagoDavid::DiagoDavid(const Real* precondition_in) { this->device = psi::device::get_device_type(this->ctx); this->precondition = precondition_in; test_david = 2; - this->one = new T(1.0, 0.0); - this->zero = new T(0.0, 0.0); - this->neg_one = new T(-1.0, 0.0); + this->one = &this->cs.one; + this->zero = &this->cs.zero; + this->neg_one = &this->cs.neg_one; // 1: check which function is called and which step is executed // 2: check the eigenvalues of the result of each iteration // 3: check the eigenvalues and errors of the last result @@ -44,9 +80,6 @@ template DiagoDavid::~DiagoDavid() if (this->device == psi::GpuDevice) { delmem_var_op()(this->ctx, this->d_precondition); } - delete this->one; - delete this->zero; - delete this->neg_one; } template @@ -65,8 +98,16 @@ void DiagoDavid::diag_mock(hamilt::Hamilt* phm_in, // However, in most cases, total number of plane waves should be much larger than nband*PW_DIAG_NDIM /// initialize variables - this->dim = psi.get_current_nbas(); - this->dmx = psi.get_nbasis(); + /// k_first = 0 means that nks is more like a dimension of "basis" to be contracted in "HPsi".In LR-TDDFT the formula writes : + /// $$\sum_{ jb\mathbf{k}'}A^I_{ia\mathbf{k}, jb\mathbf{k}' }X ^ I_{ jb\mathbf{k}'}$$ + /// In the code : + /// - "H" means A + /// - "Psi" means X + /// - "band" means the superscript I : the number of excited states to be solved + /// - k : k-points, the same meaning as the ground state + /// - "basis" : number of occupied ks-orbitals(subscripts i,j) * number of unoccupied ks-orbitals(subscripts a,b), corresponding to "bands" of the ground state + this->dim = psi.get_k_first() ? psi.get_current_nbas() : psi.get_nk() * psi.get_nbasis(); + this->dmx = psi.get_k_first() ? psi.get_nbasis() : psi.get_nk() * psi.get_nbasis(); this->n_band = psi.get_nbands(); this->nbase_x = DiagoDavid::PW_DIAG_NDIM * this->n_band; // maximum dimension of the reduced basis set @@ -132,20 +173,23 @@ void DiagoDavid::diag_mock(hamilt::Hamilt* phm_in, if(GlobalV::use_paw) { #ifdef USE_PAW - GlobalC::paw_cell.paw_nl_psi(1,reinterpret_cast*> (&psi(m, 0)), +#ifdef __DEBUG + assert(psi.get_k_first()); +#endif + GlobalC::paw_cell.paw_nl_psi(1, reinterpret_cast*> (&psi(m, 0)), reinterpret_cast*>(&this->sphi[m * this->dim])); #endif } else { - phm_in->sPsi(&psi(m, 0), &this->sphi[m * this->dim], (size_t)this->dim); + phm_in->sPsi(psi.get_k_first() ? &psi(m, 0) : &psi(m, 0, 0), &this->sphi[m * this->dim], (size_t)this->dim); } } // begin SchmitOrth for (int m = 0; m < this->n_band; m++) { // haozhihan replace 2022-10-23 - syncmem_complex_op()(this->ctx, this->ctx, &basis(m, 0), &psi(m, 0), this->dim); + syncmem_complex_op()(this->ctx, this->ctx, &basis(m, 0), psi.get_k_first() ? &psi(m, 0) : &psi(m, 0, 0), this->dim); this->SchmitOrth(this->dim, this->n_band, @@ -232,7 +276,7 @@ void DiagoDavid::diag_mock(hamilt::Hamilt* phm_in, setmem_complex_op()(this->ctx, psi.get_pointer(), 0, n_band * this->dmx); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-18 - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'N', 'N', this->dim, // m: row of A,C @@ -342,7 +386,7 @@ void DiagoDavid::cal_grad(hamilt::Hamilt* phm_in, //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-18 - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'N', 'N', this->dim, // m: row of A,C @@ -379,7 +423,7 @@ void DiagoDavid::cal_grad(hamilt::Hamilt* phm_in, Real* e_temp_gpu = nullptr; resmem_var_op()(this->ctx, e_temp_gpu, nbase); syncmem_var_h2d_op()(this->ctx, this->cpu_ctx, e_temp_gpu, e_temp_cpu.data(), nbase); - vector_mul_vector_op()(this->ctx, + vector_mul_vector_op()(this->ctx, nbase, vc_ev_vector + m * nbase, vc_ev_vector + m * nbase, @@ -389,7 +433,7 @@ void DiagoDavid::cal_grad(hamilt::Hamilt* phm_in, } else { - vector_mul_vector_op()(this->ctx, + vector_mul_vector_op()(this->ctx, nbase, vc_ev_vector + m * nbase, vc_ev_vector + m * nbase, @@ -400,7 +444,7 @@ void DiagoDavid::cal_grad(hamilt::Hamilt* phm_in, //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-18 - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'N', 'N', this->dim, // m: row of A,C @@ -424,7 +468,7 @@ void DiagoDavid::cal_grad(hamilt::Hamilt* phm_in, if (this->device == psi::GpuDevice) { #if defined(__CUDA) || defined(__ROCM) - vector_div_vector_op()(this->ctx, + vector_div_vector_op()(this->ctx, this->dim, &basis(nbase + m, 0), &basis(nbase + m, 0), @@ -433,7 +477,7 @@ void DiagoDavid::cal_grad(hamilt::Hamilt* phm_in, } else { - vector_div_vector_op()(this->ctx, + vector_div_vector_op()(this->ctx, this->dim, &basis(nbase + m, 0), &basis(nbase + m, 0), @@ -475,7 +519,7 @@ void DiagoDavid::cal_grad(hamilt::Hamilt* phm_in, // calculate the square matrix for future lagranges //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan replace 2022-10-18 - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'C', 'N', nbase, // m: row of A,C @@ -543,7 +587,7 @@ void DiagoDavid::cal_elem(const int& dim, return; ModuleBase::timer::tick("DiagoDavid", "cal_elem"); - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'C', 'N', notconv, @@ -558,7 +602,7 @@ void DiagoDavid::cal_elem(const int& dim, hcc + nbase, // notconv * (nbase + notconv) this->nbase_x); - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'C', 'N', notconv, @@ -577,31 +621,38 @@ void DiagoDavid::cal_elem(const int& dim, #ifdef __MPI if (GlobalV::NPROC_IN_POOL > 1) { - matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, hcc, hcc); - matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, scc, scc); + matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, hcc, hcc); + matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, scc, scc); auto* swap = new T[notconv * this->nbase_x]; syncmem_complex_op()(this->ctx, this->ctx, swap, hcc + nbase * this->nbase_x, notconv * this->nbase_x); - if (psi::device::get_current_precision(swap) == "single") { - MPI_Reduce(swap, hcc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_COMPLEX, MPI_SUM, 0,POOL_WORLD); - } - else { - MPI_Reduce(swap, hcc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_DOUBLE_COMPLEX, MPI_SUM, 0,POOL_WORLD); - } - syncmem_complex_op()(this->ctx, this->ctx, swap, scc + nbase * this->nbase_x, notconv * this->nbase_x); - if (psi::device::get_current_precision(swap) == "single") { - MPI_Reduce(swap, scc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_COMPLEX, MPI_SUM, 0, POOL_WORLD); + if (std::is_same::value) + { + Parallel_Reduce::reduce_pool(hcc + nbase * this->nbase_x, notconv * this->nbase_x); } - else { - MPI_Reduce(swap, scc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_DOUBLE_COMPLEX, MPI_SUM, 0, POOL_WORLD); + else + { + if (psi::device::get_current_precision(swap) == "single") { + MPI_Reduce(swap, hcc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_COMPLEX, MPI_SUM, 0, POOL_WORLD); + } + else { + MPI_Reduce(swap, hcc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_DOUBLE_COMPLEX, MPI_SUM, 0, POOL_WORLD); + } + syncmem_complex_op()(this->ctx, this->ctx, swap, scc + nbase * this->nbase_x, notconv * this->nbase_x); + if (psi::device::get_current_precision(swap) == "single") { + MPI_Reduce(swap, scc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_COMPLEX, MPI_SUM, 0, POOL_WORLD); + } + else { + MPI_Reduce(swap, scc + nbase * this->nbase_x, notconv * this->nbase_x, MPI_DOUBLE_COMPLEX, MPI_SUM, 0, POOL_WORLD); + } } delete[] swap; // Parallel_Reduce::reduce_complex_double_pool( hcc + nbase * this->nbase_x, notconv * this->nbase_x ); // Parallel_Reduce::reduce_complex_double_pool( scc + nbase * this->nbase_x, notconv * this->nbase_x ); - matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, hcc, hcc); - matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, scc, scc); + matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, hcc, hcc); + matrixTranspose_op()(this->ctx, this->nbase_x, this->nbase_x, scc, scc); } #endif @@ -643,7 +694,7 @@ void DiagoDavid::diag_zhegvx(const int& nbase, resmem_var_op()(this->ctx, eigenvalue_gpu, this->nbase_x); syncmem_var_h2d_op()(this->ctx, this->cpu_ctx, eigenvalue_gpu, this->eigenvalue, this->nbase_x); - dnevx_op()(this->ctx, nbase, this->nbase_x, this->hcc, nband, eigenvalue_gpu, this->vcc); + dnevx_op()(this->ctx, nbase, this->nbase_x, this->hcc, nband, eigenvalue_gpu, this->vcc); syncmem_var_d2h_op()(this->cpu_ctx, this->ctx, this->eigenvalue, eigenvalue_gpu, this->nbase_x); delmem_var_op()(this->ctx, eigenvalue_gpu); @@ -651,7 +702,7 @@ void DiagoDavid::diag_zhegvx(const int& nbase, } else { - dnevx_op()(this->ctx, nbase, this->nbase_x, this->hcc, nband, this->eigenvalue, this->vcc); + dnevx_op()(this->ctx, nbase, this->nbase_x, this->hcc, nband, this->eigenvalue, this->vcc); } } @@ -692,7 +743,7 @@ void DiagoDavid::refresh(const int& dim, basis.zero_out(); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-18 - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'N', 'N', this->dim, // m: row of A,C @@ -710,7 +761,7 @@ void DiagoDavid::refresh(const int& dim, //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-18 - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'N', 'N', this->dim, // m: row of A,C @@ -741,7 +792,7 @@ void DiagoDavid::refresh(const int& dim, basis.zero_out(); for (int m = 0; m < nband; m++) { - syncmem_complex_op()(this->ctx, this->ctx, &basis(m, 0), &psi(m, 0), this->dim); + syncmem_complex_op()(this->ctx, this->ctx, &basis(m, 0), psi.get_k_first() ? &psi(m, 0) : &psi(m, 0, 0), this->dim); /*for (int ig = 0; ig < npw; ig++) basis(m, ig) = psi(m, ig);*/ } @@ -776,9 +827,9 @@ void DiagoDavid::refresh(const int& dim, this->nbase_x * this->nbase_x, "DAV::vcc"); - syncmem_complex_d2h_op()(this->cpu_ctx, this->ctx, hcc_cpu, hcc, this->nbase_x * this->nbase_x); - syncmem_complex_d2h_op()(this->cpu_ctx, this->ctx, scc_cpu, scc, this->nbase_x * this->nbase_x); - syncmem_complex_d2h_op()(this->cpu_ctx, this->ctx, vcc_cpu, vcc, this->nbase_x * this->nbase_x); + syncmem_d2h_op()(this->cpu_ctx, this->ctx, hcc_cpu, hcc, this->nbase_x * this->nbase_x); + syncmem_d2h_op()(this->cpu_ctx, this->ctx, scc_cpu, scc, this->nbase_x * this->nbase_x); + syncmem_d2h_op()(this->cpu_ctx, this->ctx, vcc_cpu, vcc, this->nbase_x * this->nbase_x); for (int i = 0; i < nbase; i++) { @@ -787,9 +838,9 @@ void DiagoDavid::refresh(const int& dim, vcc_cpu[i * this->nbase_x + i] = this->one[0]; } - syncmem_complex_h2d_op()(this->ctx, this->cpu_ctx, hcc, hcc_cpu, this->nbase_x * this->nbase_x); - syncmem_complex_h2d_op()(this->ctx, this->cpu_ctx, scc, scc_cpu, this->nbase_x * this->nbase_x); - syncmem_complex_h2d_op()(this->ctx, this->cpu_ctx, vcc, vcc_cpu, this->nbase_x * this->nbase_x); + syncmem_h2d_op()(this->ctx, this->cpu_ctx, hcc, hcc_cpu, this->nbase_x * this->nbase_x); + syncmem_h2d_op()(this->ctx, this->cpu_ctx, scc, scc_cpu, this->nbase_x * this->nbase_x); + syncmem_h2d_op()(this->ctx, this->cpu_ctx, vcc, vcc_cpu, this->nbase_x * this->nbase_x); psi::memory::delete_memory_op()(this->cpu_ctx, hcc_cpu); psi::memory::delete_memory_op()(this->cpu_ctx, scc_cpu); @@ -844,7 +895,7 @@ void DiagoDavid::SchmitOrth(const int& dim, { //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-16 - gemm_op()(this->ctx, + gemm_op()(this->ctx, 'C', 'N', mm_size, // m: row of A,C @@ -863,7 +914,7 @@ void DiagoDavid::SchmitOrth(const int& dim, // calculate other lagranges for this band //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-16 - gemv_op()(this->ctx, + gemv_op()(this->ctx, 'C', this->dim, mv_size, @@ -877,16 +928,16 @@ void DiagoDavid::SchmitOrth(const int& dim, 1); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - Parallel_Reduce::reduce_complex_double_pool(lagrange_m, m + 1); + Parallel_Reduce::reduce_pool(lagrange_m, m + 1); - T var = {0, 0}; - syncmem_complex_d2h_op()(this->cpu_ctx, this->ctx, &var, lagrange_m + m, 1); - double psi_norm = var.real(); + T var = *this->zero; + syncmem_d2h_op()(this->cpu_ctx, this->ctx, &var, lagrange_m + m, 1); + double psi_norm = get_real(var); assert(psi_norm > 0.0); // haozhihan replace 2022-10-24 - gemv_op()(this->ctx, + gemv_op()(this->ctx, 'N', this->dim, m, @@ -899,7 +950,7 @@ void DiagoDavid::SchmitOrth(const int& dim, psi_m, 1); - psi_norm -= zdot_real_op()(this->ctx, m, lagrange_m, lagrange_m, false); + psi_norm -= dot_real_op()(this->ctx, m, lagrange_m, lagrange_m, false); // for (int j = 0; j < m; j++) // { @@ -927,7 +978,7 @@ void DiagoDavid::SchmitOrth(const int& dim, { //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // haozhihan repalce 2022-10-16 - vector_div_constant_op()(this->ctx, this->dim, psi_m, psi_m, psi_norm); + vector_div_constant_op()(this->ctx, this->dim, psi_m, psi_m, psi_norm); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // for (int i = 0; i < npw; i++) // { @@ -1039,4 +1090,10 @@ template class DiagoDavid, psi::DEVICE_CPU>; template class DiagoDavid, psi::DEVICE_GPU>; template class DiagoDavid, psi::DEVICE_GPU>; #endif +#ifdef __LCAO +template class DiagoDavid; +#if ((defined __CUDA) || (defined __ROCM)) +template class DiagoDavid; +#endif +#endif } // namespace hsolver diff --git a/source/module_hsolver/diago_david.h b/source/module_hsolver/diago_david.h index 72c1886c5aa..b3edcde9e16 100644 --- a/source/module_hsolver/diago_david.h +++ b/source/module_hsolver/diago_david.h @@ -16,6 +16,13 @@ #include "module_hamilt_pw/hamilt_pwdft/structure_factor.h" #include "module_psi/kernels/device.h" +template struct consts +{ + consts(); + T zero; + T one; + T neg_one; +}; namespace hsolver { @@ -142,12 +149,13 @@ class DiagoDavid : public DiagH using syncmem_var_d2h_op = psi::memory::synchronize_memory_op; using syncmem_complex_op = psi::memory::synchronize_memory_op; using castmem_complex_op = psi::memory::cast_memory_op, T, Device, Device>; - using syncmem_complex_h2d_op = psi::memory::synchronize_memory_op; - using syncmem_complex_d2h_op = psi::memory::synchronize_memory_op; + using syncmem_h2d_op = psi::memory::synchronize_memory_op; + using syncmem_d2h_op = psi::memory::synchronize_memory_op; using hpsi_info = typename hamilt::Operator::hpsi_info; - const T * one = nullptr, * zero = nullptr, * neg_one = nullptr; + consts cs; + const T* one = nullptr, * zero = nullptr, * neg_one = nullptr; }; template int DiagoDavid::PW_DIAG_NDIM = 4; } // namespace hsolver diff --git a/source/module_hsolver/diago_elpa.cpp b/source/module_hsolver/diago_elpa.cpp index be05260d7a4..f3852493a17 100644 --- a/source/module_hsolver/diago_elpa.cpp +++ b/source/module_hsolver/diago_elpa.cpp @@ -16,8 +16,12 @@ typedef hamilt::MatrixBlock> matcd; namespace hsolver { -int DiagoElpa::DecomposedState = 0; -void DiagoElpa::diag(hamilt::Hamilt> *phm_in, psi::Psi> &psi, double *eigenvalue_in) + template<> + int DiagoElpa::DecomposedState = 0; + template<> + int DiagoElpa>::DecomposedState = 0; + template<> + void DiagoElpa>::diag(hamilt::Hamilt>* phm_in, psi::Psi>& psi, Real* eigenvalue_in) { ModuleBase::TITLE("DiagoElpa", "diag"); #ifdef __MPI @@ -42,7 +46,8 @@ void DiagoElpa::diag(hamilt::Hamilt> *phm_in, psi::Psi> *phm_in, psi::Psi &psi, double *eigenvalue_in) + template<> + void DiagoElpa::diag(hamilt::Hamilt* phm_in, psi::Psi& psi, Real* eigenvalue_in) { ModuleBase::TITLE("DiagoElpa", "diag"); #ifdef __MPI @@ -70,7 +75,8 @@ void DiagoElpa::diag(hamilt::Hamilt> *phm_in, psi::Psi + bool DiagoElpa::ifElpaHandle(const bool& newIteration, const bool& ifNSCF) { int doHandle = false; if (newIteration) diff --git a/source/module_hsolver/diago_elpa.h b/source/module_hsolver/diago_elpa.h index 635d1673792..61e3343b143 100644 --- a/source/module_hsolver/diago_elpa.h +++ b/source/module_hsolver/diago_elpa.h @@ -7,14 +7,15 @@ namespace hsolver { -class DiagoElpa : public DiagH> -{ + template + class DiagoElpa : public DiagH + { + private: + using Real = typename GetTypeReal::type; - public: - void diag(hamilt::Hamilt>* phm_in, psi::Psi& psi, double* eigenvalue_in) override; + public: + void diag(hamilt::Hamilt* phm_in, psi::Psi& psi, Real* eigenvalue_in) override; - void diag(hamilt::Hamilt>* phm_in, psi::Psi>& psi, double* eigenvalue_in) override; - static int DecomposedState; private: diff --git a/source/module_hsolver/diago_iter_assist.cpp b/source/module_hsolver/diago_iter_assist.cpp index 99d8922e907..8d942f84cae 100644 --- a/source/module_hsolver/diago_iter_assist.cpp +++ b/source/module_hsolver/diago_iter_assist.cpp @@ -62,7 +62,7 @@ void DiagoIterAssist::diagH_subspace( hpsi_info hpsi_in(&psi, all_bands_range, hphi); pHamilt->ops->hPsi(hpsi_in); - gemm_op()( + gemm_op()( ctx, 'C', 'N', @@ -79,7 +79,7 @@ void DiagoIterAssist::diagH_subspace( nstart ); - gemm_op()( + gemm_op()( ctx, 'C', 'N', @@ -98,8 +98,8 @@ void DiagoIterAssist::diagH_subspace( if (GlobalV::NPROC_IN_POOL > 1) { - Parallel_Reduce::reduce_complex_double_pool(hcc, nstart * nstart); - Parallel_Reduce::reduce_complex_double_pool(scc, nstart * nstart); + Parallel_Reduce::reduce_pool(hcc, nstart * nstart); + Parallel_Reduce::reduce_pool(scc, nstart * nstart); } // after generation of H and S matrix, diag them @@ -133,7 +133,7 @@ void DiagoIterAssist::diagH_subspace( // because psi and evc are different here, // I think if psi and evc are the same, // there may be problems, mohan 2011-01-01 - gemm_op()( + gemm_op()( ctx, 'N', 'N', @@ -159,7 +159,7 @@ void DiagoIterAssist::diagH_subspace( resmem_complex_op()(ctx, evctemp, n_band * dmin, "DiagSub::evctemp"); setmem_complex_op()(ctx, evctemp, 0, n_band * dmin); - gemm_op()( + gemm_op()( ctx, 'N', 'N', @@ -176,7 +176,7 @@ void DiagoIterAssist::diagH_subspace( dmin ); - matrixSetToAnother()(ctx, n_band, evctemp, dmin, evc.get_pointer(), dmax); + matrixSetToAnother()(ctx, n_band, evctemp, dmin, evc.get_pointer(), dmax); // for (int ib = 0; ib < n_band; ib++) // { // for (int ig = 0; ig < dmin; ig++) @@ -252,7 +252,7 @@ void DiagoIterAssist::diagH_subspace_init( hpsi_info hpsi_in(&psi_temp, all_bands_range, hpsi); pHamilt->ops->hPsi(hpsi_in); - gemm_op()( + gemm_op()( ctx, 'C', 'N', @@ -269,7 +269,7 @@ void DiagoIterAssist::diagH_subspace_init( nstart ); - gemm_op()( + gemm_op()( ctx, 'C', 'N', @@ -288,8 +288,8 @@ void DiagoIterAssist::diagH_subspace_init( if (GlobalV::NPROC_IN_POOL > 1) { - Parallel_Reduce::reduce_complex_double_pool(hcc, nstart * nstart); - Parallel_Reduce::reduce_complex_double_pool(scc, nstart * nstart); + Parallel_Reduce::reduce_pool(hcc, nstart * nstart); + Parallel_Reduce::reduce_pool(scc, nstart * nstart); } // after generation of H and S matrix, diag them @@ -331,7 +331,7 @@ void DiagoIterAssist::diagH_subspace_init( // because psi and evc are different here, // I think if psi and evc are the same, // there may be problems, mohan 2011-01-01 - gemm_op()( + gemm_op()( ctx, 'N', 'N', @@ -357,7 +357,7 @@ void DiagoIterAssist::diagH_subspace_init( resmem_complex_op()(ctx, evctemp, n_band * dmin, "DiagSub::evctemp"); setmem_complex_op()(ctx, evctemp, 0, n_band * dmin); - gemm_op()( + gemm_op()( ctx, 'N', 'N', @@ -374,7 +374,7 @@ void DiagoIterAssist::diagH_subspace_init( dmin ); - matrixSetToAnother()(ctx, n_band, evctemp, dmin, evc.get_pointer(), dmax); + matrixSetToAnother()(ctx, n_band, evctemp, dmin, evc.get_pointer(), dmax); delmem_complex_op()(ctx, evctemp); } @@ -403,7 +403,7 @@ void DiagoIterAssist::diagH_LAPACK( resmem_var_op()(ctx, eigenvalues, nstart); setmem_var_op()(ctx, eigenvalues, 0, nstart); - dngvd_op()(ctx, nstart, ldh, hcc, scc, eigenvalues, vcc); + dngvd_op()(ctx, nstart, ldh, hcc, scc, eigenvalues, vcc); if (psi::device::get_device_type(ctx) == psi::GpuDevice) { #if ((defined __CUDA) || (defined __ROCM)) @@ -469,4 +469,11 @@ template class DiagoIterAssist, psi::DEVICE_CPU>; template class DiagoIterAssist, psi::DEVICE_GPU>; template class DiagoIterAssist, psi::DEVICE_GPU>; #endif + +#ifdef __LCAO +template class DiagoIterAssist; +#if ((defined __CUDA) || (defined __ROCM)) +template class DiagoIterAssist; +#endif +#endif } // namespace hsolver diff --git a/source/module_hsolver/hsolver.h b/source/module_hsolver/hsolver.h index 7b5cc1453a2..643aece4788 100644 --- a/source/module_hsolver/hsolver.h +++ b/source/module_hsolver/hsolver.h @@ -44,15 +44,6 @@ class HSolver return; } - virtual void solve(hamilt::Hamilt* phm, - psi::Psi& ppsi, - elecstate::ElecState* pes, - const std::string method, - const bool skip_charge = false) - { - return; - } - virtual void solve(hamilt::Hamilt* phm, psi::Psi& ppsi, elecstate::ElecState* pes, diff --git a/source/module_hsolver/hsolver_lcao.cpp b/source/module_hsolver/hsolver_lcao.cpp index 1fea03dbed7..d26f0b2182b 100644 --- a/source/module_hsolver/hsolver_lcao.cpp +++ b/source/module_hsolver/hsolver_lcao.cpp @@ -12,7 +12,7 @@ namespace hsolver { template -void HSolverLCAO::solveTemplate(hamilt::Hamilt>* pHamilt, +void HSolverLCAO::solveTemplate(hamilt::Hamilt* pHamilt, psi::Psi& psi, elecstate::ElecState* pes, const std::string method_in, @@ -24,35 +24,35 @@ void HSolverLCAO::solveTemplate(hamilt::Hamilt>* pHamilt, this->method = method_in; if (this->method == "scalapack_gvx") { - if (pdiagh != nullptr) + if (this->pdiagh != nullptr) { - if (pdiagh->method != this->method) + if (this->pdiagh->method != this->method) { - delete[] pdiagh; - pdiagh = nullptr; + delete[] this->pdiagh; + this->pdiagh = nullptr; } } - if (pdiagh == nullptr) + if (this->pdiagh == nullptr) { - pdiagh = new DiagoBlas(); - pdiagh->method = this->method; + this->pdiagh = new DiagoBlas(); + this->pdiagh->method = this->method; } } #ifdef __ELPA else if (this->method == "genelpa") { - if (pdiagh != nullptr) + if (this->pdiagh != nullptr) { - if (pdiagh->method != this->method) + if (this->pdiagh->method != this->method) { - delete[] pdiagh; - pdiagh = nullptr; + delete[] this->pdiagh; + this->pdiagh = nullptr; } } - if (pdiagh == nullptr) + if (this->pdiagh == nullptr) { - pdiagh = new DiagoElpa(); - pdiagh->method = this->method; + this->pdiagh = new DiagoElpa(); + this->pdiagh->method = this->method; } } #endif @@ -63,18 +63,18 @@ void HSolverLCAO::solveTemplate(hamilt::Hamilt>* pHamilt, // until the obsolete globalc::hm is removed from // diago_lapack.cpp /* - if (pdiagh != nullptr) + if (this->pdiagh != nullptr) { - if (pdiagh->method != this->method) + if (this->pdiagh->method != this->method) { - delete[] pdiagh; - pdiagh = nullptr; + delete[] this->pdiagh; + this->pdiagh = nullptr; } } - if (pdiagh == nullptr) + if (this->pdiagh == nullptr) { - pdiagh = new DiagoLapack(); - pdiagh->method = this->method; + this->pdiagh = new DiagoLapack(); + this->pdiagh->method = this->method; } */ ModuleBase::WARNING_QUIT("HSolverLCAO::solve", "This method of DiagH is not supported!"); @@ -106,8 +106,8 @@ void HSolverLCAO::solveTemplate(hamilt::Hamilt>* pHamilt, if (this->method != "genelpa" && this->method != "scalapack_gvx" && this->method != "lapack") { - delete pdiagh; - pdiagh = nullptr; + delete this->pdiagh; + this->pdiagh = nullptr; } // used in nscf calculation @@ -122,43 +122,35 @@ void HSolverLCAO::solveTemplate(hamilt::Hamilt>* pHamilt, pes->psiToRho(psi); ModuleBase::timer::tick("HSolverLCAO", "solve"); } +template +int HSolverLCAO::out_mat_hs = 0; +template +int HSolverLCAO::out_mat_hsR = 0; +template +int HSolverLCAO::out_mat_t = 0; +template +int HSolverLCAO::out_mat_dh = 0; -int HSolverLCAO::out_mat_hs = 0; -int HSolverLCAO::out_mat_hsR = 0; -int HSolverLCAO::out_mat_t = 0; -int HSolverLCAO::out_mat_dh = 0; - -void HSolverLCAO::solve(hamilt::Hamilt>* pHamilt, - psi::Psi>& psi, - elecstate::ElecState* pes, - const std::string method_in, - const bool skip_charge) -{ - this->solveTemplate(pHamilt, psi, pes, method, skip_charge); -} -void HSolverLCAO::solve(hamilt::Hamilt>* pHamilt, - psi::Psi& psi, - elecstate::ElecState* pes, - const std::string method_in, - const bool skip_charge) +template +void HSolverLCAO::solve(hamilt::Hamilt* pHamilt, + psi::Psi& psi, + elecstate::ElecState* pes, + const std::string method_in, + const bool skip_charge) { - this->solveTemplate(pHamilt, psi, pes, method, skip_charge); + this->solveTemplate(pHamilt, psi, pes, this->method, skip_charge); } -void HSolverLCAO::hamiltSolvePsiK(hamilt::Hamilt>* hm, psi::Psi>& psi, double* eigenvalue) +template +void HSolverLCAO::hamiltSolvePsiK(hamilt::Hamilt* hm, psi::Psi& psi, double* eigenvalue) { ModuleBase::TITLE("HSolverLCAO", "hamiltSolvePsiK"); ModuleBase::timer::tick("HSolverLCAO", "hamiltSolvePsiK"); - pdiagh->diag(hm, psi, eigenvalue); + this->pdiagh->diag(hm, psi, eigenvalue); ModuleBase::timer::tick("HSolverLCAO", "hamiltSolvePsiK"); } -void HSolverLCAO::hamiltSolvePsiK(hamilt::Hamilt>* hm, psi::Psi& psi, double* eigenvalue) -{ - ModuleBase::TITLE("HSolverLCAO", "hamiltSolvePsiK"); - ModuleBase::timer::tick("HSolverLCAO", "hamiltSolvePsiK"); - pdiagh->diag(hm, psi, eigenvalue); - ModuleBase::timer::tick("HSolverLCAO", "hamiltSolvePsiK"); -} +template class HSolverLCAO; +template class HSolverLCAO>; } // namespace hsolver \ No newline at end of file diff --git a/source/module_hsolver/hsolver_lcao.h b/source/module_hsolver/hsolver_lcao.h index e7067f27381..5a702590016 100644 --- a/source/module_hsolver/hsolver_lcao.h +++ b/source/module_hsolver/hsolver_lcao.h @@ -7,7 +7,8 @@ namespace hsolver { -class HSolverLCAO : public HSolver> + template + class HSolverLCAO : public HSolver { public: HSolverLCAO(const Parallel_Orbitals* ParaV_in) @@ -22,9 +23,7 @@ class HSolverLCAO : public HSolver> void update(//Input &in ) override;*/ - void solve(hamilt::Hamilt>* pHamilt, psi::Psi>& psi, elecstate::ElecState* pes, const std::string method_in, const bool skip_charge) override; - - void solve(hamilt::Hamilt>* pHamilt, psi::Psi& psi, elecstate::ElecState* pes, const std::string method_in, const bool skip_charge) override; + void solve(hamilt::Hamilt* pHamilt, psi::Psi& psi, elecstate::ElecState* pes, const std::string method_in, const bool skip_charge) override; static int out_mat_hs; // mohan add 2010-09-02 static int out_mat_hsR; // LiuXh add 2019-07-16 @@ -32,10 +31,9 @@ class HSolverLCAO : public HSolver> static int out_mat_dh; private: - void hamiltSolvePsiK(hamilt::Hamilt>* hm, psi::Psi>& psi, double* eigenvalue); - void hamiltSolvePsiK(hamilt::Hamilt>* hm, psi::Psi& psi, double* eigenvalue); + void hamiltSolvePsiK(hamilt::Hamilt* hm, psi::Psi& psi, double* eigenvalue); - template void solveTemplate(hamilt::Hamilt>* pHamilt, psi::Psi& psi, elecstate::ElecState* pes, const std::string method_in, const bool skip_charge); + void solveTemplate(hamilt::Hamilt* pHamilt, psi::Psi& psi, elecstate::ElecState* pes, const std::string method_in, const bool skip_charge); /*void solveTemplate( hamilt::Hamilt* pHamilt, psi::Psi>& psi, diff --git a/source/module_hsolver/kernels/cuda/dngvd_op.cu b/source/module_hsolver/kernels/cuda/dngvd_op.cu index 228788d52c3..95fd4b9eda2 100644 --- a/source/module_hsolver/kernels/cuda/dngvd_op.cu +++ b/source/module_hsolver/kernels/cuda/dngvd_op.cu @@ -73,6 +73,37 @@ void destroyGpuSolverHandle() } } +static inline +void xhegvd_wrapper( + const cublasFillMode_t& uplo, + const int& n, + double* A, const int& lda, + double* B, const int& ldb, + double* W) +{ + // prepare some values for cusolverDnZhegvd_bufferSize + int* devInfo = nullptr; + int lwork = 0, info_gpu = 0; + double* work = nullptr; + checkCudaErrors(cudaMalloc((void**)&devInfo, sizeof(int))); + + // calculate the sizes needed for pre-allocated buffer. + cusolverErrcheck(cusolverDnDsygvd_bufferSize(cusolver_H, CUSOLVER_EIG_TYPE_1, CUSOLVER_EIG_MODE_VECTOR, uplo, n, + A, lda, B, ldb, W, &lwork)); + // allocate memery + checkCudaErrors(cudaMalloc((void**)&work, sizeof(double) * lwork)); + + // compute eigenvalues and eigenvectors. + cusolverErrcheck(cusolverDnDsygvd(cusolver_H, CUSOLVER_EIG_TYPE_1, CUSOLVER_EIG_MODE_VECTOR, uplo, n, + A, lda, B, ldb, W, work, lwork, devInfo)); + + checkCudaErrors(cudaMemcpy(&info_gpu, devInfo, sizeof(int), cudaMemcpyDeviceToHost)); + assert(0 == info_gpu); + // free the buffer + checkCudaErrors(cudaFree(work)); + checkCudaErrors(cudaFree(devInfo)); +} + static inline void xhegvd_wrapper ( const cublasFillMode_t& uplo, @@ -137,6 +168,33 @@ void xhegvd_wrapper ( checkCudaErrors(cudaFree(devInfo)); } +static inline +void xheevd_wrapper( + const cublasFillMode_t& uplo, + const int& n, + double* A, const int& lda, + double* W) +{ + // prepare some values for cusolverDnZhegvd_bufferSize + int* devInfo = nullptr; + int lwork = 0, info_gpu = 0; + double* work = nullptr; + checkCudaErrors(cudaMalloc((void**)&devInfo, sizeof(int))); + + // calculate the sizes needed for pre-allocated buffer. + cusolverErrcheck(cusolverDnDsyevd_bufferSize(cusolver_H, CUSOLVER_EIG_MODE_VECTOR, uplo, n, + A, lda, W, &lwork)); + // allocate memery + checkCudaErrors(cudaMalloc((void**)&work, sizeof(double) * lwork)); + // compute eigenvalues and eigenvectors. + cusolverErrcheck(cusolverDnDsyevd(cusolver_H, CUSOLVER_EIG_MODE_VECTOR, uplo, n, A, lda, W, work, lwork, devInfo)); + + checkCudaErrors(cudaMemcpy(&info_gpu, devInfo, sizeof(int), cudaMemcpyDeviceToHost)); + assert(0 == info_gpu); + checkCudaErrors(cudaFree(work)); + checkCudaErrors(cudaFree(devInfo)); +} + static inline void xheevd_wrapper ( const cublasFillMode_t& uplo, @@ -192,46 +250,53 @@ void xheevd_wrapper ( checkCudaErrors(cudaFree(devInfo)); } -template -struct dngvd_op { +template +struct dngvd_op { + using Real = typename GetTypeReal::type; void operator()( - const psi::DEVICE_GPU *d, - const int nstart, - const int ldh, - const std::complex *A, // hcc - const std::complex *B, // scc - FPTYPE *W, // eigenvalue - std::complex *V) + const psi::DEVICE_GPU* d, + const int nstart, + const int ldh, + const T* A, // hcc + const T* B, // scc + Real* W, // eigenvalue + T* V) { assert(nstart == ldh); // A to V - checkCudaErrors(cudaMemcpy(V, A, sizeof(std::complex) * ldh * nstart, cudaMemcpyDeviceToDevice)); + checkCudaErrors(cudaMemcpy(V, A, sizeof(T) * ldh * nstart, cudaMemcpyDeviceToDevice)); xhegvd_wrapper(CUBLAS_FILL_MODE_UPPER, nstart, V, ldh, - (std::complex *)B, ldh, W); + (T*)B, ldh, W); } }; -template -struct dnevx_op { +template +struct dnevx_op { + using Real = typename GetTypeReal::type; void operator()( - const psi::DEVICE_GPU *d, - const int nstart, - const int ldh, - const std::complex *A, // hcc - const int m, - FPTYPE *W, // eigenvalue - std::complex *V) + const psi::DEVICE_GPU* d, + const int nstart, + const int ldh, + const T* A, // hcc + const int m, + Real* W, // eigenvalue + T* V) { assert(nstart <= ldh); // A to V - checkCudaErrors(cudaMemcpy(V, A, sizeof(std::complex) * nstart * ldh, cudaMemcpyDeviceToDevice)); + checkCudaErrors(cudaMemcpy(V, A, sizeof(T) * nstart * ldh, cudaMemcpyDeviceToDevice)); xheevd_wrapper(CUBLAS_FILL_MODE_LOWER, nstart, V, ldh, W); } }; -template struct dngvd_op; -template struct dnevx_op; +template struct dngvd_op, psi::DEVICE_GPU>; +template struct dnevx_op, psi::DEVICE_GPU>; +template struct dngvd_op, psi::DEVICE_GPU>; +template struct dnevx_op, psi::DEVICE_GPU>; + +#ifdef __LCAO template struct dngvd_op; template struct dnevx_op; +#endif } // namespace hsolver \ No newline at end of file diff --git a/source/module_hsolver/kernels/cuda/math_kernel_op.cu b/source/module_hsolver/kernels/cuda/math_kernel_op.cu index efe540a1388..c52af8a5994 100644 --- a/source/module_hsolver/kernels/cuda/math_kernel_op.cu +++ b/source/module_hsolver/kernels/cuda/math_kernel_op.cu @@ -12,9 +12,16 @@ #define FULL_MASK 0xffffffff #define THREAD_PER_BLOCK 256 +template <> +struct GetTypeReal> { + using type = float; /**< The return type specialization for std::complex. */ +}; +template <> +struct GetTypeReal> { + using type = double; /**< The return type specialization for std::complex. */ +}; namespace hsolver { - static cublasHandle_t cublas_handle = nullptr; static inline @@ -211,12 +218,12 @@ __global__ void calc_grad_with_block( } // Define the CUDA kernel: -template +template __global__ void vector_div_constant_kernel( const int size, - thrust::complex* result, - const thrust::complex* vector, - const FPTYPE constant) + T* result, + const T* vector, + const typename GetTypeReal::type constant) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < size) @@ -225,12 +232,12 @@ __global__ void vector_div_constant_kernel( } } -template +template __global__ void vector_mul_vector_kernel( const int size, - thrust::complex* result, - const thrust::complex* vector1, - const FPTYPE* vector2) + T* result, + const T* vector1, + const typename GetTypeReal::type* vector2) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < size) @@ -239,12 +246,12 @@ __global__ void vector_mul_vector_kernel( } } -template +template __global__ void vector_div_vector_kernel( const int size, - thrust::complex* result, - const thrust::complex* vector1, - const FPTYPE* vector2) + T* result, + const T* vector1, + const typename GetTypeReal::type* vector2) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < size) @@ -269,12 +276,12 @@ __global__ void constantvector_addORsub_constantVector_kernel( } } -template +template __global__ void matrix_transpose_kernel( const int row, const int col, - const thrust::complex* in, - thrust::complex* out) + const T* in, + T* out) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < row) @@ -287,13 +294,13 @@ __global__ void matrix_transpose_kernel( } -template +template __global__ void matrix_setTo_another_kernel( const int n, const int LDA, const int LDB, - const thrust::complex* matrix_A, - thrust::complex* matrix_B) + const T* matrix_A, + T* matrix_B) { int j = blockIdx.x * blockDim.x + threadIdx.x; if (j < LDA && j < LDB) @@ -349,33 +356,82 @@ void calc_grad_with_block_op::operator()( n_basis, n_basis_max); } +template <> +double dot_real_op::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + const double* psi_L, + const double* psi_R, + const bool reduce) +{ + double result = 0.0; + xdot_wrapper(dim, psi_L, 1, psi_R, 1, result); + if (reduce) { + Parallel_Reduce::reduce_pool(result); + } + return result; +} // for this implementation, please check // https://thrust.github.io/doc/group__transformed__reductions_ga321192d85c5f510e52300ae762c7e995.html denghui modify -// 2022-10-03 Note that ddot_(2*dim,a,1, b,1) = REAL( zdotc_(dim,a,1,b,1) ) GPU specialization of actual computation. -template -FPTYPE zdot_real_op::operator()( - const psi::DEVICE_GPU* d, +// 2022-10-03 Note that ddot_(2*dim,a,1,b,1) = REAL( zdotc_(dim,a,1,b,1) ) GPU specialization of actual computation. +template +inline FPTYPE dot_complex_wrapper(const psi::DEVICE_GPU* d, const int& dim, const std::complex* psi_L, const std::complex* psi_R, const bool reduce) { - //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - // denghui modify 2022-10-07 - // Note that ddot_(2*dim,a,1,b,1) = REAL( zdotc_(dim,a,1,b,1) ) - const FPTYPE* pL = reinterpret_cast(psi_L); - const FPTYPE* pR = reinterpret_cast(psi_R); - FPTYPE result = 0.0; - xdot_wrapper(dim * 2, pL, 1, pR, 1, result); - if (reduce) { - Parallel_Reduce::reduce_double_pool(result); - } - return result; + //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // denghui modify 2022-10-07 + // Note that ddot_(2*dim,a,1,b,1) = REAL( zdotc_(dim,a,1,b,1) ) + const FPTYPE* pL = reinterpret_cast(psi_L); + const FPTYPE* pR = reinterpret_cast(psi_R); + FPTYPE result = 0.0; + xdot_wrapper(dim * 2, pL, 1, pR, 1, result); + if (reduce) { + Parallel_Reduce::reduce_pool(result); + } + return result; +} + +template <> +float dot_real_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + const std::complex* psi_L, + const std::complex* psi_R, + const bool reduce) +{ + return dot_complex_wrapper(d, dim, psi_L, psi_R, reduce); +} +template <> +double dot_real_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + const std::complex* psi_L, + const std::complex* psi_R, + const bool reduce) +{ + return dot_complex_wrapper(d, dim, psi_L, psi_R, reduce); +} + +// vector operator: result[i] = vector[i] / constant +template <> +void vector_div_constant_op::operator()( + const psi::DEVICE_GPU* d, + const int dim, + double* result, + const double* vector, + const double constant) +{ + int thread = 1024; + int block = (dim + thread - 1) / thread; + vector_div_constant_kernel << > > (dim, result, vector, constant); } // vector operator: result[i] = vector[i] / constant template -void vector_div_constant_op::operator()( +inline void vector_div_constant_complex_wrapper( const psi::DEVICE_GPU* d, const int dim, std::complex* result, @@ -387,12 +443,44 @@ void vector_div_constant_op::operator()( int thread = 1024; int block = (dim + thread - 1) / thread; - vector_div_constant_kernel<<>>(dim, result_tmp, vector_tmp, constant); + vector_div_constant_kernel> << > > (dim, result_tmp, vector_tmp, constant); +} +template <> +void vector_div_constant_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int dim, + std::complex* result, + const std::complex* vector, + const float constant) +{ + vector_div_constant_complex_wrapper(d, dim, result, vector, constant); +} +template <> +void vector_div_constant_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int dim, + std::complex* result, + const std::complex* vector, + const double constant) +{ + vector_div_constant_complex_wrapper(d, dim, result, vector, constant); +} +// vector operator: result[i] = vector1[i](not complex) * vector2[i](not complex) +template <> +void vector_mul_vector_op::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + double* result, + const double* vector1, + const double* vector2) +{ + int thread = 1024; + int block = (dim + thread - 1) / thread; + vector_mul_vector_kernel << > > (dim, result, vector1, vector2); } - // vector operator: result[i] = vector1[i](complex) * vector2[i](not complex) -template -void vector_mul_vector_op::operator()( +template +inline void vector_mul_vector_complex_wrapper( const psi::DEVICE_GPU* d, const int& dim, std::complex* result, @@ -401,16 +489,47 @@ void vector_mul_vector_op::operator()( { thrust::complex* result_tmp = reinterpret_cast*>(result); const thrust::complex* vector1_tmp = reinterpret_cast*>(vector1); - int thread = 1024; int block = (dim + thread - 1) / thread; - vector_mul_vector_kernel<<>>(dim, result_tmp, vector1_tmp, vector2); + vector_mul_vector_kernel> << > > (dim, result_tmp, vector1_tmp, vector2); +} +template <> +void vector_mul_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const float* vector2) +{ + vector_mul_vector_complex_wrapper(d, dim, result, vector1, vector2); +} +template <> +void vector_mul_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const double* vector2) +{ + vector_mul_vector_complex_wrapper(d, dim, result, vector1, vector2); } - +// vector operator: result[i] = vector1[i](not complex) / vector2[i](not complex) +template <> +void vector_div_vector_op::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + double* result, + const double* vector1, + const double* vector2) +{ + int thread = 1024; + int block = (dim + thread - 1) / thread; + vector_div_vector_kernel << > > (dim, result, vector1, vector2); +} // vector operator: result[i] = vector1[i](complex) / vector2[i](not complex) -template -void vector_div_vector_op::operator()( +template +inline void vector_div_vector_complex_wrapper( const psi::DEVICE_GPU* d, const int& dim, std::complex* result, @@ -419,12 +538,30 @@ void vector_div_vector_op::operator()( { thrust::complex* result_tmp = reinterpret_cast*>(result); const thrust::complex* vector1_tmp = reinterpret_cast*>(vector1); - int thread = 1024; int block = (dim + thread - 1) / thread; - vector_div_vector_kernel<<>>(dim, result_tmp, vector1_tmp, vector2); + vector_div_vector_kernel> << > > (dim, result_tmp, vector1_tmp, vector2); +} +template <> +void vector_div_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const float* vector2) +{ + vector_div_vector_complex_wrapper(d, dim, result, vector1, vector2); +} +template <> +void vector_div_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const double* vector2) +{ + vector_div_vector_complex_wrapper(d, dim, result, vector1, vector2); } - // vector operator: result[i] = vector1[i] * constant1 + vector2[i] * constant2 template void constantvector_addORsub_constantVector_op::operator()( @@ -471,8 +608,33 @@ void axpy_op::operator()( cublasErrcheck(cublasZaxpy(cublas_handle, N, (double2*)alpha, (double2*)X, incX, (double2*)Y, incY)); } -template <> -void gemv_op::operator()( +template <> +void gemv_op::operator()( + const psi::DEVICE_GPU* d, + const char& trans, + const int& m, + const int& n, + const double* alpha, + const double* A, + const int& lda, + const double* X, + const int& incx, + const double* beta, + double* Y, + const int& incy) +{ + cublasOperation_t cutrans = {}; + if (trans == 'N') { + cutrans = CUBLAS_OP_N; + } + else if (trans == 'T') { + cutrans = CUBLAS_OP_T; + } + cublasErrcheck(cublasDgemv(cublas_handle, cutrans, m, n, alpha, A, lda, X, incx, beta, Y, incx)); +} + +template <> +void gemv_op, psi::DEVICE_GPU>::operator()( const psi::DEVICE_GPU* d, const char& trans, const int& m, @@ -500,7 +662,7 @@ void gemv_op::operator()( } template <> -void gemv_op::operator()( +void gemv_op, psi::DEVICE_GPU>::operator()( const psi::DEVICE_GPU* d, const char& trans, const int& m, @@ -547,9 +709,42 @@ void scal_op::operator()(const psi::DEVICE_GPU* d, cublasErrcheck(cublasZscal(cublas_handle, N, (double2*)alpha, (double2*)X, incx)); } - template <> -void gemm_op::operator()(const psi::DEVICE_GPU* d, +void gemm_op::operator()(const psi::DEVICE_GPU* d, + const char& transa, + const char& transb, + const int& m, + const int& n, + const int& k, + const double* alpha, + const double* a, + const int& lda, + const double* b, + const int& ldb, + const double* beta, + double* c, + const int& ldc) +{ + cublasOperation_t cutransA; + cublasOperation_t cutransB; + // cutransA + if (transa == 'N') { + cutransA = CUBLAS_OP_N; + } + else if (transa == 'T') { + cutransA = CUBLAS_OP_T; + } + // cutransB + if (transb == 'N') { + cutransB = CUBLAS_OP_N; + } + else if (transb == 'T') { + cutransB = CUBLAS_OP_T; + } + cublasErrcheck(cublasDgemm(cublas_handle, cutransA, cutransB, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)); +} +template <> +void gemm_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const char& transa, const char& transb, const int& m, @@ -590,7 +785,7 @@ void gemm_op::operator()(const psi::DEVICE_GPU* d, } template <> -void gemm_op::operator()(const psi::DEVICE_GPU* d, +void gemm_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const char& transa, const char& transb, const int& m, @@ -631,7 +826,37 @@ void gemm_op::operator()(const psi::DEVICE_GPU* d, } template <> -void matrixTranspose_op::operator()(const psi::DEVICE_GPU* d, +void matrixTranspose_op::operator()(const psi::DEVICE_GPU* d, + const int& row, + const int& col, + const double* input_matrix, + double* output_matrix) +{ + double* device_temp = nullptr; + psi::memory::resize_memory_op()(d, device_temp, row * col); + + if (row == col) + { + double ONE = 1.0, ZERO = 0.0; + + // use 'geam' API todo transpose. + cublasErrcheck(cublasDgeam(cublas_handle, CUBLAS_OP_T, CUBLAS_OP_N, col, row, &ONE, input_matrix, col, &ZERO, input_matrix, col, device_temp, col)); + } + else + { + int thread = 1024; + int block = (row + col + thread - 1) / thread; + matrix_transpose_kernel << > > (row, col, input_matrix, device_temp); + } + + psi::memory::synchronize_memory_op()(d, d, output_matrix, device_temp, row * col); + + psi::memory::delete_memory_op()(d, device_temp); + +} + +template <> +void matrixTranspose_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const int& row, const int& col, const std::complex* input_matrix, @@ -655,7 +880,7 @@ void matrixTranspose_op::operator()(const psi::DEVICE_GP { int thread = 1024; int block = (row + col + thread - 1) / thread; - matrix_transpose_kernel<<>>(row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); + matrix_transpose_kernel> << > > (row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); } psi::memory::synchronize_memory_op, psi::DEVICE_GPU, psi::DEVICE_GPU>()(d, d, output_matrix, device_temp, row * col); @@ -665,7 +890,7 @@ void matrixTranspose_op::operator()(const psi::DEVICE_GP } template <> -void matrixTranspose_op::operator()(const psi::DEVICE_GPU* d, +void matrixTranspose_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const int& row, const int& col, const std::complex* input_matrix, @@ -687,7 +912,7 @@ void matrixTranspose_op::operator()(const psi::DEVICE_G { int thread = 1024; int block = (row + col + thread - 1) / thread; - matrix_transpose_kernel<<>>(row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); + matrix_transpose_kernel> << > > (row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); } psi::memory::synchronize_memory_op, psi::DEVICE_GPU, psi::DEVICE_GPU>()(d, d, output_matrix, device_temp, row * col); @@ -696,40 +921,71 @@ void matrixTranspose_op::operator()(const psi::DEVICE_G } - -template -void matrixSetToAnother::operator()( +template <> +void matrixSetToAnother::operator()( + const psi::DEVICE_GPU* d, + const int& n, + const double* A, + const int& LDA, + double* B, + const int& LDB) +{ + int thread = 1024; + int block = (LDA + thread - 1) / thread; + matrix_setTo_another_kernel << > > (n, LDA, LDB, A, B); +} +template <> +void matrixSetToAnother, psi::DEVICE_GPU>::operator()( const psi::DEVICE_GPU* d, const int& n, - const std::complex* A, + const std::complex* A, const int& LDA, - std::complex* B, + std::complex* B, const int& LDB) { int thread = 1024; int block = (LDA + thread - 1) / thread; - matrix_setTo_another_kernel<<>>(n, LDA, LDB, reinterpret_cast*>(A), reinterpret_cast*>(B)); + matrix_setTo_another_kernel> << > > (n, LDA, LDB, reinterpret_cast*>(A), reinterpret_cast*>(B)); +} +template <> +void matrixSetToAnother, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& n, + const std::complex* A, + const int& LDA, + std::complex* B, + const int& LDB) +{ + int thread = 1024; + int block = (LDA + thread - 1) / thread; + matrix_setTo_another_kernel> << > > (n, LDA, LDB, reinterpret_cast*>(A), reinterpret_cast*>(B)); } - // Explicitly instantiate functors for the types of functor registered. -template struct zdot_real_op; +template struct dot_real_op, psi::DEVICE_GPU>; template struct calc_grad_with_block_op, psi::DEVICE_GPU>; template struct line_minimize_with_block_op, psi::DEVICE_GPU>; -template struct vector_div_constant_op; -template struct vector_mul_vector_op; -template struct vector_div_vector_op; +template struct vector_div_constant_op, psi::DEVICE_GPU>; +template struct vector_mul_vector_op, psi::DEVICE_GPU>; +template struct vector_div_vector_op, psi::DEVICE_GPU>; template struct constantvector_addORsub_constantVector_op; -template struct matrixSetToAnother; +template struct matrixSetToAnother, psi::DEVICE_GPU>; -template struct zdot_real_op; +template struct dot_real_op, psi::DEVICE_GPU>; template struct calc_grad_with_block_op, psi::DEVICE_GPU>; template struct line_minimize_with_block_op, psi::DEVICE_GPU>; +template struct vector_div_constant_op, psi::DEVICE_GPU>; +template struct vector_mul_vector_op, psi::DEVICE_GPU>; +template struct vector_div_vector_op, psi::DEVICE_GPU>; +template struct constantvector_addORsub_constantVector_op; +template struct matrixSetToAnother, psi::DEVICE_GPU>; + +#ifdef __LCAO +template struct dot_real_op; template struct vector_div_constant_op; template struct vector_mul_vector_op; template struct vector_div_vector_op; -template struct constantvector_addORsub_constantVector_op; template struct matrixSetToAnother; - +#endif } // namespace hsolver diff --git a/source/module_hsolver/kernels/dngvd_op.cpp b/source/module_hsolver/kernels/dngvd_op.cpp index b2c24651977..9477264c54a 100644 --- a/source/module_hsolver/kernels/dngvd_op.cpp +++ b/source/module_hsolver/kernels/dngvd_op.cpp @@ -4,27 +4,41 @@ namespace hsolver { -template -struct dngvd_op { - void operator()( - const psi::DEVICE_CPU *d, - const int nstart, - const int ldh, - const std::complex *hcc, - const std::complex *scc, - FPTYPE *eigenvalue, - std::complex *vcc) + inline double get_real(const double& x) + { + return x; + } + inline double get_real(const std::complex& x) + { + return x.real(); + } + inline float get_real(const std::complex& x) + { + return x.real(); + } + + template + struct dngvd_op { + using Real = typename GetTypeReal::type; + void operator()( + const psi::DEVICE_CPU* d, + const int nstart, + const int ldh, + const T* hcc, + const T* scc, + Real* eigenvalue, + T* vcc) { for (int i = 0; i < nstart * ldh; i++) { vcc[i] = hcc[i]; } int info = 0; int lwork = 2 * nstart + nstart * nstart; - std::complex *work = new std::complex[lwork]; + T* work = new T[lwork]; ModuleBase::GlobalFunc::ZEROS(work, lwork); int lrwork = 1 + 5 * nstart + 2 * nstart * nstart; - FPTYPE *rwork = new FPTYPE[lrwork]; + Real* rwork = new Real[lrwork]; ModuleBase::GlobalFunc::ZEROS(rwork, lrwork); int liwork = 3 + 5 * nstart; @@ -48,26 +62,27 @@ struct dngvd_op { }; -template -struct dnevx_op { + template + struct dnevx_op { + using Real = typename GetTypeReal::type; void operator()( const psi::DEVICE_CPU* /*ctx*/, const int nstart, const int ldh, - const std::complex* hcc, // hcc + const T* hcc, // hcc const int nbands, // nbands - FPTYPE* eigenvalue, // eigenvalue - std::complex* vcc) // vcc + Real* eigenvalue, // eigenvalue + T* vcc) // vcc { - std::complex* aux = new std::complex[nstart * ldh]; + T* aux = new T[nstart * ldh]; for (int ii = 0; ii < nstart * ldh; ii++) { aux[ii] = hcc[ii]; } int info = 0; int lwork = -1; - std::complex *work = new std::complex[1]; - FPTYPE *rwork = new FPTYPE[7 * nstart]; + T* work = new T[1]; + Real* rwork = new Real[7 * nstart]; int *iwork = new int[5 * nstart]; int *ifail = new int[nstart]; @@ -98,8 +113,8 @@ struct dnevx_op { info); - lwork = int(work[0].real()); - delete[] work; work = new std::complex[lwork]; + lwork = int(get_real(work[0])); + delete[] work; work = new T[lwork]; // The A and B storage space is (nstart * ldh), and the data that really participates in the zhegvx // operation is (nstart * nstart). In this function, the data that A and B participate in the operation will @@ -142,10 +157,13 @@ struct dnevx_op { }; -template struct dngvd_op; -template struct dngvd_op; - -template struct dnevx_op; -template struct dnevx_op; + template struct dngvd_op, psi::DEVICE_CPU>; + template struct dngvd_op, psi::DEVICE_CPU>; + template struct dnevx_op , psi::DEVICE_CPU >; + template struct dnevx_op, psi::DEVICE_CPU>; +#ifdef __LCAO + template struct dngvd_op; + template struct dnevx_op ; +#endif } // namespace hsolver \ No newline at end of file diff --git a/source/module_hsolver/kernels/dngvd_op.h b/source/module_hsolver/kernels/dngvd_op.h index df8e848e22e..23d58550872 100644 --- a/source/module_hsolver/kernels/dngvd_op.h +++ b/source/module_hsolver/kernels/dngvd_op.h @@ -11,9 +11,10 @@ namespace hsolver { -template struct dngvd_op -{ - /// @brief DNGVD computes all the eigenvalues and eigenvectors of a complex generalized + template struct dngvd_op + { + using Real = typename GetTypeReal::type; + /// @brief DNGVD computes all the eigenvalues and eigenvectors of a complex generalized /// Hermitian-definite eigenproblem. If eigenvectors are desired, it uses a divide and conquer algorithm. /// /// In this op, the CPU version is implemented through the `gvd` interface, and the CUDA version @@ -31,18 +32,19 @@ template struct dngvd_op /// Output Parameter /// @param W : calculated eigenvalues /// @param V : calculated eigenvectors (col major) - void operator()(const Device* d, - const int nstart, - const int ldh, - const std::complex* A, - const std::complex* B, - FPTYPE* W, - std::complex* V); + void operator()(const Device* d, + const int nstart, + const int ldh, + const T* A, + const T* B, + Real* W, + T* V); }; -template struct dnevx_op + template struct dnevx_op { + using Real = typename GetTypeReal::type; /// @brief DNEVX computes the first m eigenvalues and their corresponding eigenvectors of /// a complex generalized Hermitian-definite eigenproblem /// @@ -61,12 +63,12 @@ template struct dnevx_op /// @param W : calculated eigenvalues /// @param V : calculated eigenvectors (row major) void operator()(const Device* d, - const int nstart, - const int ldh, - const std::complex* A, - const int m, - FPTYPE* W, - std::complex* V); + const int nstart, + const int ldh, + const T* A, + const int m, + Real* W, + T* V); }; diff --git a/source/module_hsolver/kernels/math_kernel_op.cpp b/source/module_hsolver/kernels/math_kernel_op.cpp index 4fd56726e7b..2d3d44c78cb 100644 --- a/source/module_hsolver/kernels/math_kernel_op.cpp +++ b/source/module_hsolver/kernels/math_kernel_op.cpp @@ -92,9 +92,26 @@ struct calc_grad_with_block_op { } }; +template +struct dot_real_op { + FPTYPE operator() ( + const psi::DEVICE_CPU* d, + const int& dim, + const FPTYPE* psi_L, + const FPTYPE* psi_R, + const bool reduce) + { + FPTYPE result = BlasConnector::dot(dim, psi_L, 1, psi_R, 1); + if (reduce) { + Parallel_Reduce::reduce_pool(result); + } + return result; + } +}; + // CPU specialization of actual computation. template -struct zdot_real_op { +struct dot_real_op, psi::DEVICE_CPU> { FPTYPE operator() ( const psi::DEVICE_CPU* d, const int& dim, @@ -109,22 +126,23 @@ struct zdot_real_op { const FPTYPE* pR = reinterpret_cast(psi_R); FPTYPE result = BlasConnector::dot(2 * dim, pL, 1, pR, 1); if (reduce) { - Parallel_Reduce::reduce_double_pool(result); + Parallel_Reduce::reduce_pool(result); } return result; } }; -template struct vector_div_constant_op +template struct vector_div_constant_op { + using Real = typename GetTypeReal::type; void operator()(const psi::DEVICE_CPU* d, - const int dim, - std::complex* result, - const std::complex* vector, - const FPTYPE constant) + const int dim, + T* result, + const T* vector, + const Real constant) { #ifdef _OPENMP -#pragma omp parallel for schedule(static, 4096/sizeof(FPTYPE)) +#pragma omp parallel for schedule(static, 4096/sizeof(Real)) #endif for (int i = 0; i < dim; i++) { @@ -133,16 +151,17 @@ template struct vector_div_constant_op struct vector_mul_vector_op +template struct vector_mul_vector_op { + using Real = typename GetTypeReal::type; void operator()(const psi::DEVICE_CPU* d, - const int& dim, - std::complex* result, - const std::complex* vector1, - const FPTYPE* vector2) + const int& dim, + T* result, + const T* vector1, + const Real* vector2) { #ifdef _OPENMP -#pragma omp parallel for schedule(static, 4096/sizeof(FPTYPE)) +#pragma omp parallel for schedule(static, 4096/sizeof(Real)) #endif for (int i = 0; i < dim; i++) { @@ -151,16 +170,17 @@ template struct vector_mul_vector_op } }; -template struct vector_div_vector_op +template struct vector_div_vector_op { + using Real = typename GetTypeReal::type; void operator()(const psi::DEVICE_CPU* d, const int& dim, - std::complex* result, - const std::complex* vector1, - const FPTYPE* vector2) + T* result, + const T* vector1, + const Real* vector2) { #ifdef _OPENMP -#pragma omp parallel for schedule(static, 4096/sizeof(FPTYPE)) +#pragma omp parallel for schedule(static, 4096/sizeof(Real)) #endif for (int i = 0; i < dim; i++) { @@ -202,21 +222,21 @@ struct scal_op { } }; -template -struct gemv_op { +template +struct gemv_op { void operator()( - const psi::DEVICE_CPU *d, - const char &trans, - const int &m, - const int &n, - const std::complex *alpha, - const std::complex *A, - const int &lda, - const std::complex *X, - const int &incx, - const std::complex *beta, - std::complex *Y, - const int &incy) + const psi::DEVICE_CPU* d, + const char& trans, + const int& m, + const int& n, + const T* alpha, + const T* A, + const int& lda, + const T* X, + const int& incx, + const T* beta, + T* Y, + const int& incy) { BlasConnector::gemv(trans, m, n, *alpha, A, lda, X, incx, *beta, Y, incy); } @@ -237,40 +257,40 @@ struct axpy_op { } }; -template -struct gemm_op { +template +struct gemm_op { void operator()( - const psi::DEVICE_CPU * /*ctx*/, - const char &transa, - const char &transb, - const int &m, - const int &n, - const int &k, - const std::complex *alpha, - const std::complex *a, - const int &lda, - const std::complex *b, - const int &ldb, - const std::complex *beta, - std::complex *c, - const int &ldc) + const psi::DEVICE_CPU* /*ctx*/, + const char& transa, + const char& transb, + const int& m, + const int& n, + const int& k, + const T* alpha, + const T* a, + const int& lda, + const T* b, + const int& ldb, + const T* beta, + T* c, + const int& ldc) { BlasConnector::gemm(transb, transa, n, m, k, *alpha, b, ldb, a, lda, *beta, c, ldc); } }; -template struct matrixTranspose_op +template struct matrixTranspose_op { void operator()(const psi::DEVICE_CPU* d, - const int& row, - const int& col, - const std::complex* input_matrix, - std::complex* output_matrix) + const int& row, + const int& col, + const T* input_matrix, + T* output_matrix) { - std::complex* temp = nullptr; - psi::memory::resize_memory_op, psi::DEVICE_CPU>()(d, temp, row * col, "MTransOp"); + T* temp = nullptr; + psi::memory::resize_memory_op()(d, temp, row * col, "MTransOp"); #ifdef _OPENMP -#pragma omp parallel for collapse(2) schedule(static, 4096/sizeof(FPTYPE)) +#pragma omp parallel for collapse(2) schedule(static, 8192/sizeof(T)) #endif for (int j = 0; j < col; j++) { @@ -280,27 +300,27 @@ template struct matrixTranspose_op } } #ifdef _OPENMP -#pragma omp parallel for schedule(static, 4096/sizeof(FPTYPE)) +#pragma omp parallel for schedule(static, 8192/sizeof(T)) #endif for (int i = 0; i < row * col; i++) { output_matrix[i] = temp[i]; } - psi::memory::delete_memory_op, psi::DEVICE_CPU>()(d, temp); + psi::memory::delete_memory_op()(d, temp); } }; -template struct matrixSetToAnother +template struct matrixSetToAnother { void operator()(const psi::DEVICE_CPU* d, - const int& n, - const std::complex* A, - const int& LDA, - std::complex* B, - const int& LDB) + const int& n, + const T* A, + const int& LDA, + T* B, + const int& LDB) { #ifdef _OPENMP -#pragma omp parallel for collapse(2) schedule(static, 4096/sizeof(FPTYPE)) +#pragma omp parallel for collapse(2) schedule(static, 8192/sizeof(T)) #endif for (int i = 0; i < n; i++) { @@ -317,29 +337,40 @@ template struct matrixSetToAnother // Explicitly instantiate functors for the types of functor registered. template struct scal_op; template struct axpy_op; -template struct gemv_op; -template struct gemm_op; -template struct zdot_real_op; -template struct vector_div_constant_op; -template struct vector_mul_vector_op; -template struct vector_div_vector_op; +template struct gemv_op, psi::DEVICE_CPU>; +template struct gemm_op, psi::DEVICE_CPU>; +template struct dot_real_op, psi::DEVICE_CPU>; +template struct vector_div_constant_op, psi::DEVICE_CPU>; +template struct vector_mul_vector_op, psi::DEVICE_CPU>; +template struct vector_div_vector_op, psi::DEVICE_CPU>; template struct constantvector_addORsub_constantVector_op; -template struct matrixTranspose_op; -template struct matrixSetToAnother; +template struct matrixTranspose_op, psi::DEVICE_CPU>; +template struct matrixSetToAnother, psi::DEVICE_CPU>; template struct calc_grad_with_block_op, psi::DEVICE_CPU>; template struct line_minimize_with_block_op, psi::DEVICE_CPU>; template struct scal_op; template struct axpy_op; +template struct gemv_op, psi::DEVICE_CPU>; +template struct gemm_op, psi::DEVICE_CPU>; +template struct dot_real_op, psi::DEVICE_CPU>; +template struct vector_div_constant_op, psi::DEVICE_CPU>; +template struct vector_mul_vector_op, psi::DEVICE_CPU>; +template struct vector_div_vector_op, psi::DEVICE_CPU>; +template struct constantvector_addORsub_constantVector_op; +template struct matrixTranspose_op, psi::DEVICE_CPU>; +template struct matrixSetToAnother, psi::DEVICE_CPU>; +template struct calc_grad_with_block_op, psi::DEVICE_CPU>; +template struct line_minimize_with_block_op, psi::DEVICE_CPU>; + +#ifdef __LCAO template struct gemv_op; template struct gemm_op; -template struct zdot_real_op; -template struct vector_div_constant_op; +template struct dot_real_op; template struct vector_mul_vector_op; +template struct vector_div_constant_op; template struct vector_div_vector_op; -template struct constantvector_addORsub_constantVector_op; template struct matrixTranspose_op; template struct matrixSetToAnother; -template struct calc_grad_with_block_op, psi::DEVICE_CPU>; -template struct line_minimize_with_block_op, psi::DEVICE_CPU>; +#endif } // namespace hsolver \ No newline at end of file diff --git a/source/module_hsolver/kernels/math_kernel_op.h b/source/module_hsolver/kernels/math_kernel_op.h index 0235649e3f0..1bff8dfa858 100644 --- a/source/module_hsolver/kernels/math_kernel_op.h +++ b/source/module_hsolver/kernels/math_kernel_op.h @@ -58,7 +58,7 @@ namespace hsolver template struct line_minimize_with_block_op { - /// @brief zdot_real_op computes the dot product of the given complex arrays(treated as float arrays). + /// @brief dot_real_op computes the dot product of the given complex arrays(treated as float arrays). /// And there's may have MPI communications while enabling planewave parallization strategy. /// /// Input Parameters @@ -83,7 +83,7 @@ struct line_minimize_with_block_op { template struct calc_grad_with_block_op { - /// @brief zdot_real_op computes the dot product of the given complex arrays(treated as float arrays). + /// @brief dot_real_op computes the dot product of the given complex arrays(treated as float arrays). /// And there's may have MPI communications while enabling planewave parallization strategy. /// /// Input Parameters @@ -109,9 +109,10 @@ struct calc_grad_with_block_op { const int &n_band); }; -template -struct zdot_real_op { - /// @brief zdot_real_op computes the dot product of the given complex arrays(treated as float arrays). +template +struct dot_real_op { + using Real = typename GetTypeReal::type; + /// @brief dot_real_op computes the dot product of the given complex arrays(treated as float arrays). /// And there's may have MPI communications while enabling planewave parallization strategy. /// /// Input Parameters @@ -123,17 +124,18 @@ struct zdot_real_op { /// /// \return /// FPTYPE : dot product result - FPTYPE operator() ( + Real operator() ( const Device* d, const int& dim, - const std::complex* psi_L, - const std::complex* psi_R, + const T* psi_L, + const T* psi_R, const bool reduce = true); }; // vector operator: result[i] = vector[i] / constant -template struct vector_div_constant_op +template struct vector_div_constant_op { + using Real = typename GetTypeReal::type; /// @brief result[i] = vector[i] / constant /// /// Input Parameters @@ -146,9 +148,9 @@ template struct vector_div_constant_op /// \param result : output array void operator()(const Device* d, const int dim, - std::complex* result, - const std::complex* vector, - const FPTYPE constant); + T* result, + const T* vector, + const Real constant); }; // replace vector_div_constant_op : x = alpha * x @@ -173,8 +175,9 @@ template struct scal_op }; // vector operator: result[i] = vector1[i](complex) * vector2[i](not complex) -template struct vector_mul_vector_op +template struct vector_mul_vector_op { + using Real = typename GetTypeReal::type; /// @brief result[i] = vector1[i](complex) * vector2[i](not complex) /// /// Input Parameters @@ -186,15 +189,16 @@ template struct vector_mul_vector_op /// Output Parameters /// \param result : output array void operator()(const Device* d, - const int& dim, - std::complex* result, - const std::complex* vector1, - const FPTYPE* vector2); + const int& dim, + T* result, + const T* vector1, + const Real* vector2); }; // vector operator: result[i] = vector1[i](complex) / vector2[i](not complex) -template struct vector_div_vector_op +template struct vector_div_vector_op { + using Real = typename GetTypeReal::type; /// @brief result[i] = vector1[i](complex) / vector2[i](not complex) /// /// Input Parameters @@ -206,10 +210,10 @@ template struct vector_div_vector_op /// Output Parameters /// \param result : output array void operator()(const Device* d, - const int& dim, - std::complex* result, - const std::complex* vector1, - const FPTYPE* vector2); + const int& dim, + T* result, + const T* vector1, + const Real* vector2); }; // vector operator: result[i] = vector1[i] * constant1 + vector2[i] * constant2 @@ -262,7 +266,7 @@ template struct axpy_op }; // compute y = alpha * op(A) * x + beta * y -template struct gemv_op +template struct gemv_op { /// @brief y = alpha * op(A) * x + beta * y /// @@ -286,19 +290,19 @@ template struct gemv_op const char& trans, const int& m, const int& n, - const std::complex* alpha, - const std::complex* A, + const T* alpha, + const T* A, const int& lda, - const std::complex* X, + const T* X, const int& incx, - const std::complex* beta, - std::complex* Y, + const T* beta, + T* Y, const int& incy); }; // compute C = alpha * op(A) * op(B) + beta * C -template struct gemm_op +template struct gemm_op { /// @brief C = alpha * op(A) * op(B) + beta * C /// @@ -321,22 +325,22 @@ template struct gemm_op /// Output Parameters /// \param c : output matrix C void operator()(const Device* d, - const char& transa, - const char& transb, - const int& m, - const int& n, - const int& k, - const std::complex *alpha, - const std::complex *a, - const int& lda, - const std::complex *b, - const int& ldb, - const std::complex *beta, - std::complex *c, - const int& ldc); + const char& transa, + const char& transb, + const int& m, + const int& n, + const int& k, + const T* alpha, + const T* a, + const int& lda, + const T* b, + const int& ldb, + const T* beta, + T* c, + const int& ldc); }; -template struct matrixTranspose_op +template struct matrixTranspose_op { /// @brief transpose the input matrix /// @@ -349,13 +353,13 @@ template struct matrixTranspose_op /// Output Parameters /// \param output_matrix : output matrix void operator()(const Device* d, - const int& row, - const int& col, - const std::complex* input_matrix, - std::complex* output_matrix); + const int& row, + const int& col, + const T* input_matrix, + T* output_matrix); }; -template struct matrixSetToAnother +template struct matrixSetToAnother { /// @brief initialize matrix B with A /// @@ -369,11 +373,11 @@ template struct matrixSetToAnother /// Output Parameters /// \param B : output matrix B void operator()(const Device* d, - const int& n, - const std::complex* A, - const int& LDA, - std::complex* B, - const int& LDB); + const int& n, + const T* A, + const int& LDA, + T* B, + const int& LDB); }; #if __CUDA || __UT_USE_CUDA || __ROCM || __UT_USE_ROCM @@ -408,44 +412,48 @@ struct calc_grad_with_block_op { }; // Partially specialize functor for psi::GpuDevice. -template -struct zdot_real_op { - FPTYPE operator()( - const psi::DEVICE_GPU* d, - const int& dim, - const std::complex* psi_L, - const std::complex* psi_R, - const bool reduce = true); +template +struct dot_real_op { + using Real = typename GetTypeReal::type; + Real operator()( + const psi::DEVICE_GPU* d, + const int& dim, + const T* psi_L, + const T* psi_R, + const bool reduce = true); }; // vector operator: result[i] = vector[i] / constant -template struct vector_div_constant_op +template struct vector_div_constant_op { + using Real = typename GetTypeReal::type; void operator()(const psi::DEVICE_GPU* d, - const int dim, - std::complex* result, - const std::complex* vector, - const FPTYPE constant); + const int dim, + T* result, + const T* vector, + const Real constant); }; // vector operator: result[i] = vector1[i](complex) * vector2[i](not complex) -template struct vector_mul_vector_op +template struct vector_mul_vector_op { + using Real = typename GetTypeReal::type; void operator()(const psi::DEVICE_GPU* d, - const int& dim, - std::complex* result, - const std::complex* vector1, - const FPTYPE* vector2); + const int& dim, + T* result, + const T* vector1, + const Real* vector2); }; // vector operator: result[i] = vector1[i](complex) / vector2[i](not complex) -template struct vector_div_vector_op +template struct vector_div_vector_op { + using Real = typename GetTypeReal::type; void operator()(const psi::DEVICE_GPU* d, - const int& dim, - std::complex* result, - const std::complex* vector1, - const FPTYPE* vector2); + const int& dim, + T* result, + const T* vector1, + const Real* vector2); }; // vector operator: result[i] = vector1[i] * constant1 + vector2[i] * constant2 @@ -460,14 +468,14 @@ template struct constantvector_addORsub_constantVector_op struct matrixSetToAnother +template struct matrixSetToAnother { void operator()(const psi::DEVICE_GPU* d, - const int& n, - const std::complex* A, // input - const int& LDA, - std::complex* B, // output - const int& LDB); + const int& n, + const T* A, // input + const int& LDA, + T* B, // output + const int& LDB); }; diff --git a/source/module_hsolver/kernels/rocm/dngvd_op.hip.cu b/source/module_hsolver/kernels/rocm/dngvd_op.hip.cu index 1583f3431fd..1872fbdd2e8 100644 --- a/source/module_hsolver/kernels/rocm/dngvd_op.hip.cu +++ b/source/module_hsolver/kernels/rocm/dngvd_op.hip.cu @@ -13,7 +13,28 @@ void destroyGpuSolverHandle() { } template <> -void dngvd_op::operator()(const psi::DEVICE_GPU* ctx, +void dngvd_op::operator()(const psi::DEVICE_GPU* ctx, + const int nstart, + const int ldh, + const double* _hcc, + const double* _scc, + double* _eigenvalue, + double* _vcc) +{ + std::vector hcc(nstart * nstart, 0.0); + std::vector scc(nstart * nstart, 0.0); + std::vector vcc(nstart * nstart, 0.0); + std::vector eigenvalue(nstart, 0); + hipMemcpy(hcc.data(), _hcc, sizeof(double) * hcc.size(), hipMemcpyDeviceToHost); + hipMemcpy(scc.data(), _scc, sizeof(double) * scc.size(), hipMemcpyDeviceToHost); + psi::DEVICE_CPU* cpu_ctx = {}; + dngvd_op()(cpu_ctx, nstart, ldh, hcc.data(), scc.data(), eigenvalue.data(), vcc.data()); + hipMemcpy(_vcc, vcc.data(), sizeof(double) * vcc.size(), hipMemcpyHostToDevice); + hipMemcpy(_eigenvalue, eigenvalue.data(), sizeof(double) * eigenvalue.size(), hipMemcpyHostToDevice); +} + +template <> +void dngvd_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* ctx, const int nstart, const int ldh, const std::complex* _hcc, @@ -28,13 +49,13 @@ void dngvd_op::operator()(const psi::DEVICE_GPU* ctx, hipMemcpy(hcc.data(), _hcc, sizeof(std::complex) * hcc.size(), hipMemcpyDeviceToHost); hipMemcpy(scc.data(), _scc, sizeof(std::complex) * scc.size(), hipMemcpyDeviceToHost); psi::DEVICE_CPU * cpu_ctx = {}; - dngvd_op()(cpu_ctx, nstart, ldh, hcc.data(), scc.data(), eigenvalue.data(), vcc.data()); + dngvd_op, psi::DEVICE_CPU>()(cpu_ctx, nstart, ldh, hcc.data(), scc.data(), eigenvalue.data(), vcc.data()); hipMemcpy(_vcc, vcc.data(), sizeof(std::complex) * vcc.size(), hipMemcpyHostToDevice); hipMemcpy(_eigenvalue, eigenvalue.data(), sizeof(float) * eigenvalue.size(), hipMemcpyHostToDevice); } template <> -void dngvd_op::operator()(const psi::DEVICE_GPU* ctx, +void dngvd_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* ctx, const int nstart, const int ldh, const std::complex* _hcc, @@ -49,14 +70,32 @@ void dngvd_op::operator()(const psi::DEVICE_GPU* ctx, hipMemcpy(hcc.data(), _hcc, sizeof(std::complex) * hcc.size(), hipMemcpyDeviceToHost); hipMemcpy(scc.data(), _scc, sizeof(std::complex) * scc.size(), hipMemcpyDeviceToHost); psi::DEVICE_CPU * cpu_ctx = {}; - dngvd_op()(cpu_ctx, nstart, ldh, hcc.data(), scc.data(), eigenvalue.data(), vcc.data()); + dngvd_op, psi::DEVICE_CPU>()(cpu_ctx, nstart, ldh, hcc.data(), scc.data(), eigenvalue.data(), vcc.data()); hipMemcpy(_vcc, vcc.data(), sizeof(std::complex) * vcc.size(), hipMemcpyHostToDevice); hipMemcpy(_eigenvalue, eigenvalue.data(), sizeof(double) * eigenvalue.size(), hipMemcpyHostToDevice); } +template <> +void dnevx_op::operator()(const psi::DEVICE_GPU* ctx, + const int nstart, + const int ldh, + const double* _hcc, + const int m, + double* _eigenvalue, + double* _vcc) +{ + std::vector hcc(ldh * ldh, 0.0); + std::vector vcc(ldh * ldh, 0.0); + std::vector eigenvalue(ldh, 0); + hipMemcpy(hcc.data(), _hcc, sizeof(double) * hcc.size(), hipMemcpyDeviceToHost); + psi::DEVICE_CPU* cpu_ctx = {}; + dnevx_op()(cpu_ctx, nstart, ldh, hcc.data(), m, eigenvalue.data(), vcc.data()); + hipMemcpy(_vcc, vcc.data(), sizeof(double) * vcc.size(), hipMemcpyHostToDevice); + hipMemcpy(_eigenvalue, eigenvalue.data(), sizeof(double) * eigenvalue.size(), hipMemcpyHostToDevice); +} template <> -void dnevx_op::operator()(const psi::DEVICE_GPU* ctx, +void dnevx_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* ctx, const int nstart, const int ldh, const std::complex* _hcc, @@ -69,13 +108,13 @@ void dnevx_op::operator()(const psi::DEVICE_GPU* ctx, std::vector eigenvalue(ldh, 0); hipMemcpy(hcc.data(), _hcc, sizeof(std::complex) * hcc.size(), hipMemcpyDeviceToHost); psi::DEVICE_CPU * cpu_ctx = {}; - dnevx_op()(cpu_ctx, nstart, ldh, hcc.data(), m, eigenvalue.data(), vcc.data()); + dnevx_op, psi::DEVICE_CPU>()(cpu_ctx, nstart, ldh, hcc.data(), m, eigenvalue.data(), vcc.data()); hipMemcpy(_vcc, vcc.data(), sizeof(std::complex) * vcc.size(), hipMemcpyHostToDevice); hipMemcpy(_eigenvalue, eigenvalue.data(), sizeof(float) * eigenvalue.size(), hipMemcpyHostToDevice); } template <> -void dnevx_op::operator()(const psi::DEVICE_GPU* ctx, +void dnevx_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* ctx, const int nstart, const int ldh, const std::complex* _hcc, @@ -88,7 +127,7 @@ void dnevx_op::operator()(const psi::DEVICE_GPU* ctx, std::vector eigenvalue(ldh, 0); hipMemcpy(hcc.data(), _hcc, sizeof(std::complex) * hcc.size(), hipMemcpyDeviceToHost); psi::DEVICE_CPU * cpu_ctx = {}; - dnevx_op()(cpu_ctx, nstart, ldh, hcc.data(), m, eigenvalue.data(), vcc.data()); + dnevx_op, psi::DEVICE_CPU>()(cpu_ctx, nstart, ldh, hcc.data(), m, eigenvalue.data(), vcc.data()); hipMemcpy(_vcc, vcc.data(), sizeof(std::complex) * vcc.size(), hipMemcpyHostToDevice); hipMemcpy(_eigenvalue, eigenvalue.data(), sizeof(double) * eigenvalue.size(), hipMemcpyHostToDevice); } diff --git a/source/module_hsolver/kernels/rocm/math_kernel_op.hip.cu b/source/module_hsolver/kernels/rocm/math_kernel_op.hip.cu index 036fa479789..8ea97f3742f 100644 --- a/source/module_hsolver/kernels/rocm/math_kernel_op.hip.cu +++ b/source/module_hsolver/kernels/rocm/math_kernel_op.hip.cu @@ -203,13 +203,13 @@ __global__ void calc_grad_with_block( } // Define the CUDA kernel: -template +template __launch_bounds__(1024) __global__ void vector_div_constant_kernel( const int size, - thrust::complex* result, - const thrust::complex* vector, - const FPTYPE constant) + T* result, + const T* vector, + const typename GetTypeReal::type constant) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < size) @@ -218,13 +218,13 @@ __global__ void vector_div_constant_kernel( } } -template +template __launch_bounds__(1024) __global__ void vector_mul_vector_kernel( const int size, - thrust::complex* result, - const thrust::complex* vector1, - const FPTYPE* vector2) + T* result, + const T* vector1, + const typename GetTypeReal::type* vector2) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < size) @@ -233,13 +233,13 @@ __global__ void vector_mul_vector_kernel( } } -template +template __launch_bounds__(1024) __global__ void vector_div_vector_kernel( const int size, - thrust::complex* result, - const thrust::complex* vector1, - const FPTYPE* vector2) + T* result, + const T* vector1, + const typename GetTypeReal::type* vector2) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < size) @@ -265,13 +265,13 @@ __global__ void constantvector_addORsub_constantVector_kernel( } } -template +template __launch_bounds__(1024) __global__ void matrix_transpose_kernel( const int row, const int col, - const thrust::complex* in, - thrust::complex* out) + const T* in, + T* out) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < row) @@ -284,14 +284,14 @@ __global__ void matrix_transpose_kernel( } -template +template __launch_bounds__(1024) __global__ void matrix_setTo_another_kernel( const int n, const int LDA, const int LDB, - const thrust::complex* matrix_A, - thrust::complex* matrix_B) + const T* matrix_A, + T* matrix_B) { int j = blockIdx.x * blockDim.x + threadIdx.x; if (j < LDA && j < LDB) @@ -347,33 +347,81 @@ void calc_grad_with_block_op::operator()( n_basis, n_basis_max); } +template <> +double dot_real_op::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + const double* psi_L, + const double* psi_R, + const bool reduce) +{ + double result = 0.0; + xdot_wrapper(dim, psi_L, 1, psi_R, 1, result); + if (reduce) { + Parallel_Reduce::reduce_pool(result); + } + return result; +} + // for this implementation, please check // https://thrust.github.io/doc/group__transformed__reductions_ga321192d85c5f510e52300ae762c7e995.html denghui modify // 2022-10-03 Note that ddot_(2*dim,a,1, b,1) = REAL( zdotc_(dim,a,1,b,1) ) GPU specialization of actual computation. template -FPTYPE zdot_real_op::operator()( +inline FPTYPE dot_complex_wrapper( const psi::DEVICE_GPU* d, const int& dim, const std::complex* psi_L, const std::complex* psi_R, const bool reduce) { - //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - // denghui modify 2022-10-07 - // Note that ddot_(2*dim,a,1,b,1) = REAL( zdotc_(dim,a,1,b,1) ) - const FPTYPE* pL = reinterpret_cast(psi_L); - const FPTYPE* pR = reinterpret_cast(psi_R); - FPTYPE result = 0.0; - xdot_wrapper(dim * 2, pL, 1, pR, 1, result); - if (reduce) { - Parallel_Reduce::reduce_double_pool(result); - } - return result; + //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // denghui modify 2022-10-07 + // Note that ddot_(2*dim,a,1,b,1) = REAL( zdotc_(dim,a,1,b,1) ) + const FPTYPE* pL = reinterpret_cast(psi_L); + const FPTYPE* pR = reinterpret_cast(psi_R); + FPTYPE result = 0.0; + xdot_wrapper(dim * 2, pL, 1, pR, 1, result); + if (reduce) { + Parallel_Reduce::reduce_pool(result); + } + return result; +} +template <> +float dot_real_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + const std::complex* psi_L, + const std::complex* psi_R, + const bool reduce) +{ + return dot_complex_wrapper(d, dim, psi_L, psi_R, reduce); +} +template <> +double dot_real_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + const std::complex* psi_L, + const std::complex* psi_R, + const bool reduce) +{ + return dot_complex_wrapper(d, dim, psi_L, psi_R, reduce); } +template <> +void vector_div_constant_op::operator()( + const psi::DEVICE_GPU* d, + const int dim, + double* result, + const double* vector, + const double constant) +{ + int thread = 1024; + int block = (dim + thread - 1) / thread; + hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_div_constant_kernel), dim3(block), dim3(thread), 0, 0, dim, result, vector, constant); +} // vector operator: result[i] = vector[i] / constant template -void vector_div_constant_op::operator()( +inline void vector_div_constant_complex_wrapper( const psi::DEVICE_GPU* d, const int dim, std::complex* result, @@ -382,15 +430,47 @@ void vector_div_constant_op::operator()( { thrust::complex* result_tmp = reinterpret_cast*>(result); const thrust::complex* vector_tmp = reinterpret_cast*>(vector); - int thread = 1024; int block = (dim + thread - 1) / thread; - hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_div_constant_kernel), dim3(block), dim3(thread), 0, 0, dim, result_tmp, vector_tmp, constant); + hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_div_constant_kernel>), dim3(block), dim3(thread), 0, 0, dim, result_tmp, vector_tmp, constant); +} +template <> +void vector_div_constant_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int dim, + std::complex* result, + const std::complex* vector, + const float constant) +{ + vector_div_constant_complex_wrapper(d, dim, result, vector, constant); +} +template <> +void vector_div_constant_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int dim, + std::complex* result, + const std::complex* vector, + const double constant) +{ + vector_div_constant_complex_wrapper(d, dim, result, vector, constant); +} +// vector operator: result[i] = vector1[i](not complex) * vector2[i](not complex) +template <> +void vector_mul_vector_op::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + double* result, + const double* vector1, + const double* vector2) +{ + int thread = 1024; + int block = (dim + thread - 1) / thread; + hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_mul_vector_kernel), dim3(block), dim3(thread), 0, 0, dim, result, vector1, vector2); } // vector operator: result[i] = vector1[i](complex) * vector2[i](not complex) -template -void vector_mul_vector_op::operator()( +template +inline void vector_mul_vector_complex_wrapper( const psi::DEVICE_GPU* d, const int& dim, std::complex* result, @@ -399,16 +479,46 @@ void vector_mul_vector_op::operator()( { thrust::complex* result_tmp = reinterpret_cast*>(result); const thrust::complex* vector1_tmp = reinterpret_cast*>(vector1); - int thread = 1024; int block = (dim + thread - 1) / thread; - hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_mul_vector_kernel), dim3(block), dim3(thread), 0, 0, dim, result_tmp, vector1_tmp, vector2); + hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_mul_vector_kernel>), dim3(block), dim3(thread), 0, 0, dim, result_tmp, vector1_tmp, vector2); +} +template <> +void vector_mul_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const float* vector2) +{ + vector_mul_vector_complex_wrapper(d, dim, result, vector1, vector2); +} +template <> +void vector_mul_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const double* vector2) +{ + vector_mul_vector_complex_wrapper(d, dim, result, vector1, vector2); +} +// vector operator: result[i] = vector1[i](complex) / vector2[i](not complex) +template <> +void vector_div_vector_op::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + double* result, + const double* vector1, + const double* vector2) +{ + int thread = 1024; + int block = (dim + thread - 1) / thread; + hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_div_vector_kernel), dim3(block), dim3(thread), 0, 0, dim, result, vector1, vector2); } - - // vector operator: result[i] = vector1[i](complex) / vector2[i](not complex) template -void vector_div_vector_op::operator()( +inline void vector_div_vector_op_complex_wrapper( const psi::DEVICE_GPU* d, const int& dim, std::complex* result, @@ -417,10 +527,29 @@ void vector_div_vector_op::operator()( { thrust::complex* result_tmp = reinterpret_cast*>(result); const thrust::complex* vector1_tmp = reinterpret_cast*>(vector1); - int thread = 1024; int block = (dim + thread - 1) / thread; - hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_div_vector_kernel), dim3(block), dim3(thread), 0, 0, dim, result_tmp, vector1_tmp, vector2); + hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_div_vector_kernel>), dim3(block), dim3(thread), 0, 0, dim, result_tmp, vector1_tmp, vector2); +} +template <> +void vector_div_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const float* vector2) +{ + vector_div_vector_op_complex_wrapper(d, dim, result, vector1, vector2); +} +template <> +void vector_div_vector_op, psi::DEVICE_GPU>::operator()( + const psi::DEVICE_GPU* d, + const int& dim, + std::complex* result, + const std::complex* vector1, + const double* vector2) +{ + vector_div_vector_op_complex_wrapper(d, dim, result, vector1, vector2); } // vector operator: result[i] = vector1[i] * constant1 + vector2[i] * constant2 @@ -469,8 +598,36 @@ void axpy_op::operator()( hipblasZaxpy(cublas_handle, N, (hipblasDoubleComplex*)alpha, (hipblasDoubleComplex*)X, incX, (hipblasDoubleComplex*)Y, incY); } -template <> -void gemv_op::operator()( +template <> +void gemv_op::operator()( + const psi::DEVICE_GPU* d, + const char& trans, + const int& m, + const int& n, + const double* alpha, + const double* A, + const int& lda, + const double* X, + const int& incx, + const double* beta, + double* Y, + const int& incy) +{ + hipblasOperation_t cutrans = {}; + if (trans == 'N') { + cutrans = HIPBLAS_OP_N; + } + else if (trans == 'T') { + cutrans = HIPBLAS_OP_T; + } + else if (trans == 'C') { + cutrans = HIPBLAS_OP_C; + } + hipblasZgemv(cublas_handle, cutrans, m, n, alpha, A, lda, X, incx, beta, Y, incx); +} + +template <> +void gemv_op, psi::DEVICE_GPU>::operator()( const psi::DEVICE_GPU* d, const char& trans, const int& m, @@ -491,14 +648,11 @@ void gemv_op::operator()( else if (trans == 'T'){ cutrans = HIPBLAS_OP_T; } - else if (trans == 'C'){ - cutrans = HIPBLAS_OP_C; - } - hipblasCgemv(cublas_handle, cutrans, m, n, (hipblasComplex*)alpha, (hipblasComplex*)A, lda, (hipblasComplex*)X, incx, (hipblasComplex*)beta, (hipblasComplex*)Y, incx); + hipblasDgemv(cublas_handle, cutrans, m, n, alpha, A, lda, X, incx, beta, Y, incx); } template <> -void gemv_op::operator()( +void gemv_op, psi::DEVICE_GPU>::operator()( const psi::DEVICE_GPU* d, const char& trans, const int& m, @@ -545,9 +699,43 @@ void scal_op::operator()(const psi::DEVICE_GPU* d, hipblasZscal(cublas_handle, N, (hipblasDoubleComplex*)alpha, (hipblasDoubleComplex*)X, incx); } +template <> +void gemm_op::operator()(const psi::DEVICE_GPU* d, + const char& transa, + const char& transb, + const int& m, + const int& n, + const int& k, + const double* alpha, + const double* a, + const int& lda, + const double* b, + const int& ldb, + const double* beta, + double* c, + const int& ldc) +{ + hipblasOperation_t cutransA; + hipblasOperation_t cutransB; + // cutransA + if (transa == 'N') { + cutransA = HIPBLAS_OP_N; + } + else if (transa == 'T') { + cutransA = HIPBLAS_OP_T; + } + // cutransB + if (transb == 'N') { + cutransB = HIPBLAS_OP_N; + } + else if (transb == 'T') { + cutransB = HIPBLAS_OP_T; + } + hipblasDgemm(cublas_handle, cutransA, cutransB, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc); +} template <> -void gemm_op::operator()(const psi::DEVICE_GPU* d, +void gemm_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const char& transa, const char& transb, const int& m, @@ -588,7 +776,7 @@ void gemm_op::operator()(const psi::DEVICE_GPU* d, } template <> -void gemm_op::operator()(const psi::DEVICE_GPU* d, +void gemm_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const char& transa, const char& transb, const int& m, @@ -629,7 +817,36 @@ void gemm_op::operator()(const psi::DEVICE_GPU* d, } template <> -void matrixTranspose_op::operator()(const psi::DEVICE_GPU* d, +void matrixTranspose_op::operator()(const psi::DEVICE_GPU* d, + const int& row, + const int& col, + const double* input_matrix, + double* output_matrix) +{ + double* device_temp = nullptr; + psi::memory::resize_memory_op()(d, device_temp, row * col); + + if (row == col) + { + double ONE = 1.0, ZERO = 0.0; + // use 'geam' API todo transpose. + hipblasDgeam(cublas_handle, HIPBLAS_OP_T, HIPBLAS_OP_N, col, row, &ONE, input_matrix, col, &ZERO, input_matrix, col, device_temp, col); + } + else + { + int thread = 1024; + int block = (row + col + thread - 1) / thread; + hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_transpose_kernel), dim3(block), dim3(thread), 0, 0, row, col, input_matrix, device_temp); + } + + psi::memory::synchronize_memory_op()(d, d, output_matrix, device_temp, row * col); + + psi::memory::delete_memory_op()(d, device_temp); + +} + +template <> +void matrixTranspose_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const int& row, const int& col, const std::complex* input_matrix, @@ -653,7 +870,7 @@ void matrixTranspose_op::operator()(const psi::DEVICE_GP { int thread = 1024; int block = (row + col + thread - 1) / thread; - hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_transpose_kernel), dim3(block), dim3(thread), 0, 0, row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); + hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_transpose_kernel>), dim3(block), dim3(thread), 0, 0, row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); } psi::memory::synchronize_memory_op, psi::DEVICE_GPU, psi::DEVICE_GPU>()(d, d, output_matrix, device_temp, row * col); @@ -663,7 +880,7 @@ void matrixTranspose_op::operator()(const psi::DEVICE_GP } template <> -void matrixTranspose_op::operator()(const psi::DEVICE_GPU* d, +void matrixTranspose_op, psi::DEVICE_GPU>::operator()(const psi::DEVICE_GPU* d, const int& row, const int& col, const std::complex* input_matrix, @@ -681,7 +898,7 @@ void matrixTranspose_op::operator()(const psi::DEVICE_G { int thread = 1024; int block = (row + col + thread - 1) / thread; - hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_transpose_kernel), dim3(block), dim3(thread), 0, 0, row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); + hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_transpose_kernel>), dim3(block), dim3(thread), 0, 0, row, col, (thrust::complex*)input_matrix, (thrust::complex*)device_temp); } psi::memory::synchronize_memory_op, psi::DEVICE_GPU, psi::DEVICE_GPU>()(d, d, output_matrix, device_temp, row * col); @@ -690,40 +907,72 @@ void matrixTranspose_op::operator()(const psi::DEVICE_G } - -template -void matrixSetToAnother::operator()( +template <> +void matrixSetToAnother < double, psi::DEVICE_GPU > ::operator()( + const psi::DEVICE_GPU* d, + const int& n, + const double* A, + const int& LDA, + double* B, + const int& LDB) +{ + int thread = 1024; + int block = (LDA + thread - 1) / thread; + hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_setTo_another_kernel), dim3(block), dim3(thread), 0, 0, n, LDA, LDB, A, B); +} +template <> +void matrixSetToAnother < std::complex, psi::DEVICE_GPU > ::operator()( const psi::DEVICE_GPU* d, const int& n, - const std::complex* A, + const std::complex* A, const int& LDA, - std::complex* B, + std::complex* B, const int& LDB) { int thread = 1024; int block = (LDA + thread - 1) / thread; - hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_setTo_another_kernel), dim3(block), dim3(thread), 0, 0, n, LDA, LDB, reinterpret_cast*>(A), reinterpret_cast*>(B)); + hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_setTo_another_kernel>), dim3(block), dim3(thread), 0, 0, n, LDA, LDB, reinterpret_cast*>(A), reinterpret_cast*>(B)); +} +template <> +void matrixSetToAnother < std::complex, psi::DEVICE_GPU > ::operator()( + const psi::DEVICE_GPU* d, + const int& n, + const std::complex* A, + const int& LDA, + std::complex* B, + const int& LDB) +{ + int thread = 1024; + int block = (LDA + thread - 1) / thread; + hipLaunchKernelGGL(HIP_KERNEL_NAME(matrix_setTo_another_kernel>), dim3(block), dim3(thread), 0, 0, n, LDA, LDB, reinterpret_cast*>(A), reinterpret_cast*>(B)); } // Explicitly instantiate functors for the types of functor registered. -template struct zdot_real_op; +template struct dot_real_op, psi::DEVICE_GPU>; template struct calc_grad_with_block_op, psi::DEVICE_GPU>; template struct line_minimize_with_block_op, psi::DEVICE_GPU>; -template struct vector_div_constant_op; -template struct vector_mul_vector_op; -template struct vector_div_vector_op; +template struct vector_div_constant_op, psi::DEVICE_GPU>; +template struct vector_mul_vector_op, psi::DEVICE_GPU>; +template struct vector_div_vector_op, psi::DEVICE_GPU>; template struct constantvector_addORsub_constantVector_op; -template struct matrixSetToAnother; +template struct matrixSetToAnother, psi::DEVICE_GPU>; -template struct zdot_real_op; +template struct dot_real_op, psi::DEVICE_GPU>; template struct calc_grad_with_block_op, psi::DEVICE_GPU>; template struct line_minimize_with_block_op, psi::DEVICE_GPU>; +template struct vector_div_constant_op, psi::DEVICE_GPU>; +template struct vector_mul_vector_op, psi::DEVICE_GPU>; +template struct vector_div_vector_op, psi::DEVICE_GPU>; +template struct constantvector_addORsub_constantVector_op; +template struct matrixSetToAnother, psi::DEVICE_GPU>; + +#ifdef __LCAO +template struct dot_real_op; template struct vector_div_constant_op; template struct vector_mul_vector_op; -template struct vector_div_vector_op; -template struct constantvector_addORsub_constantVector_op; +template struct vector_div_vector_op; template struct matrixSetToAnother; - +#endif } // namespace hsolver diff --git a/source/module_hsolver/kernels/test/math_dngvd_test.cpp b/source/module_hsolver/kernels/test/math_dngvd_test.cpp index 31319ee1170..4308a621208 100644 --- a/source/module_hsolver/kernels/test/math_dngvd_test.cpp +++ b/source/module_hsolver/kernels/test/math_dngvd_test.cpp @@ -143,7 +143,7 @@ TEST_F(TestModuleHsolverMathDngvd, transpose_gpu) // run hsolver::createGpuBlasHandle(); - hsolver::matrixTranspose_op()(gpu_ctx, 2, 3, device_transpose, device_transpose); + hsolver::matrixTranspose_op, psi::DEVICE_GPU>()(gpu_ctx, 2, 3, device_transpose, device_transpose); hsolver::destoryBLAShandle(); // copy transpose data from GPU to CPU diff --git a/source/module_hsolver/kernels/test/math_kernel_test.cpp b/source/module_hsolver/kernels/test/math_kernel_test.cpp index 2cbbbd5ab8d..1a1c6905e82 100644 --- a/source/module_hsolver/kernels/test/math_kernel_test.cpp +++ b/source/module_hsolver/kernels/test/math_kernel_test.cpp @@ -51,8 +51,8 @@ class TestModuleHsolverMathKernel : public ::testing::Test { } - using zdot_real_cpu_op = hsolver::zdot_real_op; - using zdot_real_gpu_op = hsolver::zdot_real_op; + using zdot_real_cpu_op = hsolver::dot_real_op, psi::DEVICE_CPU>; + using zdot_real_gpu_op = hsolver::dot_real_op, psi::DEVICE_GPU>; using resize_memory_op = psi::memory::resize_memory_op, psi::DEVICE_GPU>; using delete_memory_op = psi::memory::delete_memory_op, psi::DEVICE_GPU>; @@ -71,23 +71,23 @@ class TestModuleHsolverMathKernel : public ::testing::Test // haozhihan add // cpu operator - using vector_div_constant_op_cpu = hsolver::vector_div_constant_op; - using vector_mul_vector_op_cpu = hsolver::vector_mul_vector_op; - using vector_div_vector_op_cpu = hsolver::vector_div_vector_op; + using vector_div_constant_op_cpu = hsolver::vector_div_constant_op, psi::DEVICE_CPU>; + using vector_mul_vector_op_cpu = hsolver::vector_mul_vector_op, psi::DEVICE_CPU>; + using vector_div_vector_op_cpu = hsolver::vector_div_vector_op, psi::DEVICE_CPU>; using constantvector_addORsub_constantVector_op_cpu = hsolver::constantvector_addORsub_constantVector_op; using axpy_op_cpu = hsolver::axpy_op; using scal_op_cpu = hsolver::scal_op; - using gemv_op_cpu = hsolver::gemv_op; + using gemv_op_cpu = hsolver::gemv_op, psi::DEVICE_CPU>; // gpu operator - using vector_div_constant_op_gpu = hsolver::vector_div_constant_op; - using vector_mul_vector_op_gpu = hsolver::vector_mul_vector_op; - using vector_div_vector_op_gpu = hsolver::vector_div_vector_op; + using vector_div_constant_op_gpu = hsolver::vector_div_constant_op, psi::DEVICE_GPU>; + using vector_mul_vector_op_gpu = hsolver::vector_mul_vector_op, psi::DEVICE_GPU>; + using vector_div_vector_op_gpu = hsolver::vector_div_vector_op, psi::DEVICE_GPU>; using constantvector_addORsub_constantVector_op_gpu = hsolver::constantvector_addORsub_constantVector_op; using axpy_op_gpu = hsolver::axpy_op; using scal_op_gpu = hsolver::scal_op; - using gemv_op_gpu = hsolver::gemv_op; + using gemv_op_gpu = hsolver::gemv_op, psi::DEVICE_GPU>; // haozhihan add std::vector> L = {{-0.65412617, -0.74208893}, @@ -669,7 +669,7 @@ TEST_F(TestModuleHsolverMathKernel, matrixSetToAnother_op_gpu) B.size()); // run - hsolver::matrixSetToAnother()(gpu_ctx, n, device_A, LDA, device_B, LDB); + hsolver::matrixSetToAnother, psi::DEVICE_GPU>()(gpu_ctx, n, device_A, LDA, device_B, LDB); std::vector> B_gpu2cpu(8); psi::memory::synchronize_memory_op, psi::DEVICE_CPU, psi::DEVICE_GPU>()(cpu_ctx, @@ -679,7 +679,7 @@ TEST_F(TestModuleHsolverMathKernel, matrixSetToAnother_op_gpu) B_gpu2cpu.size()); std::vector> B_cpu(8); - hsolver::matrixSetToAnother()(cpu_ctx, n, A.data(), LDA, B_cpu.data(), LDB); + hsolver::matrixSetToAnother, psi::DEVICE_CPU>()(cpu_ctx, n, A.data(), LDA, B_cpu.data(), LDB); // for (int i = 0; i < 4; i++) // { diff --git a/source/module_hsolver/test/CMakeLists.txt b/source/module_hsolver/test/CMakeLists.txt index 5809c9f13a1..eef80715c17 100644 --- a/source/module_hsolver/test/CMakeLists.txt +++ b/source/module_hsolver/test/CMakeLists.txt @@ -42,6 +42,16 @@ AddTest( ../../module_hamilt_general/operator.cpp ../../module_hamilt_pw/hamilt_pwdft/operator_pw/operator_pw.cpp ) +if(ENABLE_LCAO) +AddTest( + TARGET HSolver_dav_real + LIBS ${math_libs} base psi device + SOURCES diago_david_real_test.cpp ../diago_david.cpp ../diago_iter_assist.cpp + ../../module_basis/module_pw/test/test_tool.cpp + ../../module_hamilt_general/operator.cpp + ../../module_hamilt_pw/hamilt_pwdft/operator_pw/operator_pw.cpp +) +endif() AddTest( TARGET HSolver_base diff --git a/source/module_hsolver/test/diago_bpcg_test.cpp b/source/module_hsolver/test/diago_bpcg_test.cpp index 1b450e4eff1..47b51c26dd3 100644 --- a/source/module_hsolver/test/diago_bpcg_test.cpp +++ b/source/module_hsolver/test/diago_bpcg_test.cpp @@ -116,7 +116,7 @@ class DiagoBPCGPrepare DIAGOTEST::npw_local = new int[nprocs]; #ifdef __MPI DIAGOTEST::cal_division(DIAGOTEST::npw); - DIAGOTEST::divide_hpsi(psi,psi_local); //will distribute psi and Hmatrix to each process + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix, DIAGOTEST::hmatrix_local); //will distribute psi and Hmatrix to each process precondition_local = new double[DIAGOTEST::npw_local[mypnum]]; DIAGOTEST::divide_psi(precondition,precondition_local); #else @@ -163,7 +163,7 @@ TEST_P(DiagoBPCGTest, RandomHamilt) hsolver::DiagoIterAssist>::PW_DIAG_THR = dcp.eps; //std::cout<<"maxiter "<>::PW_DIAG_NMAX<>::PW_DIAG_THR<> hpsi(dcp.nband, dcp.npw, dcp.sparsity); DIAGOTEST::hmatrix = hpsi.hamilt(); DIAGOTEST::npw = dcp.npw; @@ -188,7 +188,7 @@ TEST(DiagoBPCGTest, Hamilt) { int dim = 2; int nbnd = 2; - HPsi hpsi(nbnd, dim); + HPsi> hpsi(nbnd, dim); std::vector> hm = hpsi.hamilt(); EXPECT_EQ(DIAGOTEST::h_nr, 2); EXPECT_EQ(DIAGOTEST::h_nc, 2); @@ -235,7 +235,7 @@ TEST(DiagoBPCGTest, TwoByTwo) DiagoBPCGPrepare dcp(nband, dim, 0, true, 1e-4, 50, 1e-10); hsolver::DiagoIterAssist>::PW_DIAG_NMAX = dcp.maxiter; hsolver::DiagoIterAssist>::PW_DIAG_THR = dcp.eps; - HPsi hpsi; + HPsi> hpsi; hpsi.create(nband, dim); DIAGOTEST::hmatrix = hm; DIAGOTEST::npw = dim; @@ -258,7 +258,7 @@ TEST(DiagoBPCGTest, readH) hsolver::DiagoIterAssist>::PW_DIAG_NMAX = dcp.maxiter; hsolver::DiagoIterAssist>::PW_DIAG_THR = dcp.eps; hsolver::DiagoIterAssist>::SCF_ITER = 1; - HPsi hpsi; + HPsi> hpsi; hpsi.create(nband, dim); DIAGOTEST::hmatrix = hpsi.hamilt(); DIAGOTEST::npw = dim; diff --git a/source/module_hsolver/test/diago_cg_float_test.cpp b/source/module_hsolver/test/diago_cg_float_test.cpp index 728e2b47eec..f382d90fd62 100644 --- a/source/module_hsolver/test/diago_cg_float_test.cpp +++ b/source/module_hsolver/test/diago_cg_float_test.cpp @@ -120,9 +120,9 @@ class DiagoCGPrepare DIAGOTEST::npw_local = new int[nprocs]; #ifdef __MPI DIAGOTEST::cal_division(DIAGOTEST::npw); - DIAGOTEST::divide_hpsi_f(psi,psi_local); //will distribute psi and Hmatrix to each process + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix_f, DIAGOTEST::hmatrix_local_f); //will distribute psi and Hmatrix to each process precondition_local = new float[DIAGOTEST::npw_local[mypnum]]; - DIAGOTEST::divide_psi_f(precondition,precondition_local); + DIAGOTEST::divide_psi(precondition, precondition_local); #else DIAGOTEST::hmatrix_local_f = DIAGOTEST::hmatrix_f; DIAGOTEST::npw_local[0] = DIAGOTEST::npw; @@ -164,7 +164,7 @@ TEST_P(DiagoCGFloatTest, RandomHamilt) hsolver::DiagoIterAssist>::PW_DIAG_THR = dcp.eps; //std::cout<<"maxiter "<>::PW_DIAG_NMAX<>::PW_DIAG_THR<> hpsi(dcp.nband, dcp.npw, dcp.sparsity); DIAGOTEST::hmatrix_f = hpsi.hamilt(); DIAGOTEST::npw = dcp.npw; @@ -189,7 +189,7 @@ TEST(DiagoCGFloatTest, Hamilt) { int dim = 2; int nbnd = 2; - HPsi_f hpsi(nbnd, dim); + HPsi> hpsi(nbnd, dim); std::vector> hm = hpsi.hamilt(); EXPECT_EQ(DIAGOTEST::h_nr, 2); EXPECT_EQ(DIAGOTEST::h_nc, 2); @@ -258,7 +258,7 @@ TEST(DiagoCGFloatTest, readH) DiagoCGPrepare dcp(nband, dim, 0, true, 1e-5, 500, 1e-0); hsolver::DiagoIterAssist>::PW_DIAG_NMAX = dcp.maxiter; hsolver::DiagoIterAssist>::PW_DIAG_THR = dcp.eps; - HPsi_f hpsi; + HPsi> hpsi; hpsi.create(nband, dim); DIAGOTEST::hmatrix_f = hpsi.hamilt(); DIAGOTEST::npw = dim; diff --git a/source/module_hsolver/test/diago_cg_test.cpp b/source/module_hsolver/test/diago_cg_test.cpp index 79d8e7e1afc..4c765471229 100644 --- a/source/module_hsolver/test/diago_cg_test.cpp +++ b/source/module_hsolver/test/diago_cg_test.cpp @@ -116,7 +116,7 @@ class DiagoCGPrepare DIAGOTEST::npw_local = new int[nprocs]; #ifdef __MPI DIAGOTEST::cal_division(DIAGOTEST::npw); - DIAGOTEST::divide_hpsi(psi,psi_local); //will distribute psi and Hmatrix to each process + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix, DIAGOTEST::hmatrix_local); //will distribute psi and Hmatrix to each process precondition_local = new double[DIAGOTEST::npw_local[mypnum]]; DIAGOTEST::divide_psi(precondition,precondition_local); #else @@ -160,7 +160,7 @@ TEST_P(DiagoCGTest, RandomHamilt) hsolver::DiagoIterAssist>::PW_DIAG_THR = dcp.eps; //std::cout<<"maxiter "<>::PW_DIAG_NMAX<>::PW_DIAG_THR<> hpsi(dcp.nband, dcp.npw, dcp.sparsity); DIAGOTEST::hmatrix = hpsi.hamilt(); DIAGOTEST::npw = dcp.npw; @@ -185,7 +185,7 @@ TEST(DiagoCGTest, Hamilt) { int dim = 2; int nbnd = 2; - HPsi hpsi(nbnd, dim); + HPsi> hpsi(nbnd, dim); std::vector> hm = hpsi.hamilt(); EXPECT_EQ(DIAGOTEST::h_nr, 2); EXPECT_EQ(DIAGOTEST::h_nc, 2); @@ -254,7 +254,7 @@ TEST(DiagoCGTest, readH) DiagoCGPrepare dcp(nband, dim, 0, true, 1e-5, 500, 1e-3); hsolver::DiagoIterAssist>::PW_DIAG_NMAX = dcp.maxiter; hsolver::DiagoIterAssist>::PW_DIAG_THR = dcp.eps; - HPsi hpsi; + HPsi> hpsi; hpsi.create(nband, dim); DIAGOTEST::hmatrix = hpsi.hamilt(); DIAGOTEST::npw = dim; diff --git a/source/module_hsolver/test/diago_david_float_test.cpp b/source/module_hsolver/test/diago_david_float_test.cpp index dad311f2805..880d643da40 100644 --- a/source/module_hsolver/test/diago_david_float_test.cpp +++ b/source/module_hsolver/test/diago_david_float_test.cpp @@ -128,7 +128,7 @@ TEST_P(DiagoDavTest,RandomHamilt) if (DETAILINFO&&ddp.mypnum==0) std::cout << "npw=" << ddp.npw << ", nband=" << ddp.nband << ", sparsity=" << ddp.sparsity << ", eps=" << ddp.eps << std::endl; - HPsi_f hpsi(ddp.nband,ddp.npw,ddp.sparsity); + HPsi> hpsi(ddp.nband, ddp.npw, ddp.sparsity); DIAGOTEST::hmatrix_f = hpsi.hamilt(); DIAGOTEST::npw = ddp.npw; DIAGOTEST::npw_local = new int[ddp.nprocs]; @@ -138,9 +138,9 @@ TEST_P(DiagoDavTest,RandomHamilt) #ifdef __MPI DIAGOTEST::cal_division(DIAGOTEST::npw); - DIAGOTEST::divide_hpsi_f(psi,psi_local); + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix_f, DIAGOTEST::hmatrix_local_f); precondition_local = new float[DIAGOTEST::npw_local[ddp.mypnum]]; - DIAGOTEST::divide_psi_f(hpsi.precond(),precondition_local); + DIAGOTEST::divide_psi(hpsi.precond(), precondition_local); #else DIAGOTEST::hmatrix_local_f = DIAGOTEST::hmatrix_f; DIAGOTEST::npw_local[0] = DIAGOTEST::npw; @@ -174,7 +174,7 @@ TEST(DiagoDavRealSystemTest,dataH) DiagoDavPrepare ddp(nband,DIAGOTEST::npw,0,2,1e-5,500); - HPsi_f hpsi(nband,DIAGOTEST::npw); + HPsi> hpsi(nband, DIAGOTEST::npw); psi::Psi> psi = hpsi.psi(); DIAGOTEST::npw_local = new int[ddp.nprocs]; psi::Psi> psi_local; @@ -182,9 +182,9 @@ TEST(DiagoDavRealSystemTest,dataH) #ifdef __MPI DIAGOTEST::cal_division(DIAGOTEST::npw); - DIAGOTEST::divide_hpsi_f(psi,psi_local); + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix_f, DIAGOTEST::hmatrix_local_f); precondition_local = new float[DIAGOTEST::npw_local[ddp.mypnum]]; - DIAGOTEST::divide_psi_f(hpsi.precond(),precondition_local); + DIAGOTEST::divide_psi(hpsi.precond(), precondition_local); #else DIAGOTEST::hmatrix_local_f = DIAGOTEST::hmatrix_f; DIAGOTEST::npw_local[0] = DIAGOTEST::npw; diff --git a/source/module_hsolver/test/diago_david_real_test.cpp b/source/module_hsolver/test/diago_david_real_test.cpp new file mode 100644 index 00000000000..0843b02ae9a --- /dev/null +++ b/source/module_hsolver/test/diago_david_real_test.cpp @@ -0,0 +1,226 @@ +#include"module_hsolver/diago_david.h" +#include"module_hsolver/diago_iter_assist.h" +#include"module_hamilt_pw/hamilt_pwdft/hamilt_pw.h" +#include"diago_mock.h" +#include "module_psi/psi.h" +#include"gtest/gtest.h" +#include "module_base/inverse_matrix.h" +#include "module_base/lapack_connector.h" +#include "module_basis/module_pw/test/test_tool.h" +#include"mpi.h" + +#define CONVTHRESHOLD 1e-0 +#define DETAILINFO false + + +/************************************************ +* unit test of class Diago_David +***********************************************/ + +/** + * Class Diago_David is used to solve the eigenvalues + * This unittest test the function Diago_David::diag() for FPTYPE=double and Device=cpu + * with different examples. + * - the hamilt matrix (npw=100,500,1000) produced by random with sparsity of 90% + * - the hamilt matrix (npw=100,500,1000) produced by random with sparsity of 50% + * - the hamilt matrix (npw=100,500,1000) produced by random with sparsity of 0% + * - the hamilt matrix read from "data-H" + * + * The test is passed when the eignvalues are closed to these calculated by LAPACK. + * + */ + + //use lapack to calcualte eigenvalue of matrix hm + //NOTE: after finish this function, hm stores the eigen vectors. +void lapackEigen(int& npw, std::vector& hm, double* e, bool outtime = false) +{ + int info = 0; + auto tmp = hm; + clock_t start, end; + start = clock(); + char tmp_c1 = 'V', tmp_c2 = 'U'; + + double work_tmp; + constexpr int minus_one = -1; + dsyev_(&tmp_c1, &tmp_c2, &npw, tmp.data(), &npw, e, &work_tmp, &minus_one, &info); // get best lwork + + const int lwork = work_tmp; + double* work2 = new double[lwork]; + dsyev_(&tmp_c1, &tmp_c2, &npw, tmp.data(), &npw, e, work2, &lwork, &info); + end = clock(); + if (info) std::cout << "ERROR: Lapack solver, info=" << info << std::endl; + if (outtime) std::cout << "Lapack Run time: " << (double)(end - start) / CLOCKS_PER_SEC << " S" << std::endl; + delete[] work2; +} +class DiagoDavPrepare +{ +public: + DiagoDavPrepare(int nband, int npw, int sparsity, int order, double eps, int maxiter) : + nband(nband), npw(npw), sparsity(sparsity), order(order), eps(eps), maxiter(maxiter) + { +#ifdef __MPI + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); +#endif + } + + int nband, npw, sparsity, order, maxiter, notconv; + double eps, avg_iter; + int nprocs = 1, mypnum = 0; + + void CompareEigen(psi::Psi& phi, double* precondition) + { + //calculate eigenvalues by LAPACK; + double* e_lapack = new double[npw]; + double* ev; + if (mypnum == 0) lapackEigen(npw, DIAGOTEST::hmatrix_d, e_lapack, DETAILINFO); + + //do Diago_David::diag() + double* en = new double[npw]; + hamilt::Hamilt* phm; + phm = new hamilt::HamiltPW(nullptr, nullptr, nullptr); + hsolver::DiagoDavid dav(precondition); + hsolver::DiagoDavid::PW_DIAG_NDIM = order; + hsolver::DiagoIterAssist::PW_DIAG_NMAX = maxiter; + hsolver::DiagoIterAssist::PW_DIAG_THR = eps; + GlobalV::NPROC_IN_POOL = nprocs; + phi.fix_k(0); + + double use_time = 0.0; +#ifdef __MPI + double start = 0.0, end = 0.0; + start = MPI_Wtime(); +#else + clock_t start, end; + start = clock(); +#endif + + dav.diag(phm, phi, en); + +#ifdef __MPI + end = MPI_Wtime(); + use_time = end - start; +#else + end = clock(); + use_time = (double)(end - start); +#endif + + if (mypnum == 0) + { + if (DETAILINFO) std::cout << "diag Run time: " << use_time << std::endl; + for (int i = 0;i < nband;i++) + { + EXPECT_NEAR(en[i], e_lapack[i], CONVTHRESHOLD); + } + } + delete[] en; + delete phm; + delete[] e_lapack; + } +}; + +class DiagoDavTest : public ::testing::TestWithParam {}; + +TEST_P(DiagoDavTest, RandomHamilt) +{ + DiagoDavPrepare ddp = GetParam(); + if (DETAILINFO && ddp.mypnum == 0) std::cout << "npw=" << ddp.npw << ", nband=" << ddp.nband << ", sparsity=" + << ddp.sparsity << ", eps=" << ddp.eps << std::endl; + + HPsi hpsi(ddp.nband, ddp.npw, ddp.sparsity); + DIAGOTEST::hmatrix_d = hpsi.hamilt(); + DIAGOTEST::npw = ddp.npw; + DIAGOTEST::npw_local = new int[ddp.nprocs]; + psi::Psi psi = hpsi.psi(); + psi::Psi psi_local; + double* precondition_local; + +#ifdef __MPI + DIAGOTEST::cal_division(DIAGOTEST::npw); + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix_d, DIAGOTEST::hmatrix_local_d); + precondition_local = new double[DIAGOTEST::npw_local[ddp.mypnum]]; + DIAGOTEST::divide_psi(hpsi.precond(), precondition_local); +#else + DIAGOTEST::hmatrix_local_d = DIAGOTEST::hmatrix_d; + DIAGOTEST::npw_local[0] = DIAGOTEST::npw; + psi_local = psi; + precondition_local = new double[DIAGOTEST::npw]; + for (int i = 0;i < DIAGOTEST::npw;i++) precondition_local[i] = (hpsi.precond())[i]; +#endif + + ddp.CompareEigen(psi_local, precondition_local); + delete[] DIAGOTEST::npw_local; + delete[] precondition_local; +} + + +INSTANTIATE_TEST_SUITE_P(VerifyDiag, DiagoDavTest, ::testing::Values( + //DiagoDavPrepare(int nband, int npw, int sparsity, int order,double eps,int maxiter) + DiagoDavPrepare(10, 100, 0, 4, 1e-5, 500), + DiagoDavPrepare(20, 500, 7, 4, 1e-5, 500) + //DiagoDavPrepare(50,1000,8,4,1e-5,500) + //DiagoDavPrepare(20,2000,8,4,1e-5,500) +)); + +TEST(DiagoDavRealSystemTest, dataH) +{ + std::vector hmatrix; + std::ifstream ifs("H-GammaOnly-Si64.dat"); + DIAGOTEST::readh(ifs, hmatrix); + ifs.close(); + DIAGOTEST::hmatrix_d = hmatrix; + int nband = std::max(DIAGOTEST::npw / 20, 1); + + DiagoDavPrepare ddp(nband, DIAGOTEST::npw, 0, 2, 1e-5, 500); + + HPsi hpsi(nband, DIAGOTEST::npw); + psi::Psi psi = hpsi.psi(); + DIAGOTEST::npw_local = new int[ddp.nprocs]; + psi::Psi psi_local; + double* precondition_local; + +#ifdef __MPI + DIAGOTEST::cal_division(DIAGOTEST::npw); + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix_d, DIAGOTEST::hmatrix_local_d); + precondition_local = new double[DIAGOTEST::npw_local[ddp.mypnum]]; + DIAGOTEST::divide_psi(hpsi.precond(), precondition_local); +#else + DIAGOTEST::hmatrix_local_d = DIAGOTEST::hmatrix_d; + DIAGOTEST::npw_local[0] = DIAGOTEST::npw; + psi_local = psi; + precondition_local = new double[DIAGOTEST::npw]; + for (int i = 0;i < DIAGOTEST::npw;i++) precondition_local[i] = (hpsi.precond())[i]; +#endif + + ddp.CompareEigen(psi_local, precondition_local); + + delete[] DIAGOTEST::npw_local; + delete[] precondition_local; +} + +int main(int argc, char** argv) +{ + int nproc = 1, myrank = 0; + +#ifdef __MPI + int nproc_in_pool, kpar = 1, mypool, rank_in_pool; + setupmpi(argc, argv, nproc, myrank); + divide_pools(nproc, myrank, nproc_in_pool, kpar, mypool, rank_in_pool); +#else + MPI_Init(&argc, &argv); +#endif + + testing::InitGoogleTest(&argc, argv); + ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); + if (myrank != 0) delete listeners.Release(listeners.default_result_printer()); + + int result = RUN_ALL_TESTS(); + if (myrank == 0 && result != 0) + { + std::cout << "ERROR:some tests are not passed" << std::endl; + return result; + } + + MPI_Finalize(); + return 0; +} diff --git a/source/module_hsolver/test/diago_david_test.cpp b/source/module_hsolver/test/diago_david_test.cpp index 222dc10609f..d55cfcb0a2e 100644 --- a/source/module_hsolver/test/diago_david_test.cpp +++ b/source/module_hsolver/test/diago_david_test.cpp @@ -32,7 +32,9 @@ //use lapack to calcualte eigenvalue of matrix hm //NOTE: after finish this function, hm stores the eigen vectors. -void lapackEigen(int &npw, std::vector> &hm, double * e, bool outtime=false) + + +void lapackEigen(int& npw, std::vector>& hm, double* e, bool outtime = false) { int lwork = 2 * npw; std::complex *work2= new std::complex[lwork]; @@ -128,7 +130,7 @@ TEST_P(DiagoDavTest,RandomHamilt) if (DETAILINFO&&ddp.mypnum==0) std::cout << "npw=" << ddp.npw << ", nband=" << ddp.nband << ", sparsity=" << ddp.sparsity << ", eps=" << ddp.eps << std::endl; - HPsi hpsi(ddp.nband,ddp.npw,ddp.sparsity); + HPsi> hpsi(ddp.nband, ddp.npw, ddp.sparsity); DIAGOTEST::hmatrix = hpsi.hamilt(); DIAGOTEST::npw = ddp.npw; DIAGOTEST::npw_local = new int[ddp.nprocs]; @@ -138,7 +140,7 @@ TEST_P(DiagoDavTest,RandomHamilt) #ifdef __MPI DIAGOTEST::cal_division(DIAGOTEST::npw); - DIAGOTEST::divide_hpsi(psi,psi_local); + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix, DIAGOTEST::hmatrix_local); precondition_local = new double[DIAGOTEST::npw_local[ddp.mypnum]]; DIAGOTEST::divide_psi(hpsi.precond(),precondition_local); #else @@ -163,7 +165,7 @@ INSTANTIATE_TEST_SUITE_P(VerifyDiag,DiagoDavTest,::testing::Values( //DiagoDavPrepare(20,2000,8,4,1e-5,500) )); -TEST(DiagoDavRealSystemTest,dataH) +TEST(DiagoDavRealSystemTest, dataH) { std::vector> hmatrix; std::ifstream ifs("H-KPoints-Si64.dat"); @@ -174,7 +176,7 @@ TEST(DiagoDavRealSystemTest,dataH) DiagoDavPrepare ddp(nband,DIAGOTEST::npw,0,2,1e-5,500); - HPsi hpsi(nband,DIAGOTEST::npw); + HPsi> hpsi(nband, DIAGOTEST::npw); psi::Psi> psi = hpsi.psi(); DIAGOTEST::npw_local = new int[ddp.nprocs]; psi::Psi> psi_local; @@ -182,7 +184,7 @@ TEST(DiagoDavRealSystemTest,dataH) #ifdef __MPI DIAGOTEST::cal_division(DIAGOTEST::npw); - DIAGOTEST::divide_hpsi(psi,psi_local); + DIAGOTEST::divide_hpsi(psi, psi_local, DIAGOTEST::hmatrix, DIAGOTEST::hmatrix_local); precondition_local = new double[DIAGOTEST::npw_local[ddp.mypnum]]; DIAGOTEST::divide_psi(hpsi.precond(),precondition_local); #else diff --git a/source/module_hsolver/test/diago_lcao_parallel_test.sh b/source/module_hsolver/test/diago_lcao_parallel_test.sh index 89d2b7cfd36..276fc75ce01 100644 --- a/source/module_hsolver/test/diago_lcao_parallel_test.sh +++ b/source/module_hsolver/test/diago_lcao_parallel_test.sh @@ -9,6 +9,7 @@ for i in 6 3 2;do fi echo "TEST DIAGO davidson in parallel, nprocs=$i" mpirun -np $i ./HSolver_LCAO + mpirun -np $i ./HSolver_dav_real if [[ $? != 0 ]];then echo -e "\e[1;33m [ FAILED ] \e[0m"\ "execute UT with $i cores error." diff --git a/source/module_hsolver/test/diago_lcao_test.cpp b/source/module_hsolver/test/diago_lcao_test.cpp index 691dc25b674..487820a9d5d 100644 --- a/source/module_hsolver/test/diago_lcao_test.cpp +++ b/source/module_hsolver/test/diago_lcao_test.cpp @@ -26,7 +26,7 @@ * self-realized functions in module_hsolver/test/diago_elpa_utils.h */ -template class HamiltTEST : public hamilt::Hamilt> +template class HamiltTEST : public hamilt::Hamilt { public: int desc[9]; @@ -60,10 +60,10 @@ template class DiagoPrepare MPI_Comm_rank(MPI_COMM_WORLD, &myrank); if (ks_solver == "scalapack_gvx") - dh = new hsolver::DiagoBlas; + dh = new hsolver::DiagoBlas; #ifdef __ELPA else if(ks_solver == "genelpa") - dh = new hsolver::DiagoElpa; + dh = new hsolver::DiagoElpa; #endif else { @@ -82,7 +82,7 @@ template class DiagoPrepare std::vector s; std::vector h_local; std::vector s_local; - hsolver::DiagH>* dh=0; + hsolver::DiagH* dh = 0; psi::Psi psi; std::vector e_solver; std::vector e_lapack; diff --git a/source/module_hsolver/test/diago_mock.h b/source/module_hsolver/test/diago_mock.h index 944715061f8..ddfdbfae34e 100644 --- a/source/module_hsolver/test/diago_mock.h +++ b/source/module_hsolver/test/diago_mock.h @@ -7,6 +7,8 @@ namespace DIAGOTEST { + std::vector hmatrix_d; + std::vector hmatrix_local_d; std::vector> hmatrix; std::vector> hmatrix_local; std::vector> hmatrix_f; @@ -16,7 +18,25 @@ namespace DIAGOTEST int npw; int* npw_local; //number of plane wave distributed to each process - void readh(std::ifstream &inf, std::vector> &hm) + void readh(std::ifstream& inf, std::vector& hm) + { + int npw_; + inf >> npw_; + DIAGOTEST::npw = npw_; + hm.resize(npw * npw); + h_nr = npw; + h_nc = npw; + for (int i = 0;i < npw;i++) + { + for (int j = i;j < npw;j++) + { + inf >> hm[i * npw + j]; + if (i != j) { hm[j * npw + i] = hm[i * npw + j]; } + } + } + } + + void readh(std::ifstream& inf, std::vector>& hm) { int npw_; inf >> npw_; @@ -76,8 +96,12 @@ namespace DIAGOTEST MPI_Send(&(psi[start_point]),npw_local[j],MPI_DOUBLE,j,0,MPI_COMM_WORLD); else if(std::is_same>::value) MPI_Send(&(psi[start_point]),npw_local[j],MPI_DOUBLE_COMPLEX,j,0,MPI_COMM_WORLD); + else if (std::is_same::value) + MPI_Send(&(psi[start_point]), npw_local[j], MPI_FLOAT, j, 0, MPI_COMM_WORLD); + else if (std::is_same>::value) + MPI_Send(&(psi[start_point]), npw_local[j], MPI_C_FLOAT_COMPLEX, j, 0, MPI_COMM_WORLD); start_point += npw_local[j]; - } + } } else { @@ -85,46 +109,17 @@ namespace DIAGOTEST if (std::is_same::value) MPI_Recv(psi_local, npw_local[mypnum],MPI_DOUBLE,0,0,MPI_COMM_WORLD, MPI_STATUS_IGNORE); else if(std::is_same>::value) - MPI_Recv(psi_local, npw_local[mypnum],MPI_DOUBLE_COMPLEX,0,0,MPI_COMM_WORLD, MPI_STATUS_IGNORE); -#endif - } - } - - template - void divide_psi_f(T *psi, T *psi_local) - { - int nprocs=1, mypnum=0; -#ifdef __MPI - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); -#endif - - if(mypnum == 0) - { - for(int j=0;j::value) - MPI_Send(&(psi[start_point]),npw_local[j],MPI_FLOAT,j,0,MPI_COMM_WORLD); - else if(std::is_same>::value) - MPI_Send(&(psi[start_point]),npw_local[j],MPI_C_FLOAT_COMPLEX,j,0,MPI_COMM_WORLD); - start_point += npw_local[j]; - } - } - else - { - int recv_len = mypnum < (npw%nprocs) ? npw/nprocs + 1 : npw/nprocs; - if (std::is_same::value) - MPI_Recv(psi_local, npw_local[mypnum],MPI_FLOAT,0,0,MPI_COMM_WORLD, MPI_STATUS_IGNORE); - else if(std::is_same>::value) - MPI_Recv(psi_local, npw_local[mypnum],MPI_C_FLOAT_COMPLEX,0,0,MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(psi_local, npw_local[mypnum], MPI_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + else if (std::is_same::value) + MPI_Recv(psi_local, npw_local[mypnum], MPI_FLOAT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + else if (std::is_same>::value) + MPI_Recv(psi_local, npw_local[mypnum], MPI_C_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); #endif } } - - + template void divide_psi(double* psi, double* psi_local); + template void divide_psi>(std::complex* psi, std::complex* psi_local); + template void divide_psi>(std::complex* psi, std::complex* psi_local); #ifdef __MPI void cal_division(int &npw) { @@ -138,7 +133,8 @@ namespace DIAGOTEST } } - void divide_hpsi(psi::Psi> &psi, psi::Psi> &psi_local) + template + void divide_hpsi(psi::Psi& psi, psi::Psi& psi_local, std::vector& hmatrix, std::vector& hmatrix_local) { int nprocs, mypnum; MPI_Comm_size(MPI_COMM_WORLD, &nprocs); @@ -154,52 +150,23 @@ namespace DIAGOTEST psi_local.resize(nk,nbands,npw_local[mypnum]); for(int i=0;i>(&(hmatrix[i*npw]),&(hmatrix_local[i*npw_local[mypnum]])); - if(i>(psi.get_pointer(i),psi_local.get_pointer(i)); - } - } - } - } - - void divide_hpsi_f(psi::Psi> &psi, psi::Psi> &psi_local) - { - int nprocs, mypnum; - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); - - int npw = psi.get_nbasis(); - int nbands = psi.get_nbands(); - int nk = psi.get_nk(); - - hmatrix_local_f.resize(npw * npw_local[mypnum]); - h_nc = npw_local[mypnum]; - h_nr = npw; - psi_local.resize(nk,nbands,npw_local[mypnum]); - for(int i=0;i>(&(hmatrix_f[i*npw]),&(hmatrix_local_f[i*npw_local[mypnum]])); + divide_psi(&(hmatrix[i * npw]), &(hmatrix_local[i * npw_local[mypnum]])); if(i>(psi.get_pointer(i),psi_local.get_pointer(i)); + divide_psi(psi.get_pointer(i), psi_local.get_pointer(i)); } } } - } + } #endif - } - +#include "module_base/macros.h" +template class HPsi { /** @@ -216,11 +183,11 @@ class HPsi * (0 means no sparsity, 10 means a diagonal matrix) * * After instantiation a HPsi, one can use below functions: - * - hamilt(): return the Hermite matrix (type: std::vector>) - * - precond(): return the precondition (type: double Pointer) + * - hamilt(): return the Hermite matrix (type: std::vector) + * - precond(): return the precondition (type: Real Pointer) * */ - + using Real = typename GetTypeReal::type; public: HPsi(int nband,int npw, int sparsity=7): nband(nband),npw(npw),sparsity(sparsity) {genhmatrix();genpsi();genprecondition();} @@ -236,14 +203,14 @@ class HPsi } //return the matrix - double* precond() {return precondition;} - std::vector> hamilt() {return hmatrix;} + Real* precond() { return precondition; } + std::vector hamilt() { return hmatrix; } //ModuleBase::ComplexMatrix psi() {return psimatrix;} - psi::Psi> psi() + psi::Psi psi() { Structure_Factor* sf; int* ngk = nullptr; - psi::Psi> psitmp(1,nband,npw,ngk); + psi::Psi psitmp(1, nband, npw, ngk); for(int i=0;i u(min,max); - if (sparsity < 0) sparsity = 0; - if (sparsity > 10) sparsity = 10; - for(int i=0;i(u(e))/max; - //double imagp= pow(-1.0,u(e)%2) * static_cast(u(e))/max; - if (int (u(e) % 10) > int (sparsity-1)) mincoef = 1.0; - if(i==j) - { - hmatrix[i * npw + j] = std::complex{realp,0.0}; - } - else - { - //hmatrix(i,j) = mincoef*std::complex{realp,imagp}; - hmatrix[i * npw + j] = mincoef*std::complex{realp,0.0}; - hmatrix[j * npw + i] = conj(hmatrix[i * npw + j]); - } - } - } - } + void genhmatrix(); //generate the psi matrix - void genpsi() - { - psimatrix.resize(nband * npw); - std::default_random_engine e(10); - std::uniform_int_distribution u(min,max); - for(int i=0;i(u(e))/max; - //double imagp=pow(-1.0,u(e)%2) * static_cast(u(e))/max; - double imagp = 0.0; - psimatrix[i * npw + j] = std::complex{realp,imagp}; - } - } - } + void genpsi(); //generate precondition void genprecondition() { - precondition = new double [npw]; + precondition = new Real[npw]; std::default_random_engine e(1000); - std::uniform_int_distribution u(min,max); - for(int i=0;i u(min, max); + for (int i = 0;i < npw;i++) { - precondition[i] = 1.0 + static_cast(u(e))/max; + precondition[i] = 1.0 + static_cast(u(e)) / max; } } - private: +private: int npw; int nband; - std::vector> hmatrix; - std::vector> psimatrix; - double* precondition; - int min=0; - int max=9999; + std::vector hmatrix; + std::vector psimatrix; + Real* precondition; + int min = 0; + int max = 9999; int sparsity; }; -class HPsi_f +template<> +void HPsi::genhmatrix() { - /** - * This calss used to produce the Hermite matrix, the initial - * guess wave function, and the precondition by the random - * number. The elements of Hermite matrix and wave function are - * between -1.0 to 1.0, and the preconddition is between 1.0 to 2.0. - * - * The parameters in construct function or function create() - * are same: - * - int nband/nbd: number of calculated bands - * - int npw: number of plane wave - * - int sparsity: the sparsity of Halmit matrix, between 0 and 10. - * (0 means no sparsity, 10 means a diagonal matrix) - * - * After instantiation a HPsi, one can use below functions: - * - hamilt(): return the Hermite matrix (type: std::vector>) - * - precond(): return the precondition (type: float Pointer) - * - */ - - public: - HPsi_f(int nband,int npw, int sparsity=7): - nband(nband),npw(npw),sparsity(sparsity) {genhmatrix();genpsi();genprecondition();} - HPsi_f(){}; - ~HPsi_f() {delete [] precondition;} - - void create(int nbd,int npw, int sparsity=7) + hmatrix.resize(npw * npw); + DIAGOTEST::h_nr = npw; + DIAGOTEST::h_nc = npw; + std::default_random_engine e(100); + std::uniform_int_distribution u(min, max); + if (sparsity < 0) sparsity = 0; + if (sparsity > 10) sparsity = 10; + for (int i = 0;i < npw;i++) { - this->nband = nbd; - this->npw = npw; - this->sparsity = sparsity; - genhmatrix();genpsi();genprecondition(); + for (int j = 0;j <= i;j++) + { + double mincoef = 0.0; + double realp = pow(-1.0, u(e) % 2) * static_cast(u(e)) / max; + if (int(u(e) % 10) > int(sparsity - 1)) mincoef = 1.0; + if (i == j) + hmatrix[i * npw + j] = realp; + else + hmatrix[j * npw + i] = hmatrix[i * npw + j] = mincoef * realp; + } } - - //return the matrix - float* precond() {return precondition;} - std::vector> hamilt() {return hmatrix;} - psi::Psi> psi() +} +template<> +void HPsi>::genhmatrix() +{ + hmatrix.resize(npw * npw); + DIAGOTEST::h_nr = npw; + DIAGOTEST::h_nc = npw; + std::default_random_engine e(100); + std::uniform_int_distribution u(min, max); + if (sparsity < 0) sparsity = 0; + if (sparsity > 10) sparsity = 10; + for (int i = 0;i < npw;i++) { - Structure_Factor* sf; - int* ngk = nullptr; - psi::Psi> psitmp(1,nband,npw,ngk); - for(int i=0;i(u(e)) / max; + //double imagp= pow(-1.0,u(e)%2) * static_cast(u(e))/max; + if (int(u(e) % 10) > int(sparsity - 1)) mincoef = 1.0; + if (i == j) + { + hmatrix[i * npw + j] = std::complex{ realp,0.0 }; + } + else + { + //hmatrix(i,j) = mincoef*std::complex{realp,imagp}; + hmatrix[i * npw + j] = mincoef * std::complex{ realp, 0.0 }; + hmatrix[j * npw + i] = conj(hmatrix[i * npw + j]); + } + } + } +} +template<> +void HPsi>::genhmatrix() +{ + hmatrix.resize(npw * npw); + DIAGOTEST::h_nr = npw; + DIAGOTEST::h_nc = npw; + std::default_random_engine e(100); + std::uniform_int_distribution u(min, max); + if (sparsity < 0) sparsity = 0; + if (sparsity > 10) sparsity = 10; + for (int i = 0;i < npw;i++) { - hmatrix.resize(npw * npw); - DIAGOTEST::h_nr = npw; - DIAGOTEST::h_nc = npw; - std::default_random_engine e(100); - std::uniform_int_distribution u(min,max); - if (sparsity < 0) sparsity = 0; - if (sparsity > 10) sparsity = 10; - for(int i=0;i(u(e)) / max; + if (int(u(e) % 10) > int(sparsity - 1)) mincoef = 1.0; + if (i == j) { - float mincoef = 0.0; - float realp= pow(-1.0,u(e)%2) * static_cast(u(e))/max; - //float imagp= pow(-1.0,u(e)%2) * static_cast(u(e))/max; - if (int (u(e) % 10) > int (sparsity-1)) mincoef = 1.0; - if(i==j) - { - hmatrix[i * npw + j] = std::complex{realp,0.0}; - } - else - { - //hmatrix(i,j) = mincoef*std::complex{realp,imagp}; - hmatrix[i * npw + j] = mincoef*std::complex{realp,0.0}; - hmatrix[j * npw + i] = conj(hmatrix[i * npw + j]); - } + hmatrix[i * npw + j] = std::complex{ realp,0.0 }; + } + else + { + hmatrix[i * npw + j] = mincoef * std::complex{ realp, 0.0 }; + hmatrix[j * npw + i] = conj(hmatrix[i * npw + j]); } } } +} - //generate the psi matrix - void genpsi() +template<> +void HPsi::genpsi() +{ { psimatrix.resize(nband * npw); std::default_random_engine e(10); - std::uniform_int_distribution u(min,max); - for(int i=0;i u(min, max); + for (int i = 0;i < nband;i++) + for (int j = 0;j < npw;j++) + psimatrix[i * npw + j] = pow(-1.0, u(e) % 2) * static_cast(u(e)) / max; + } +} +template<> +void HPsi>::genpsi() +{ + { + psimatrix.resize(nband * npw); + std::default_random_engine e(10); + std::uniform_int_distribution u(min, max); + for (int i = 0;i < nband;i++) { - for(int j=0;j(u(e))/max; - //float imagp=pow(-1.0,u(e)%2) * static_cast(u(e))/max; - float imagp = 0.0; - psimatrix[i * npw + j] = std::complex{realp,imagp}; + double realp = pow(-1.0, u(e) % 2) * static_cast(u(e)) / max; + //double imagp=pow(-1.0,u(e)%2) * static_cast(u(e))/max; + double imagp = 0.0; + psimatrix[i * npw + j] = std::complex{ realp,imagp }; } } } - - //generate precondition - void genprecondition() +} +template<> +void HPsi>::genpsi() +{ { - precondition = new float [npw]; - std::default_random_engine e(1000); - std::uniform_int_distribution u(min,max); - for(int i=0;i u(min, max); + for (int i = 0;i < nband;i++) { - precondition[i] = 1.0 + static_cast(u(e))/max; + for (int j = 0;j < npw;j++) + { + float realp = pow(-1.0, u(e) % 2) * static_cast(u(e)) / max; + float imagp = 0.0; + psimatrix[i * npw + j] = std::complex{ realp,imagp }; + } } } +} - private: - int npw; - int nband; - std::vector> hmatrix; - std::vector> psimatrix; - float* precondition; - int min=0; - int max=9999; - int sparsity; -}; +template class HPsi; +template class HPsi>; +template class HPsi>; //totally same as the original function -template<> void hamilt::HamiltPW>::sPsi +template<> void hamilt::Hamilt::sPsi ( - const std::complex *psi, - std::complex *spsi, + const double* psi, + double* spsi, const size_t size )const { - for (size_t i=0; i void hamilt::HamiltPW>::sPsi +template<> void hamilt::Hamilt>::sPsi ( - const std::complex *psi, - std::complex *spsi, + const std::complex* psi, + std::complex* spsi, const size_t size )const { - for (size_t i=0; i void hamilt::Hamilt>::sPsi +( + const std::complex* psi, + std::complex* spsi, + const size_t size +)const +{ + for (size_t i = 0; i < size; i++) { spsi[i] = psi[i]; } @@ -479,9 +429,10 @@ template<> void hamilt::HamiltPW>::sPsi //Mock function h_psi #include "module_hamilt_pw/hamilt_pwdft/operator_pw/operator_pw.h" -class OperatorMock_d : public hamilt::OperatorPW> +template +class OperatorMock : public hamilt::Operator { - ~OperatorMock_d() + ~OperatorMock() { if(this->hpsi != nullptr) { @@ -494,82 +445,123 @@ class OperatorMock_d : public hamilt::OperatorPW> const int nbands, const int nbasis, const int npol, - const std::complex* tmpsi_in, - std::complex* tmhpsi, - const int ngk_ik = 0)const + const T* tmpsi_in, + T* tmhpsi, + const int ngk_ik = 0)const; +}; +template<> +void OperatorMock::act( + const int nbands, + const int nbasis, + const int npol, + const double* tmpsi_in, + double* tmhpsi, + const int ngk_ik)const +{ + int nprocs = 1, mypnum = 0; +#ifdef __MPI + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); +#endif + + double* hpsi0 = new double[DIAGOTEST::npw]; + for (int m = 0; m < nbands; m++) { - int nprocs=1, mypnum=0; - #ifdef __MPI - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); - #endif - - std::complex *hpsi0 = new std::complex[DIAGOTEST::npw]; - for (int m = 0; m < nbands; m++) + for (int i = 0;i < DIAGOTEST::npw;i++) { - for(int i=0;i>(hpsi0, tmhpsi); - tmhpsi += nbasis; - tmpsi_in += nbasis; } - delete [] hpsi0; + Parallel_Reduce::reduce_pool(hpsi0, DIAGOTEST::npw); + DIAGOTEST::divide_psi(hpsi0, tmhpsi); + tmhpsi += nbasis; + tmpsi_in += nbasis; } -}; - -class OperatorMock_f : public hamilt::OperatorPW> + delete[] hpsi0; +} +template<> +void OperatorMock>::act( + const int nbands, + const int nbasis, + const int npol, + const std::complex* tmpsi_in, + std::complex* tmhpsi, + const int ngk_ik)const { - ~OperatorMock_f() + int nprocs = 1, mypnum = 0; +#ifdef __MPI + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); +#endif + + std::complex* hpsi0 = new std::complex[DIAGOTEST::npw]; + for (int m = 0; m < nbands; m++) { - if(this->hpsi != nullptr) + for (int i = 0;i < DIAGOTEST::npw;i++) { - delete this->hpsi; - this->hpsi = nullptr; + hpsi0[i] = 0.0; + for (int j = 0;j < (DIAGOTEST::npw_local[mypnum]);j++) + { + hpsi0[i] += DIAGOTEST::hmatrix_local[i * DIAGOTEST::h_nc + j] * tmpsi_in[j]; + } } + Parallel_Reduce::reduce_pool(hpsi0, DIAGOTEST::npw); + DIAGOTEST::divide_psi>(hpsi0, tmhpsi); + tmhpsi += nbasis; + tmpsi_in += nbasis; } - virtual void act - ( - const int nbands, - const int nbasis, - const int npol, - const std::complex* tmpsi_in, - std::complex* tmhpsi, - const int ngk_ik = 0)const + delete[] hpsi0; +} +template<> +void OperatorMock>::act( + const int nbands, + const int nbasis, + const int npol, + const std::complex* tmpsi_in, + std::complex* tmhpsi, + const int ngk_ik)const +{ + int nprocs = 1, mypnum = 0; +#ifdef __MPI + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); +#endif + + std::complex* hpsi0 = new std::complex[DIAGOTEST::npw]; + for (int m = 0; m < nbands; m++) { - int nprocs=1, mypnum=0; - #ifdef __MPI - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Comm_rank(MPI_COMM_WORLD, &mypnum); - #endif - - std::complex *hpsi0 = new std::complex[DIAGOTEST::npw]; - for (int m = 0; m < nbands; m++) + for (int i = 0;i < DIAGOTEST::npw;i++) { - for(int i=0;i>(hpsi0, tmhpsi); - tmhpsi += nbasis; - tmpsi_in += nbasis; } - delete [] hpsi0; + Parallel_Reduce::reduce_pool(hpsi0, DIAGOTEST::npw); + DIAGOTEST::divide_psi>(hpsi0, tmhpsi); + tmhpsi += nbasis; + tmpsi_in += nbasis; } -}; + delete[] hpsi0; +} +template<> void hamilt::HamiltPW::updateHk(const int ik) +{ + return; +} + +template<> hamilt::HamiltPW::HamiltPW(elecstate::Potential* pot_in, ModulePW::PW_Basis_K* wfc_basis, K_Vectors* pkv) +{ + this->ops = new OperatorMock; +} + +template<> hamilt::HamiltPW::~HamiltPW() +{ + delete this->ops; +} template<> void hamilt::HamiltPW>::updateHk(const int ik) { @@ -578,7 +570,7 @@ template<> void hamilt::HamiltPW>::updateHk(const int ik) template<> hamilt::HamiltPW>::HamiltPW(elecstate::Potential* pot_in, ModulePW::PW_Basis_K* wfc_basis, K_Vectors* pkv) { - this->ops = new OperatorMock_d; + this->ops = new OperatorMock>; } template<> hamilt::HamiltPW>::~HamiltPW() @@ -593,7 +585,7 @@ template<> void hamilt::HamiltPW>::updateHk(const int ik) template<> hamilt::HamiltPW>::HamiltPW(elecstate::Potential* pot_in, ModulePW::PW_Basis_K* wfc_basis, K_Vectors* pkv) { - this->ops = new OperatorMock_f; + this->ops = new OperatorMock>; } template<> hamilt::HamiltPW>::~HamiltPW() diff --git a/source/module_hsolver/test/hsolver_pw_sup.h b/source/module_hsolver/test/hsolver_pw_sup.h index 0c7ba15c938..bb83befb6c0 100644 --- a/source/module_hsolver/test/hsolver_pw_sup.h +++ b/source/module_hsolver/test/hsolver_pw_sup.h @@ -65,6 +65,11 @@ FFT::~FFT() #include "module_hsolver/diago_cg.h" #include "module_hsolver/diago_david.h" #include "module_hsolver/diago_iter_assist.h" + +template consts::consts() {} +template class consts>; +template class consts>; + namespace hsolver { @@ -168,7 +173,6 @@ void DiagoDavid::diag(hamilt::Hamilt* phm_in, DiagoIterAssist::avg_iter += 1.0; return; } - template class DiagoDavid, psi::DEVICE_CPU>; template class DiagoDavid, psi::DEVICE_CPU>; diff --git a/source/module_hsolver/test/test_hsolver.cpp b/source/module_hsolver/test/test_hsolver.cpp index 67340d6e452..ee02c20756b 100644 --- a/source/module_hsolver/test/test_hsolver.cpp +++ b/source/module_hsolver/test/test_hsolver.cpp @@ -35,16 +35,20 @@ template class hsolver::HSolver, psi::DEVICE_CPU>; class TestHSolver : public ::testing::Test { - public: - hsolver::HSolver, psi::DEVICE_CPU> hs_f; - hsolver::HSolver, psi::DEVICE_CPU> hs_d; - - hamilt::Hamilt> hamilt_test_d; - hamilt::Hamilt> hamilt_test_f; - +public: + hsolver::HSolver, psi::DEVICE_CPU> hs_cf; + hsolver::HSolver, psi::DEVICE_CPU> hs_cd; + hsolver::HSolver hs_f; + hsolver::HSolver hs_d; + + hamilt::Hamilt> hamilt_test_cd; + hamilt::Hamilt> hamilt_test_cf; psi::Psi> psi_test_cd; - psi::Psi> psi_test_cf; - psi::Psi psi_test_d; + psi::Psi> psi_test_cf; + + hamilt::Hamilt hamilt_test_d; + hamilt::Hamilt hamilt_test_f; + psi::Psi psi_test_d; psi::Psi psi_test_f; Stochastic_WF stowf_test; @@ -60,16 +64,16 @@ class TestHSolver : public ::testing::Test TEST_F(TestHSolver, solve) { - hs_f.solve(&hamilt_test_f, psi_test_cf, &elecstate_test, method_test, false); + hs_cf.solve(&hamilt_test_cf, psi_test_cf, &elecstate_test, method_test, false); hs_f.solve(&hamilt_test_f, psi_test_f, &elecstate_test, method_test, false); - hs_d.solve(&hamilt_test_d, psi_test_cd, &elecstate_test, method_test, false); + hs_cd.solve(&hamilt_test_cd, psi_test_cd, &elecstate_test, method_test, false); hs_d.solve(&hamilt_test_d, psi_test_d, &elecstate_test, method_test, false); - hs_f.solve(&hamilt_test_f, psi_test_cf, &elecstate_test, method_test, true); + hs_cf.solve(&hamilt_test_cf, psi_test_cf, &elecstate_test, method_test, true); hs_f.solve(&hamilt_test_f, psi_test_f, &elecstate_test, method_test, true); - hs_d.solve(&hamilt_test_d, psi_test_cd, &elecstate_test, method_test, true); + hs_cd.solve(&hamilt_test_cd, psi_test_cd, &elecstate_test, method_test, true); hs_d.solve(&hamilt_test_d, psi_test_d, &elecstate_test, method_test, true); - hs_f.solve(&hamilt_test_f, psi_test_cf, &elecstate_test, wfcpw, stowf_test, 0, 0, method_test, true); - hs_d.solve(&hamilt_test_d, psi_test_cd, &elecstate_test, wfcpw, stowf_test, 0, 0, method_test, true); + hs_cf.solve(&hamilt_test_cf, psi_test_cf, &elecstate_test, wfcpw, stowf_test, 0, 0, method_test, true); + hs_cd.solve(&hamilt_test_cd, psi_test_cd, &elecstate_test, wfcpw, stowf_test, 0, 0, method_test, true); EXPECT_EQ(hs_f.classname, "none"); EXPECT_EQ(hs_d.classname, "none"); EXPECT_EQ(hs_f.method, "none"); @@ -120,13 +124,21 @@ namespace hsolver TEST_F(TestHSolver, diagh) { - this->hs_f.pdiagh = new hsolver::DiagH_mock>; - //test DiagH::diag - this->hs_f.pdiagh->diag(nullptr, this->psi_test_f, nullptr); - EXPECT_EQ(this->hs_f.pdiagh->method, "none"); - this->hs_d.pdiagh = new hsolver::DiagH_mock>; - //test DiagH::diag - this->hs_d.pdiagh->diag(nullptr, this->psi_test_d, nullptr); - EXPECT_EQ(this->hs_d.pdiagh->method, "none"); - //test HSolver::~HSolver() it will delete pdiagh + //test DiagH::diag + this->hs_cf.pdiagh = new hsolver::DiagH_mock>; + this->hs_cf.pdiagh->diag(nullptr, this->psi_test_cf, nullptr); + EXPECT_EQ(this->hs_cf.pdiagh->method, "none"); + + this->hs_cd.pdiagh = new hsolver::DiagH_mock>; + this->hs_cd.pdiagh->diag(nullptr, this->psi_test_cd, nullptr); + EXPECT_EQ(this->hs_cd.pdiagh->method, "none"); + + this->hs_f.pdiagh = new hsolver::DiagH_mock; + this->hs_f.pdiagh->diag(nullptr, this->psi_test_f, nullptr); + EXPECT_EQ(this->hs_f.pdiagh->method, "none"); + + this->hs_d.pdiagh = new hsolver::DiagH_mock; + this->hs_d.pdiagh->diag(nullptr, this->psi_test_d, nullptr); + EXPECT_EQ(this->hs_d.pdiagh->method, "none"); + //test HSolver::~HSolver() it will delete pdiagh } \ No newline at end of file diff --git a/source/module_io/berryphase.h b/source/module_io/berryphase.h index c216c39e657..b2d056f2ecc 100644 --- a/source/module_io/berryphase.h +++ b/source/module_io/berryphase.h @@ -59,10 +59,17 @@ class berryphase const K_Vectors& kv); void Macroscopic_polarization(const int npwx, - const psi::Psi>* psi_in, - const ModulePW::PW_Basis* rhopw, - const ModulePW::PW_Basis_K* wfcpw, - const K_Vectors& kv); + const psi::Psi* psi_in, + const ModulePW::PW_Basis* rhopw, + const ModulePW::PW_Basis_K* wfcpw, + const K_Vectors& kv) { + throw std::logic_error("berry phase supports only multi-k"); + }; + void Macroscopic_polarization(const int npwx, + const psi::Psi>* psi_in, + const ModulePW::PW_Basis* rhopw, + const ModulePW::PW_Basis_K* wfcpw, + const K_Vectors& kv); std::string outFormat(const double polarization, const double modulus, const ModuleBase::Vector3 project); diff --git a/source/module_io/cal_r_overlap_R.cpp b/source/module_io/cal_r_overlap_R.cpp index deef52bdef8..2743c99b6c6 100644 --- a/source/module_io/cal_r_overlap_R.cpp +++ b/source/module_io/cal_r_overlap_R.cpp @@ -358,7 +358,7 @@ void cal_r_overlap_R::out_rR(const int &istep) } } - Parallel_Reduce::reduce_int_all(rR_nonzero_num, 3); + Parallel_Reduce::reduce_all(rR_nonzero_num, 3); if (rR_nonzero_num[0] || rR_nonzero_num[1] || rR_nonzero_num[2]) { @@ -595,7 +595,7 @@ void cal_r_overlap_R::out_rR_other(const int &istep, const std::set* psid, - const psi::Psi>* psi, - LCAO_Hamilt& uhm, - const ModuleBase::matrix& ekb, - const ModuleBase::matrix& wg, - const double& dos_edelta_ev, - const double& dos_scale, - const double& dos_sigma, - const K_Vectors& kv, - const Parallel_Kpoints& Pkpoints, - const UnitCell& ucell, - const elecstate::efermi& eferm, - int nbands, - hamilt::Hamilt>* p_ham) + template + void out_dos_nao( + const psi::Psi* psi, + LCAO_Hamilt& uhm, + const ModuleBase::matrix& ekb, + const ModuleBase::matrix& wg, + const double& dos_edelta_ev, + const double& dos_scale, + const double& dos_sigma, + const K_Vectors& kv, + const Parallel_Kpoints& Pkpoints, + const UnitCell& ucell, + const elecstate::efermi& eferm, + int nbands, + hamilt::Hamilt* p_ham) { ModuleBase::TITLE("Driver", "init"); - write_dos_lcao(psid, psi, uhm, ekb, wg, dos_edelta_ev, dos_scale, dos_sigma, kv, p_ham); + write_dos_lcao(psi, uhm, ekb, wg, dos_edelta_ev, dos_scale, dos_sigma, kv, p_ham); int nspin0 = (GlobalV::NSPIN == 2) ? 2 : 1; if (INPUT.out_dos == 3) @@ -57,5 +57,32 @@ void out_dos_nao(const psi::Psi* psid, GlobalV::ofs_running << " Fermi energy (spin = 1) is " << eferm.ef_up << " Rydberg" << std::endl; GlobalV::ofs_running << " Fermi energy (spin = 2) is " << eferm.ef_dw << " Rydberg" << std::endl; } -} + } + + template void out_dos_nao(const psi::Psi* psi, + LCAO_Hamilt& uhm, + const ModuleBase::matrix& ekb, + const ModuleBase::matrix& wg, + const double& dos_edelta_ev, + const double& dos_scale, + const double& dos_sigma, + const K_Vectors& kv, + const Parallel_Kpoints& Pkpoints, + const UnitCell& ucell, + const elecstate::efermi& eferm, + int nbands, + hamilt::Hamilt* p_ham); + template void out_dos_nao(const psi::Psi>* psi, + LCAO_Hamilt& uhm, + const ModuleBase::matrix& ekb, + const ModuleBase::matrix& wg, + const double& dos_edelta_ev, + const double& dos_scale, + const double& dos_sigma, + const K_Vectors& kv, + const Parallel_Kpoints& Pkpoints, + const UnitCell& ucell, + const elecstate::efermi& eferm, + int nbands, + hamilt::Hamilt>* p_ham); } // namespace ModuleIO \ No newline at end of file diff --git a/source/module_io/dos_nao.h b/source/module_io/dos_nao.h index 1566095a781..dd86fc86ae8 100644 --- a/source/module_io/dos_nao.h +++ b/source/module_io/dos_nao.h @@ -7,8 +7,9 @@ namespace ModuleIO { -void out_dos_nao(const psi::Psi* psid, - const psi::Psi>* psi, + template + void out_dos_nao( + const psi::Psi* psi, LCAO_Hamilt& uhm, const ModuleBase::matrix& ekb, const ModuleBase::matrix& wg, @@ -20,7 +21,7 @@ void out_dos_nao(const psi::Psi* psid, const UnitCell& ucell, const elecstate::efermi& eferm, int nbands, - hamilt::Hamilt>* p_ham); + hamilt::Hamilt* p_ham); } #endif \ No newline at end of file diff --git a/source/module_io/input_conv.cpp b/source/module_io/input_conv.cpp index 10fed05f59d..7676d45dd6d 100644 --- a/source/module_io/input_conv.cpp +++ b/source/module_io/input_conv.cpp @@ -294,7 +294,8 @@ void Input_Conv::Convert(void) GlobalV::PRESS3 = INPUT.press3; GlobalV::out_element_info = INPUT.out_element_info; #ifdef __LCAO - Force_Stress_LCAO::force_invalid_threshold_ev = INPUT.force_thr_ev2; + Force_Stress_LCAO::force_invalid_threshold_ev = INPUT.force_thr_ev2; + Force_Stress_LCAO>::force_invalid_threshold_ev = INPUT.force_thr_ev2; #endif BFGS_Basic::relax_bfgs_w1 = INPUT.relax_bfgs_w1; @@ -622,10 +623,14 @@ void Input_Conv::Convert(void) #ifdef __LCAO Local_Orbital_Charge::out_dm = INPUT.out_dm; Local_Orbital_Charge::out_dm1 = INPUT.out_dm1; - hsolver::HSolverLCAO::out_mat_hs = INPUT.out_mat_hs; - hsolver::HSolverLCAO::out_mat_hsR = INPUT.out_mat_hs2; // LiuXh add 2019-07-16 - hsolver::HSolverLCAO::out_mat_t = INPUT.out_mat_t; - hsolver::HSolverLCAO::out_mat_dh = INPUT.out_mat_dh; + hsolver::HSolverLCAO::out_mat_hs = INPUT.out_mat_hs; + hsolver::HSolverLCAO::out_mat_hsR = INPUT.out_mat_hs2; // LiuXh add 2019-07-16 + hsolver::HSolverLCAO::out_mat_t = INPUT.out_mat_t; + hsolver::HSolverLCAO::out_mat_dh = INPUT.out_mat_dh; + hsolver::HSolverLCAO>::out_mat_hs = INPUT.out_mat_hs; + hsolver::HSolverLCAO>::out_mat_hsR = INPUT.out_mat_hs2; // LiuXh add 2019-07-16 + hsolver::HSolverLCAO>::out_mat_t = INPUT.out_mat_t; + hsolver::HSolverLCAO>::out_mat_dh = INPUT.out_mat_dh; if (GlobalV::GAMMA_ONLY_LOCAL) { elecstate::ElecStateLCAO::out_wfc_lcao = INPUT.out_wfc_lcao; diff --git a/source/module_io/istate_charge.h b/source/module_io/istate_charge.h index 80a6e013aa6..b0ee05bd35f 100644 --- a/source/module_io/istate_charge.h +++ b/source/module_io/istate_charge.h @@ -9,12 +9,19 @@ #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h" #include "module_hamilt_lcao/module_gint/gint_gamma.h" #include "module_psi/psi.h" +#include class IState_Charge { public: IState_Charge(psi::Psi* psi_gamma_in, - Local_Orbital_Charge &loc_in); + Local_Orbital_Charge& loc_in); + IState_Charge(psi::Psi>* psi_k_in, + Local_Orbital_Charge& loc_in) + { + throw std::logic_error("IState_Charge for multi-k is not implemented."); + }; + ~IState_Charge(); void begin(Gint_Gamma& gg, diff --git a/source/module_io/istate_envelope.h b/source/module_io/istate_envelope.h index c3cd65a1aa3..6328951b06d 100644 --- a/source/module_io/istate_envelope.h +++ b/source/module_io/istate_envelope.h @@ -8,7 +8,7 @@ #include "module_hamilt_lcao/module_gint/gint_k.h" #include "module_hamilt_pw/hamilt_pwdft/structure_factor.h" #include "module_psi/psi.h" - +#include class IState_Envelope { public: @@ -24,7 +24,21 @@ class IState_Envelope Gint_Gamma& gg, int& out_wfc_pw, int& out_wfc_r, - const K_Vectors& kv); + const K_Vectors& kv); + + + /// tmp, delete after Gint is refactored. + void begin(const psi::Psi* psid, + const ModulePW::PW_Basis* rhopw, + const ModulePW::PW_Basis_K* wfcpw, + const ModulePW::PW_Basis_Big* bigpw, + Local_Orbital_wfc& lowf, + Gint_k& gg, + int& out_wfc_pw, + int& out_wfc_r, + const K_Vectors& kv) { + throw std::logic_error("gint_k should use with complex psi."); + }; /// for multi-k void begin(const psi::Psi>* psi, const ModulePW::PW_Basis* rhopw, @@ -36,6 +50,19 @@ class IState_Envelope int& out_wfc_r, const K_Vectors& kv); + /// tmp, delete after Gint is refactored. + void begin(const psi::Psi>* psi, + const ModulePW::PW_Basis* rhopw, + const ModulePW::PW_Basis_K* wfcpw, + const ModulePW::PW_Basis_Big* bigpw, + Local_Orbital_wfc& lowf, + Gint_Gamma& gk, + int& out_wfc_pw, + int& out_wfc_r, + const K_Vectors& kv) { + throw std::logic_error("gint_gamma should use with real psi."); + }; + private: bool* bands_picked = nullptr; const elecstate::ElecState* pes = nullptr; diff --git a/source/module_io/mulliken_charge.cpp b/source/module_io/mulliken_charge.cpp index 40df32e3927..c9662721cf9 100644 --- a/source/module_io/mulliken_charge.cpp +++ b/source/module_io/mulliken_charge.cpp @@ -20,9 +20,9 @@ #include "write_orb_info.h" #include "module_elecstate/elecstate_lcao.h" - +template<> ModuleBase::matrix ModuleIO::cal_mulliken(const std::vector> &dm, - LCAO_Matrix *LM + LCAO_Matrix* LM, const K_Vectors& kv, hamilt::Hamilt* ham_in ) { ModuleBase::TITLE("Mulliken_Charge", "cal_mulliken"); @@ -120,7 +120,8 @@ ModuleBase::matrix ModuleIO::cal_mulliken(const std::vector> return orbMulP; } -ModuleBase::matrix ModuleIO::cal_mulliken_k(const std::vector>> &dm, +template<> +ModuleBase::matrix ModuleIO::cal_mulliken(const std::vector>>& dm, LCAO_Matrix* LM, const K_Vectors& kv, hamilt::Hamilt>* ham_in ) { @@ -260,23 +261,15 @@ std::vector>> ModuleIO::convert(const ModuleBase return AorbMulP; } -void ModuleIO::out_mulliken(const int& step, LCAO_Matrix *LM, const elecstate::ElecState* pelec, const K_Vectors& kv, hamilt::Hamilt>* ham_in) +template +void ModuleIO::out_mulliken(const int& step, LCAO_Matrix* LM, const elecstate::ElecState* pelec, const K_Vectors& kv, hamilt::Hamilt* ham_in) { ModuleBase::TITLE("Mulliken_Charge", "out_mulliken"); ModuleBase::matrix orbMulP; - if(GlobalV::GAMMA_ONLY_LOCAL) - { - const std::vector>& dm_gamma = - dynamic_cast*> (pelec)->get_DM()->get_DMK_vector(); - orbMulP = ModuleIO::cal_mulliken(dm_gamma, LM); - } - else - { - const std::vector>>& dm_k = - dynamic_cast>*> (pelec)->get_DM()->get_DMK_vector(); - orbMulP = ModuleIO::cal_mulliken_k(dm_k, LM, kv, ham_in); - } + const std::vector>& dm = + dynamic_cast*> (pelec)->get_DM()->get_DMK_vector(); + orbMulP = ModuleIO::cal_mulliken(dm, LM, kv, ham_in); std::vector>> AorbMulP = ModuleIO::convert(orbMulP); @@ -449,4 +442,6 @@ void ModuleIO::out_mulliken(const int& step, LCAO_Matrix *LM, const elecstate::E os.close(); ModuleIO::write_orb_info(&(GlobalC::ucell)); } -} \ No newline at end of file +} +template void ModuleIO::out_mulliken(const int& step, LCAO_Matrix* LM, const elecstate::ElecState* pelec, const K_Vectors& kv, hamilt::Hamilt* ham_in); +template void ModuleIO::out_mulliken(const int& step, LCAO_Matrix* LM, const elecstate::ElecState* pelec, const K_Vectors& kv, hamilt::Hamilt>* ham_in); \ No newline at end of file diff --git a/source/module_io/mulliken_charge.h b/source/module_io/mulliken_charge.h index 8d04c82780a..c1fa62cc1bc 100644 --- a/source/module_io/mulliken_charge.h +++ b/source/module_io/mulliken_charge.h @@ -13,7 +13,8 @@ // convert to namespace, liuyu 2023-04-18 namespace ModuleIO { - void out_mulliken(const int& step, LCAO_Matrix *LM, const elecstate::ElecState* pelec, const K_Vectors& kv, hamilt::Hamilt>* ham_in); + template + void out_mulliken(const int& step, LCAO_Matrix* LM, const elecstate::ElecState* pelec, const K_Vectors& kv, hamilt::Hamilt* ham_in); /* 1. cal_mulliken: for gamma-only @@ -25,13 +26,11 @@ namespace ModuleIO return ModuleBase::matrix with shape (GlobalV::NSPIN, GlobalV::NLOCAL/2) */ - ModuleBase::matrix cal_mulliken(const std::vector> &dm, - LCAO_Matrix *LM + template + ModuleBase::matrix cal_mulliken(const std::vector>& dm, + LCAO_Matrix* LM, const K_Vectors& kv, hamilt::Hamilt* ham_in ); - ModuleBase::matrix cal_mulliken_k(const std::vector>> &dm, - LCAO_Matrix *LM, const K_Vectors& kv, hamilt::Hamilt>* ham_in - ); std::vector>> convert(const ModuleBase::matrix &orbMulP); diff --git a/source/module_io/numerical_basis.cpp b/source/module_io/numerical_basis.cpp index 9d2e12dc2bd..2a21d6be46f 100644 --- a/source/module_io/numerical_basis.cpp +++ b/source/module_io/numerical_basis.cpp @@ -134,10 +134,10 @@ void Numerical_Basis::output_overlap(const psi::Psi>& psi, #ifdef __MPI for (int ik = 0; ik < kv.nks; ik++) { - Parallel_Reduce::reduce_complex_double_pool( overlap_Q[ik].ptr, overlap_Q[ik].getSize() ); - Parallel_Reduce::reduce_complex_double_pool( overlap_Sq[ik].ptr, overlap_Sq[ik].getSize() ); + Parallel_Reduce::reduce_pool(overlap_Q[ik].ptr, overlap_Q[ik].getSize()); + Parallel_Reduce::reduce_pool(overlap_Sq[ik].ptr, overlap_Sq[ik].getSize()); } - Parallel_Reduce::reduce_double_pool(overlap_V.c, overlap_V.nr*overlap_V.nc); // Peize Lin add 2020.04.23 + Parallel_Reduce::reduce_pool(overlap_V.c, overlap_V.nr * overlap_V.nc); // Peize Lin add 2020.04.23 #endif this->output_info(ofs, bessel_basis, kv); diff --git a/source/module_io/output_mat_sparse.cpp b/source/module_io/output_mat_sparse.cpp index 27a2a145720..693528a43ee 100644 --- a/source/module_io/output_mat_sparse.cpp +++ b/source/module_io/output_mat_sparse.cpp @@ -6,17 +6,18 @@ namespace ModuleIO { -Output_Mat_Sparse::Output_Mat_Sparse(int out_mat_hsR, - int out_mat_dh, - int out_mat_t, - int out_mat_r, - int istep, - const ModuleBase::matrix& v_eff, - const Parallel_Orbitals& pv, - LCAO_Hamilt& UHM, - LCAO_Matrix& LM, - const K_Vectors& kv, - hamilt::Hamilt>* p_ham) + template + Output_Mat_Sparse::Output_Mat_Sparse(int out_mat_hsR, + int out_mat_dh, + int out_mat_t, + int out_mat_r, + int istep, + const ModuleBase::matrix& v_eff, + const Parallel_Orbitals& pv, + LCAO_Hamilt& UHM, + LCAO_Matrix& LM, + const K_Vectors& kv, + hamilt::Hamilt* p_ham) : _out_mat_hsR(out_mat_hsR), _out_mat_dh(out_mat_dh), _out_mat_t(out_mat_t), @@ -29,9 +30,11 @@ Output_Mat_Sparse::Output_Mat_Sparse(int out_mat_hsR, _kv(kv), _p_ham(p_ham) { -} - -void Output_Mat_Sparse::write() + } + template<> + void Output_Mat_Sparse::write() {} + template<> + void Output_Mat_Sparse>::write() { if (_out_mat_hsR) { @@ -64,4 +67,6 @@ void Output_Mat_Sparse::write() } } + template class Output_Mat_Sparse; + template class Output_Mat_Sparse>; } // namespace ModuleIO \ No newline at end of file diff --git a/source/module_io/output_mat_sparse.h b/source/module_io/output_mat_sparse.h index 6670a7aa257..4d5bcde5c26 100644 --- a/source/module_io/output_mat_sparse.h +++ b/source/module_io/output_mat_sparse.h @@ -9,21 +9,22 @@ namespace ModuleIO { -/// @brief the output interface to write the sparse matrix of H, S, T, and r -class Output_Mat_Sparse : public Output_Interface + /// @brief the output interface to write the sparse matrix of H, S, T, and r + template + class Output_Mat_Sparse : public Output_Interface { public: Output_Mat_Sparse(int out_mat_hsR, - int out_mat_dh, - int out_mat_t, - int out_mat_r, - int istep, - const ModuleBase::matrix& v_eff, - const Parallel_Orbitals& pv, - LCAO_Hamilt& UHM, - LCAO_Matrix& LM, - const K_Vectors& kv, - hamilt::Hamilt>* p_ham); + int out_mat_dh, + int out_mat_t, + int out_mat_r, + int istep, + const ModuleBase::matrix& v_eff, + const Parallel_Orbitals& pv, + LCAO_Hamilt& UHM, + LCAO_Matrix& LM, + const K_Vectors& kv, + hamilt::Hamilt* p_ham); void write() override; private: @@ -37,7 +38,7 @@ class Output_Mat_Sparse : public Output_Interface LCAO_Hamilt& _UHM; LCAO_Matrix& _LM; const K_Vectors& _kv; - hamilt::Hamilt>* _p_ham; + hamilt::Hamilt* _p_ham; }; } // namespace ModuleIO diff --git a/source/module_io/single_R_io.cpp b/source/module_io/single_R_io.cpp index d40b298b186..c278d177829 100644 --- a/source/module_io/single_R_io.cpp +++ b/source/module_io/single_R_io.cpp @@ -45,7 +45,7 @@ void ModuleIO::output_single_R(std::ofstream &ofs, const std::map::need_psi_grid = 1; template<> bool elecstate::ElecStateLCAO>::need_psi_grid = 1; // -int hsolver::HSolverLCAO::out_mat_hs = 0; -int hsolver::HSolverLCAO::out_mat_hsR = 0; -int hsolver::HSolverLCAO::out_mat_t = 0; -int hsolver::HSolverLCAO::out_mat_dh = 0; +template<> +int hsolver::HSolverLCAO::out_mat_hs = 0; +template<> +int hsolver::HSolverLCAO>::out_mat_hs = 0; +template<> +int hsolver::HSolverLCAO::out_mat_hsR = 0; +template<> +int hsolver::HSolverLCAO>::out_mat_hsR = 0; +template<> +int hsolver::HSolverLCAO::out_mat_t = 0; +template<> +int hsolver::HSolverLCAO>::out_mat_t = 0; +template<> +int hsolver::HSolverLCAO::out_mat_dh = 0; +template<> +int hsolver::HSolverLCAO > ::out_mat_dh = 0; int Local_Orbital_Charge::out_dm = 0; int Local_Orbital_Charge::out_dm1 = 0; double module_tddft::Evolve_elec::td_force_dt; @@ -115,7 +127,10 @@ int elecstate::H_TDDFT_pw::heavi_count; std::vector elecstate::H_TDDFT_pw::heavi_t0; std::vector elecstate::H_TDDFT_pw::heavi_amp; // Ry/bohr -double Force_Stress_LCAO::force_invalid_threshold_ev = 0.0; +template<> +double Force_Stress_LCAO::force_invalid_threshold_ev = 0.0; +template<> +double Force_Stress_LCAO>::force_invalid_threshold_ev = 0.0; double BFGS_Basic::relax_bfgs_w1 = -1.0; double BFGS_Basic::relax_bfgs_w2 = -1.0; double Ions_Move_Basic::relax_bfgs_rmax = -1.0; diff --git a/source/module_io/test/input_conv_test.cpp b/source/module_io/test/input_conv_test.cpp index b29d83fc232..e78f2ffde49 100644 --- a/source/module_io/test/input_conv_test.cpp +++ b/source/module_io/test/input_conv_test.cpp @@ -64,8 +64,9 @@ TEST_F(InputConvTest, Conv) EXPECT_EQ(GlobalV::PRESS2,0); EXPECT_EQ(GlobalV::PRESS3,0); EXPECT_EQ(GlobalV::out_element_info,0); - EXPECT_EQ(Force_Stress_LCAO::force_invalid_threshold_ev,0); - EXPECT_DOUBLE_EQ(BFGS_Basic::relax_bfgs_w1,0.01); + EXPECT_EQ(Force_Stress_LCAO::force_invalid_threshold_ev, 0); + EXPECT_EQ(Force_Stress_LCAO>::force_invalid_threshold_ev, 0); + EXPECT_DOUBLE_EQ(BFGS_Basic::relax_bfgs_w1, 0.01); EXPECT_DOUBLE_EQ(BFGS_Basic::relax_bfgs_w2,0.5); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_rmax,0.8); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_rmin,0.00001); @@ -144,11 +145,15 @@ TEST_F(InputConvTest, Conv) EXPECT_EQ(GlobalV::out_bandgap, false); EXPECT_EQ(Local_Orbital_Charge::out_dm,false); EXPECT_EQ(Local_Orbital_Charge::out_dm1,false); - EXPECT_EQ(hsolver::HSolverLCAO::out_mat_hs,false); - EXPECT_EQ( hsolver::HSolverLCAO::out_mat_hsR,false); - EXPECT_EQ(hsolver::HSolverLCAO::out_mat_t,false); - EXPECT_EQ(hsolver::HSolverLCAO::out_mat_dh,INPUT.out_mat_dh); - EXPECT_EQ(GlobalV::out_interval,1); + EXPECT_EQ(hsolver::HSolverLCAO::out_mat_hs, false); + EXPECT_EQ(hsolver::HSolverLCAO>::out_mat_hs, false); + EXPECT_EQ(hsolver::HSolverLCAO::out_mat_hsR, false); + EXPECT_EQ(hsolver::HSolverLCAO>::out_mat_hsR, false); + EXPECT_EQ(hsolver::HSolverLCAO::out_mat_t, false); + EXPECT_EQ(hsolver::HSolverLCAO>::out_mat_t, false); + EXPECT_EQ(hsolver::HSolverLCAO::out_mat_dh, INPUT.out_mat_dh); + EXPECT_EQ(hsolver::HSolverLCAO>::out_mat_dh, INPUT.out_mat_dh); + EXPECT_EQ(GlobalV::out_interval, 1); EXPECT_EQ(elecstate::ElecStateLCAO::out_wfc_lcao, false); EXPECT_EQ(berryphase::berry_phase_flag, false); EXPECT_EQ(GlobalV::imp_sol,false); diff --git a/source/module_io/write_HS.cpp b/source/module_io/write_HS.cpp index c56d8f7085d..0e677f8f6d9 100644 --- a/source/module_io/write_HS.cpp +++ b/source/module_io/write_HS.cpp @@ -215,8 +215,8 @@ void ModuleIO::save_HS_triangle(const int istep, // do nothing } - Parallel_Reduce::reduce_double_all(lineH, GlobalV::NLOCAL - i); - Parallel_Reduce::reduce_double_all(lineS, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_all(lineH, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_all(lineS, GlobalV::NLOCAL - i); if (GlobalV::DRANK == 0) { @@ -316,8 +316,8 @@ void ModuleIO::save_HS_triangle(const int istep, // do nothing } - Parallel_Reduce::reduce_double_all(lineH, GlobalV::NLOCAL - i); - Parallel_Reduce::reduce_double_all(lineS, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_all(lineH, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_all(lineS, GlobalV::NLOCAL - i); if (GlobalV::DRANK == 0) { @@ -459,8 +459,8 @@ void ModuleIO::save_HS_complete(const int istep, // do nothing } - Parallel_Reduce::reduce_double_all(lineH, GlobalV::NLOCAL); - Parallel_Reduce::reduce_double_all(lineS, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineH, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineS, GlobalV::NLOCAL); if (GlobalV::DRANK == 0) { @@ -560,8 +560,8 @@ void ModuleIO::save_HS_complete(const int istep, // do nothing } - Parallel_Reduce::reduce_double_all(lineH, GlobalV::NLOCAL); - Parallel_Reduce::reduce_double_all(lineS, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineH, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineS, GlobalV::NLOCAL); if (GlobalV::DRANK == 0) { @@ -735,8 +735,8 @@ void ModuleIO::save_HS_complex_triangle(const int istep, // do nothing } - Parallel_Reduce::reduce_complex_double_pool(lineH, GlobalV::NLOCAL - i); - Parallel_Reduce::reduce_complex_double_pool(lineS, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_pool(lineH, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_pool(lineS, GlobalV::NLOCAL - i); if (GlobalV::DRANK == 0) { @@ -836,8 +836,8 @@ void ModuleIO::save_HS_complex_triangle(const int istep, // do nothing } - Parallel_Reduce::reduce_complex_double_pool(lineH, GlobalV::NLOCAL - i); - Parallel_Reduce::reduce_complex_double_pool(lineS, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_pool(lineH, GlobalV::NLOCAL - i); + Parallel_Reduce::reduce_pool(lineS, GlobalV::NLOCAL - i); if (GlobalV::DRANK == 0) { @@ -980,8 +980,8 @@ void ModuleIO::save_HS_complex_complete(const int istep, // do nothing } - Parallel_Reduce::reduce_complex_double_pool(lineH, GlobalV::NLOCAL); - Parallel_Reduce::reduce_complex_double_pool(lineS, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(lineH, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(lineS, GlobalV::NLOCAL); if (GlobalV::DRANK == 0) { @@ -1081,8 +1081,8 @@ void ModuleIO::save_HS_complex_complete(const int istep, // do nothing } - Parallel_Reduce::reduce_complex_double_pool(lineH, GlobalV::NLOCAL); - Parallel_Reduce::reduce_complex_double_pool(lineS, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(lineH, GlobalV::NLOCAL); + Parallel_Reduce::reduce_pool(lineS, GlobalV::NLOCAL); if (GlobalV::DRANK == 0) { @@ -1257,17 +1257,17 @@ void ModuleIO::save_HSR_tr(const int current_spin, LCAO_Matrix &lm) // do nothing } - // Parallel_Reduce::reduce_double_all(lineH,GlobalV::NLOCAL-i); - // Parallel_Reduce::reduce_double_all(lineS,GlobalV::NLOCAL-i); + // Parallel_Reduce::reduce_all(lineH,GlobalV::NLOCAL-i); + // Parallel_Reduce::reduce_all(lineS,GlobalV::NLOCAL-i); if (GlobalV::NSPIN != 4) { - Parallel_Reduce::reduce_double_all(lineH, GlobalV::NLOCAL); - Parallel_Reduce::reduce_double_all(lineS, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineH, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineS, GlobalV::NLOCAL); } else { - Parallel_Reduce::reduce_complex_double_all(lineH_soc, GlobalV::NLOCAL); - Parallel_Reduce::reduce_complex_double_all(lineS_soc, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineH_soc, GlobalV::NLOCAL); + Parallel_Reduce::reduce_all(lineS_soc, GlobalV::NLOCAL); } if (GlobalV::DRANK == 0) diff --git a/source/module_io/write_HS_sparse.cpp b/source/module_io/write_HS_sparse.cpp index f67f209be61..89a10e1dfbf 100644 --- a/source/module_io/write_HS_sparse.cpp +++ b/source/module_io/write_HS_sparse.cpp @@ -96,10 +96,10 @@ void ModuleIO::save_HSR_sparse( count++; } - Parallel_Reduce::reduce_int_all(S_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(S_nonzero_num, total_R_num); for (int ispin = 0; ispin < spin_loop; ++ispin) { - Parallel_Reduce::reduce_int_all(H_nonzero_num[ispin], total_R_num); + Parallel_Reduce::reduce_all(H_nonzero_num[ispin], total_R_num); } if (GlobalV::NSPIN == 2) @@ -388,7 +388,7 @@ void ModuleIO::save_SR_sparse( count++; } - Parallel_Reduce::reduce_int_all(S_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(S_nonzero_num, total_R_num); for (int index = 0; index < total_R_num; ++index) { @@ -525,7 +525,7 @@ void ModuleIO::save_TR_sparse( count++; } - Parallel_Reduce::reduce_int_all(T_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(T_nonzero_num, total_R_num); for (int index = 0; index < total_R_num; ++index) { @@ -718,9 +718,9 @@ void ModuleIO::save_dH_sparse( for (int ispin = 0; ispin < spin_loop; ++ispin) { - Parallel_Reduce::reduce_int_all(dHx_nonzero_num[ispin], total_R_num); - Parallel_Reduce::reduce_int_all(dHy_nonzero_num[ispin], total_R_num); - Parallel_Reduce::reduce_int_all(dHz_nonzero_num[ispin], total_R_num); + Parallel_Reduce::reduce_all(dHx_nonzero_num[ispin], total_R_num); + Parallel_Reduce::reduce_all(dHy_nonzero_num[ispin], total_R_num); + Parallel_Reduce::reduce_all(dHz_nonzero_num[ispin], total_R_num); } if (GlobalV::NSPIN == 2) diff --git a/source/module_io/write_dipole.cpp b/source/module_io/write_dipole.cpp index 59dc660b5a1..eb2a39a8844 100644 --- a/source/module_io/write_dipole.cpp +++ b/source/module_io/write_dipole.cpp @@ -55,9 +55,9 @@ void ModuleIO::write_dipole(const double* rho_save, dipole_elec_x *= GlobalC::ucell.omega / static_cast(rhopw->nxyz); dipole_elec_y *= GlobalC::ucell.omega / static_cast(rhopw->nxyz); dipole_elec_z *= GlobalC::ucell.omega / static_cast(rhopw->nxyz); - Parallel_Reduce::reduce_double_pool(dipole_elec_x); - Parallel_Reduce::reduce_double_pool(dipole_elec_y); - Parallel_Reduce::reduce_double_pool(dipole_elec_z); + Parallel_Reduce::reduce_pool(dipole_elec_x); + Parallel_Reduce::reduce_pool(dipole_elec_y); + Parallel_Reduce::reduce_pool(dipole_elec_z); ofs << istep << " " << dipole_elec_x << " " << dipole_elec_y << dipole_elec_z; #else @@ -78,9 +78,9 @@ void ModuleIO::write_dipole(const double* rho_save, dipole_elec[2] += rho_save[ir] * z; } - Parallel_Reduce::reduce_double_pool(dipole_elec[0]); - Parallel_Reduce::reduce_double_pool(dipole_elec[1]); - Parallel_Reduce::reduce_double_pool(dipole_elec[2]); + Parallel_Reduce::reduce_pool(dipole_elec[0]); + Parallel_Reduce::reduce_pool(dipole_elec[1]); + Parallel_Reduce::reduce_pool(dipole_elec[2]); for (int i = 0; i < 3; ++i) { dipole_elec[i] *= GlobalC::ucell.lat0 / bmod[i] * GlobalC::ucell.omega / rhopw->nxyz; diff --git a/source/module_io/write_dm.cpp b/source/module_io/write_dm.cpp index b33271cd6c3..e2deb9596a9 100644 --- a/source/module_io/write_dm.cpp +++ b/source/module_io/write_dm.cpp @@ -144,7 +144,7 @@ void ModuleIO::write_dm( } } } - Parallel_Reduce::reduce_int_all( count, GlobalV::NLOCAL ); + Parallel_Reduce::reduce_all(count, GlobalV::NLOCAL); // reduce the density matrix for 'i' line. ModuleBase::GlobalFunc::ZEROS(tmp, GlobalV::NLOCAL); @@ -160,7 +160,7 @@ void ModuleIO::write_dm( } } } - Parallel_Reduce::reduce_double_all( tmp, GlobalV::NLOCAL ); + Parallel_Reduce::reduce_all(tmp, GlobalV::NLOCAL); if(GlobalV::MY_RANK==0) { diff --git a/source/module_io/write_dm_sparse.cpp b/source/module_io/write_dm_sparse.cpp index 76b09707b08..f6851a9cf8a 100644 --- a/source/module_io/write_dm_sparse.cpp +++ b/source/module_io/write_dm_sparse.cpp @@ -171,7 +171,7 @@ void ModuleIO::write_dm_sparse(const int &is, const int &istep, const Parallel_O count++; } - Parallel_Reduce::reduce_int_all(DMR_nonzero_num, total_R_num); + Parallel_Reduce::reduce_all(DMR_nonzero_num, total_R_num); for (int index = 0; index < total_R_num; ++index) { diff --git a/source/module_io/write_dos_lcao.cpp b/source/module_io/write_dos_lcao.cpp index 67dd9e9e8f9..8decbc96757 100644 --- a/source/module_io/write_dos_lcao.cpp +++ b/source/module_io/write_dos_lcao.cpp @@ -28,16 +28,17 @@ #include "module_base/parallel_reduce.h" #include "module_base/scalapack_connector.h" -void ModuleIO::write_dos_lcao(const psi::Psi* psid, - const psi::Psi>* psi, - LCAO_Hamilt& uhm, - const ModuleBase::matrix& ekb, - const ModuleBase::matrix& wg, - const double& dos_edelta_ev, - const double& dos_scale, - const double& bcoeff, - const K_Vectors& kv, - hamilt::Hamilt>* p_ham) +template <> +void ModuleIO::write_dos_lcao( + const psi::Psi* psi, + LCAO_Hamilt& uhm, + const ModuleBase::matrix& ekb, + const ModuleBase::matrix& wg, + const double& dos_edelta_ev, + const double& dos_scale, + const double& bcoeff, + const K_Vectors& kv, + hamilt::Hamilt* p_ham) { ModuleBase::TITLE("ModuleIO", "write_dos_lcao"); @@ -113,73 +114,312 @@ void ModuleIO::write_dos_lcao(const psi::Psi* psid, for (int is = 0; is < nspin0; ++is) { - if (GlobalV::GAMMA_ONLY_LOCAL) + + std::vector Mulk; + Mulk.resize(1); + Mulk[0].create(pv->ncol, pv->nrow); + + psi->fix_k(is); + const double* ppsi = psi->get_pointer(); + for (int i = 0; i < GlobalV::NBANDS; ++i) { - std::vector Mulk; - Mulk.resize(1); - Mulk[0].create(pv->ncol, pv->nrow); + ModuleBase::GlobalFunc::ZEROS(waveg, GlobalV::NLOCAL); - psid->fix_k(is); - const double* ppsi = psid->get_pointer(); - for (int i = 0; i < GlobalV::NBANDS; ++i) + ModuleBase::GlobalFunc::ZEROS(Gauss, np); + for (int n = 0; n < npoints; ++n) { - ModuleBase::GlobalFunc::ZEROS(waveg, GlobalV::NLOCAL); + double en = emin + n * de_ev; + double en0 = ekb(0, i) * ModuleBase::Ry_to_eV; + double de = en - en0; + double de2 = 0.5 * de * de; + Gauss[n] = kv.wk[0] * exp(-de2 / a / a) / b; + } + + const int NB = i + 1; - ModuleBase::GlobalFunc::ZEROS(Gauss, np); + const double one_float = 1.0, zero_float = 0.0; + const int one_int = 1; + +#ifdef __MPI + const char T_char = 'T'; + pdgemv_(&T_char, + &GlobalV::NLOCAL, + &GlobalV::NLOCAL, + &one_float, + uhm.LM->Sloc.data(), + &one_int, + &one_int, + pv->desc, + ppsi, + &one_int, + &NB, + pv->desc, + &one_int, + &zero_float, + Mulk[0].c, + &one_int, + &NB, + pv->desc, + &one_int); +#endif + + for (int j = 0; j < GlobalV::NLOCAL; ++j) + { + + if (pv->in_this_processor(j, i)) + { + + const int ir = pv->global2local_row(j); + const int ic = pv->global2local_col(i); + waveg[j] = Mulk[0](ic, ir) * psi[0](ic, ir); + const double x = waveg[j].real(); + BlasConnector::axpy(np, x, Gauss, 1, pdosk[is].c + j * pdosk[is].nc, 1); + } + } + } // ib + +#ifdef __MPI + MPI_Reduce(pdosk[is].c, pdos[is].c, NUM, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); +#endif + } // is + delete[] pdosk; + delete[] waveg; + delete[] Gauss; + if (GlobalV::MY_RANK == 0) + { + { + std::stringstream ps; + ps << GlobalV::global_out_dir << "TDOS"; + std::ofstream out(ps.str().c_str()); + if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 4) + { + + for (int n = 0; n < npoints; ++n) + { + double y = 0.0; + double en = emin + n * de_ev; + for (int i = 0; i < GlobalV::NLOCAL; i++) + { + y += pdos[0](i, n); + } + + out << std::setw(20) << en << std::setw(30) << y << std::endl; + } + } + else if (GlobalV::NSPIN == 2) + { for (int n = 0; n < npoints; ++n) { + double y = 0.0; + double z = 0.0; double en = emin + n * de_ev; - double en0 = ekb(0, i) * ModuleBase::Ry_to_eV; - double de = en - en0; - double de2 = 0.5 * de * de; - Gauss[n] = kv.wk[0] * exp(-de2 / a / a) / b; + for (int i = 0; i < GlobalV::NLOCAL; i++) + { + y += pdos[0](i, n); + z += pdos[1](i, n); + } + + out << std::setw(20) << en << std::setw(30) << y << std::setw(30) << z << std::endl; } + } + out.close(); + } - const int NB = i + 1; + /* decomposed Mulliken charge */ - const double one_float = 1.0, zero_float = 0.0; - const int one_int = 1; + { + std::stringstream as; + as << GlobalV::global_out_dir << "PDOS"; + std::ofstream out(as.str().c_str()); -#ifdef __MPI - const char T_char = 'T'; - pdgemv_(&T_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &one_float, - uhm.LM->Sloc.data(), - &one_int, - &one_int, - pv->desc, - ppsi, - &one_int, - &NB, - pv->desc, - &one_int, - &zero_float, - Mulk[0].c, - &one_int, - &NB, - pv->desc, - &one_int); -#endif + out << "" << std::endl; + out << "" << GlobalV::NSPIN << "" << std::endl; + if (GlobalV::NSPIN == 4) + out << "" << std::setw(2) << GlobalV::NLOCAL / 2 << "" << std::endl; + else + out << "" << std::setw(2) << GlobalV::NLOCAL << "" << std::endl; + out << "" << std::endl; - for (int j = 0; j < GlobalV::NLOCAL; ++j) + for (int n = 0; n < npoints; ++n) + { + double y = 0.0; + double en = emin + n * de_ev; + out << std::setw(20) << en << std::endl; + } + out << "" << std::endl; + for (int i = 0; i < GlobalC::ucell.nat; i++) + { + int a = GlobalC::ucell.iat2ia[i]; + int t = GlobalC::ucell.iat2it[i]; + Atom* atom1 = &GlobalC::ucell.atoms[t]; + const int s0 = GlobalC::ucell.itiaiw2iwt(t, a, 0); + for (int j = 0; j < atom1->nw; ++j) { + const int L1 = atom1->iw2l[j]; + const int N1 = atom1->iw2n[j]; + const int m1 = atom1->iw2m[j]; + const int w = GlobalC::ucell.itiaiw2iwt(t, a, j); - if (pv->in_this_processor(j, i)) + // out << "" <" << std::endl; + out << "" << std::endl; + if (GlobalV::NSPIN == 1) { + for (int n = 0; n < npoints; ++n) + { - const int ir = pv->global2local_row(j); - const int ic = pv->global2local_col(i); - waveg[j] = Mulk[0](ic, ir) * psid[0](ic, ir); - const double x = waveg[j].real(); - BlasConnector::axpy(np, x, Gauss, 1, pdosk[is].c + j * pdosk[is].nc, 1); + out << std::setw(13) << pdos[0](w, n) << std::endl; + } // n } - } - } // ib - } // if - else + else if (GlobalV::NSPIN == 2) + { + for (int n = 0; n < npoints; ++n) + { + out << std::setw(20) << pdos[0](w, n) << std::setw(30) << pdos[1](w, n) << std::endl; + } // n + } + else if (GlobalV::NSPIN == 4) + { + int w0 = w - s0; + for (int n = 0; n < npoints; ++n) + { + out << std::setw(20) << pdos[0](s0 + 2 * w0, n) + pdos[0](s0 + 2 * w0 + 1, n) + << std::endl; + } // n + } + + out << "" << std::endl; + out << "" << std::endl; + } // j + } // i + + out << "" << std::endl; + out.close(); + } + ModuleIO::write_orb_info(&(GlobalC::ucell)); + } + delete[] pdos; + + // output the DOS file. + for (int is = 0; is < nspin0; ++is) + { + std::stringstream ss; + ss << GlobalV::global_out_dir << "DOS" << is + 1; + std::stringstream ss1; + ss1 << GlobalV::global_out_dir << "DOS" << is + 1 << "_smearing.dat"; + + ModuleIO::calculate_dos(is, + ss.str(), + ss1.str(), + dos_edelta_ev, + emax, + emin, + bcoeff, + kv.nks, + kv.nkstot, + kv.wk, + kv.isk, + GlobalV::NBANDS, + ekb, + wg); + } + + return; +} +template<> +void ModuleIO::write_dos_lcao( + const psi::Psi>* psi, + LCAO_Hamilt& uhm, + const ModuleBase::matrix& ekb, + const ModuleBase::matrix& wg, + const double& dos_edelta_ev, + const double& dos_scale, + const double& bcoeff, + const K_Vectors& kv, + hamilt::Hamilt>* p_ham) +{ + ModuleBase::TITLE("ModuleIO", "write_dos_lcao"); + + const Parallel_Orbitals* pv = uhm.LM->ParaV; + + int nspin0 = 1; + if (GlobalV::NSPIN == 2) + nspin0 = 2; + + // find the maximal and minimal band energy. + double emax = ekb(0, 0); + double emin = ekb(0, 0); + for (int ik = 0; ik < kv.nks; ++ik) + { + for (int ib = 0; ib < GlobalV::NBANDS; ++ib) { + emax = std::max(emax, ekb(ik, ib)); + emin = std::min(emin, ekb(ik, ib)); + } + } + +#ifdef __MPI + Parallel_Reduce::gather_max_double_all(emax); + Parallel_Reduce::gather_min_double_all(emin); +#endif + + emax *= ModuleBase::Ry_to_eV; + emin *= ModuleBase::Ry_to_eV; + if (INPUT.dos_setemax) + emax = INPUT.dos_emax_ev; + if (INPUT.dos_setemin) + emin = INPUT.dos_emin_ev; + if (!INPUT.dos_setemax && !INPUT.dos_setemin) + { + // scale up a little bit so the end peaks are displaced better + double delta = (emax - emin) * dos_scale; + emax = emax + delta / 2.0; + emin = emin - delta / 2.0; + } + + // OUT(GlobalV::ofs_running,"minimal energy is (eV)", emin); + // OUT(GlobalV::ofs_running,"maximal energy is (eV)", emax); + // output the PDOS file.////qifeng-2019-01-21 + // atom_arrange::set_sr_NL(); + // atom_arrange::search( GlobalV::SEARCH_RADIUS );//qifeng-2019-01-21 + const double de_ev = dos_edelta_ev; + + const int npoints = static_cast(std::floor((emax - emin) / de_ev)); + + int NUM = GlobalV::NLOCAL * npoints; + + const int np = npoints; + ModuleBase::matrix* pdosk = new ModuleBase::matrix[nspin0]; + + for (int is = 0; is < nspin0; ++is) + { + + pdosk[is].create(GlobalV::NLOCAL, np, true); + } + ModuleBase::matrix* pdos = new ModuleBase::matrix[nspin0]; + for (int is = 0; is < nspin0; ++is) + { + pdos[is].create(GlobalV::NLOCAL, np, true); + } + + double a = bcoeff; + double c = 2 * 3.141592653; + double b = sqrt(c) * a; + + std::complex* waveg = new std::complex[GlobalV::NLOCAL]; + + double* Gauss = new double[np]; + + for (int is = 0; is < nspin0; ++is) + { + std::vector Mulk; Mulk.resize(1); Mulk[0].create(pv->ncol, pv->nrow); @@ -191,7 +431,7 @@ void ModuleIO::write_dos_lcao(const psi::Psi* psid, { // calculate SK for current k point // the target matrix is LM->Sloc2 with collumn-major - if(GlobalV::NSPIN == 4) + if (GlobalV::NSPIN == 4) { dynamic_cast, std::complex>*>(p_ham)->updateSk(ik, uhm.LM, 1); } @@ -225,31 +465,31 @@ void ModuleIO::write_dos_lcao(const psi::Psi* psid, const int NB = i + 1; - const double one_float[2] = {1.0, 0.0}, zero_float[2] = {0.0, 0.0}; + const double one_float[2] = { 1.0, 0.0 }, zero_float[2] = { 0.0, 0.0 }; const int one_int = 1; // const int two_int=2; const char T_char = 'T'; // N_char='N',U_char='U' #ifdef __MPI pzgemv_(&T_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &one_float[0], - uhm.LM->Sloc2.data(), - &one_int, - &one_int, - pv->desc, - p_dwfc, - &one_int, - &NB, - pv->desc, - &one_int, - &zero_float[0], - Mulk[0].c, - &one_int, - &NB, - pv->desc, - &one_int); + &GlobalV::NLOCAL, + &GlobalV::NLOCAL, + &one_float[0], + uhm.LM->Sloc2.data(), + &one_int, + &one_int, + pv->desc, + p_dwfc, + &one_int, + &NB, + pv->desc, + &one_int, + &zero_float[0], + Mulk[0].c, + &one_int, + &NB, + pv->desc, + &one_int); #endif for (int j = 0; j < GlobalV::NLOCAL; ++j) @@ -271,7 +511,7 @@ void ModuleIO::write_dos_lcao(const psi::Psi* psid, } // if } // ik - } // else + #ifdef __MPI MPI_Reduce(pdosk[is].c, pdos[is].c, NUM, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); #endif @@ -410,19 +650,19 @@ void ModuleIO::write_dos_lcao(const psi::Psi* psid, ss1 << GlobalV::global_out_dir << "DOS" << is + 1 << "_smearing.dat"; ModuleIO::calculate_dos(is, - ss.str(), - ss1.str(), - dos_edelta_ev, - emax, - emin, - bcoeff, - kv.nks, - kv.nkstot, - kv.wk, - kv.isk, - GlobalV::NBANDS, - ekb, - wg); + ss.str(), + ss1.str(), + dos_edelta_ev, + emax, + emin, + bcoeff, + kv.nks, + kv.nkstot, + kv.wk, + kv.isk, + GlobalV::NBANDS, + ekb, + wg); } return; diff --git a/source/module_io/write_dos_lcao.h b/source/module_io/write_dos_lcao.h index 9bc33befb32..31aeb781acc 100644 --- a/source/module_io/write_dos_lcao.h +++ b/source/module_io/write_dos_lcao.h @@ -9,15 +9,16 @@ namespace ModuleIO { /// @brief calculate density of states(DOS) and partial density of states(PDOS) and mulliken charge for LCAO base -void write_dos_lcao(const psi::Psi* psid, - const psi::Psi>* psi, - LCAO_Hamilt& uhm, - const ModuleBase::matrix& ekb, - const ModuleBase::matrix& wg, - const double& dos_edelta_ev, - const double& dos_scale, - const double& bcoeff, - const K_Vectors& kv, - hamilt::Hamilt>* p_ham); + template + void write_dos_lcao( + const psi::Psi* psi, + LCAO_Hamilt& uhm, + const ModuleBase::matrix& ekb, + const ModuleBase::matrix& wg, + const double& dos_edelta_ev, + const double& dos_scale, + const double& bcoeff, + const K_Vectors& kv, + hamilt::Hamilt* p_ham); } #endif diff --git a/source/module_io/write_proj_band_lcao.cpp b/source/module_io/write_proj_band_lcao.cpp index 601cea44f29..c77de39cc90 100644 --- a/source/module_io/write_proj_band_lcao.cpp +++ b/source/module_io/write_proj_band_lcao.cpp @@ -8,22 +8,23 @@ #include "write_orb_info.h" #include "module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h" -void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, - const psi::Psi> *psi, +template<> +void ModuleIO::write_proj_band_lcao( + const psi::Psi* psi, LCAO_Hamilt& uhm, const elecstate::ElecState* pelec, const K_Vectors& kv, const UnitCell &ucell, - hamilt::Hamilt>* p_ham) + hamilt::Hamilt* p_ham) { - ModuleBase::TITLE("ModuleIO","write_proj_band_lcao"); + ModuleBase::TITLE("ModuleIO", "write_proj_band_lcao"); ModuleBase::timer::tick("ModuleIO", "write_proj_band_lcao"); const Parallel_Orbitals* pv = uhm.LM->ParaV; int nspin0 = 1; if (GlobalV::NSPIN == 2) - nspin0 = 2; + nspin0 = 2; int nks = 0; if (nspin0 == 1) { @@ -36,73 +37,167 @@ void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, ModuleBase::ComplexMatrix weightk; ModuleBase::matrix weight; - int NUM = 0; - if (GlobalV::GAMMA_ONLY_LOCAL) - { - NUM = GlobalV::NLOCAL * GlobalV::NBANDS * nspin0; - weightk.create(nspin0, GlobalV::NBANDS * GlobalV::NLOCAL, true); - weight.create(nspin0, GlobalV::NBANDS * GlobalV::NLOCAL, true); - } - else - { - NUM = GlobalV::NLOCAL * GlobalV::NBANDS * kv.nks; - weightk.create(kv.nks, GlobalV::NBANDS * GlobalV::NLOCAL, true); - weight.create(kv.nks, GlobalV::NBANDS * GlobalV::NLOCAL, true); - } + int NUM = GlobalV::NLOCAL * GlobalV::NBANDS * nspin0; + weightk.create(nspin0, GlobalV::NBANDS * GlobalV::NLOCAL, true); + weight.create(nspin0, GlobalV::NBANDS * GlobalV::NLOCAL, true); + for (int is = 0; is < nspin0; is++) { + std::vector Mulk; + Mulk.resize(1); + Mulk[0].create(pv->ncol, pv->nrow); - if (GlobalV::GAMMA_ONLY_LOCAL) + psi->fix_k(is); + for (int i = 0; i < GlobalV::NBANDS; ++i) { - std::vector Mulk; - Mulk.resize(1); - Mulk[0].create(pv->ncol, pv->nrow); + const int NB = i + 1; - psid->fix_k(is); - for (int i = 0; i < GlobalV::NBANDS; ++i) + const double one_float = 1.0, zero_float = 0.0; + const int one_int = 1; +#ifdef __MPI + const char T_char = 'T'; + pdgemv_(&T_char, + &GlobalV::NLOCAL, + &GlobalV::NLOCAL, + &one_float, + uhm.LM->Sloc.data(), + &one_int, + &one_int, + pv->desc, + psi->get_pointer(), + &one_int, + &NB, + pv->desc, + &one_int, + &zero_float, + Mulk[0].c, + &one_int, + &NB, + pv->desc, + &one_int); +#endif + for (int j = 0; j < GlobalV::NLOCAL; ++j) { - const int NB = i + 1; - const double one_float = 1.0, zero_float = 0.0; - const int one_int = 1; + if (pv->in_this_processor(j, i)) + { + const int ir = pv->global2local_row(j); + const int ic = pv->global2local_col(i); + weightk(is, i * GlobalV::NLOCAL + j) = Mulk[0](ic, ir) * psi[0](ic, ir); + } + } + } // ib #ifdef __MPI - const char T_char = 'T'; - pdgemv_(&T_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &one_float, - uhm.LM->Sloc.data(), - &one_int, - &one_int, - pv->desc, - psid->get_pointer(), - &one_int, - &NB, - pv->desc, - &one_int, - &zero_float, - Mulk[0].c, - &one_int, - &NB, - pv->desc, - &one_int); + MPI_Reduce(weightk.real().c, weight.c, NUM, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); #endif - for (int j = 0; j < GlobalV::NLOCAL; ++j) + + if (GlobalV::MY_RANK == 0) + { + std::stringstream ps2; + ps2 << GlobalV::global_out_dir << "PBANDS_" << is + 1; + GlobalV::ofs_running << "\n Output projected bands in file: " << ps2.str() << std::endl; + std::ofstream out(ps2.str().c_str()); + + out << "" << std::endl; + out << "" << GlobalV::NSPIN << "" << std::endl; + if (GlobalV::NSPIN == 4) + out << "" << std::setw(2) << GlobalV::NLOCAL / 2 << "" << std::endl; + else + out << "" << std::setw(2) << GlobalV::NLOCAL << "" << std::endl; + out << "" + << std::endl; + for (int ib = 0; ib < GlobalV::NBANDS; ib++) + out << " " << (pelec->ekb(is * nks, ib)) * ModuleBase::Ry_to_eV; + out << std::endl; + out << "" << std::endl; + + for (int i = 0; i < ucell.nat; i++) + { + int a = ucell.iat2ia[i]; + int t = ucell.iat2it[i]; + Atom* atom1 = &ucell.atoms[t]; + const int s0 = ucell.itiaiw2iwt(t, a, 0); + for (int j = 0; j < atom1->nw; ++j) { + const int L1 = atom1->iw2l[j]; + const int N1 = atom1->iw2n[j]; + const int m1 = atom1->iw2m[j]; + const int w = ucell.itiaiw2iwt(t, a, j); - if (pv->in_this_processor(j, i)) + // out << "" <" << std::endl; + out << "" << std::endl; + for (int ib = 0; ib < GlobalV::NBANDS; ib++) { - - const int ir = pv->global2local_row(j); - const int ic = pv->global2local_col(i); - weightk(is, i * GlobalV::NLOCAL + j) = Mulk[0](ic, ir) * psid[0](ic, ir); + if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 2) + out << std::setw(13) << weight(is, ib * GlobalV::NLOCAL + w); + else if (GlobalV::NSPIN == 4) + { + int w0 = w - s0; + out << std::setw(13) + << weight(is, ib * GlobalV::NLOCAL + s0 + 2 * w0) + + weight(is, ib * GlobalV::NLOCAL + s0 + 2 * w0 + 1); + } } - } - } // ib - } // if - else - { + out << std::endl; + out << "" << std::endl; + out << "" << std::endl; + } // j + } // i + + out << "" << std::endl; + out.close(); + } + } // is + ModuleIO::write_orb_info(&ucell); + + ModuleBase::timer::tick("ModuleIO", "write_proj_band_lcao"); + return; +} + +template<> +void ModuleIO::write_proj_band_lcao( + const psi::Psi>* psi, + LCAO_Hamilt& uhm, + const elecstate::ElecState* pelec, + const K_Vectors& kv, + const UnitCell& ucell, + hamilt::Hamilt>* p_ham) +{ + ModuleBase::TITLE("ModuleIO", "write_proj_band_lcao"); + ModuleBase::timer::tick("ModuleIO", "write_proj_band_lcao"); + + const Parallel_Orbitals* pv = uhm.LM->ParaV; + + int nspin0 = 1; + if (GlobalV::NSPIN == 2) + nspin0 = 2; + int nks = 0; + if (nspin0 == 1) + { + nks = kv.nkstot; + } + else if (nspin0 == 2) + { + nks = kv.nkstot / 2; + } + + ModuleBase::ComplexMatrix weightk; + ModuleBase::matrix weight; + int NUM = GlobalV::NLOCAL * GlobalV::NBANDS * kv.nks; + weightk.create(kv.nks, GlobalV::NBANDS * GlobalV::NLOCAL, true); + weight.create(kv.nks, GlobalV::NBANDS * GlobalV::NLOCAL, true); + + for (int is = 0; is < nspin0; is++) + { std::vector Mulk; Mulk.resize(1); Mulk[0].create(pv->ncol, pv->nrow); @@ -113,7 +208,7 @@ void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, { // calculate SK for current k point // the target matrix is LM->Sloc2 with collumn-major - if(GlobalV::NSPIN == 4) + if (GlobalV::NSPIN == 4) { dynamic_cast, std::complex>*>(p_ham)->updateSk(ik, uhm.LM, 1); } @@ -134,30 +229,30 @@ void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, { const int NB = i + 1; - const double one_float[2] = {1.0, 0.0}, zero_float[2] = {0.0, 0.0}; + const double one_float[2] = { 1.0, 0.0 }, zero_float[2] = { 0.0, 0.0 }; const int one_int = 1; // const int two_int=2; const char T_char = 'T'; // N_char='N',U_char='U' #ifdef __MPI pzgemv_(&T_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &one_float[0], - uhm.LM->Sloc2.data(), - &one_int, - &one_int, - pv->desc, - p_dwfc, - &one_int, - &NB, - pv->desc, - &one_int, - &zero_float[0], - Mulk[0].c, - &one_int, - &NB, - pv->desc, - &one_int); + &GlobalV::NLOCAL, + &GlobalV::NLOCAL, + &one_float[0], + uhm.LM->Sloc2.data(), + &one_int, + &one_int, + pv->desc, + p_dwfc, + &one_int, + &NB, + pv->desc, + &one_int, + &zero_float[0], + Mulk[0].c, + &one_int, + &NB, + pv->desc, + &one_int); #endif for (int j = 0; j < GlobalV::NLOCAL; ++j) { @@ -176,7 +271,6 @@ void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, } // if } // ik - } // else #ifdef __MPI MPI_Reduce(weightk.real().c, weight.c, NUM, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); #endif @@ -196,21 +290,12 @@ void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, out << "" << std::setw(2) << GlobalV::NLOCAL << "" << std::endl; out << "" << std::endl; - if (GlobalV::GAMMA_ONLY_LOCAL) - { - for (int ib = 0; ib < GlobalV::NBANDS; ib++) - out << " " << (pelec->ekb(is * nks, ib)) * ModuleBase::Ry_to_eV; - out << std::endl; - } - else - { for (int ik = 0; ik < nks; ik++) { for (int ib = 0; ib < GlobalV::NBANDS; ib++) out << " " << (pelec->ekb(ik + is * nks, ib)) * ModuleBase::Ry_to_eV; out << std::endl; } - } out << "" << std::endl; for (int i = 0; i < ucell.nat; i++) @@ -236,24 +321,6 @@ void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, out << std::setw(2) << "z=\"" << std::setw(40) << N1 + 1 << "\"" << std::endl; out << ">" << std::endl; out << "" << std::endl; - if (GlobalV::GAMMA_ONLY_LOCAL) - { - for (int ib = 0; ib < GlobalV::NBANDS; ib++) - { - if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 2) - out << std::setw(13) << weight(is, ib * GlobalV::NLOCAL + w); - else if (GlobalV::NSPIN == 4) - { - int w0 = w - s0; - out << std::setw(13) - << weight(is, ib * GlobalV::NLOCAL + s0 + 2 * w0) - + weight(is, ib * GlobalV::NLOCAL + s0 + 2 * w0 + 1); - } - } - out << std::endl; - } - else - { for (int ik = 0; ik < nks; ik++) { for (int ib = 0; ib < GlobalV::NBANDS; ib++) @@ -267,12 +334,11 @@ void ModuleIO::write_proj_band_lcao(const psi::Psi *psid, int w0 = w - s0; out << std::setw(13) << weight(ik, ib * GlobalV::NLOCAL + s0 + 2 * w0) - + weight(ik, ib * GlobalV::NLOCAL + s0 + 2 * w0 + 1); + + weight(ik, ib * GlobalV::NLOCAL + s0 + 2 * w0 + 1); } } out << std::endl; } - } out << "" << std::endl; out << "" << std::endl; } // j diff --git a/source/module_io/write_proj_band_lcao.h b/source/module_io/write_proj_band_lcao.h index fde6f1cf6a6..5fdb486da20 100644 --- a/source/module_io/write_proj_band_lcao.h +++ b/source/module_io/write_proj_band_lcao.h @@ -11,13 +11,14 @@ namespace ModuleIO { - void write_proj_band_lcao(const psi::Psi *psid, - const psi::Psi> *psi, + template + void write_proj_band_lcao( + const psi::Psi* psi, LCAO_Hamilt& uhm, const elecstate::ElecState* pelec, const K_Vectors& kv, const UnitCell &ucell, - hamilt::Hamilt>* p_ham); + hamilt::Hamilt* p_ham); } #endif diff --git a/source/module_psi/kernels/device.cpp b/source/module_psi/kernels/device.cpp index db0a17ae8ca..a63dd252784 100644 --- a/source/module_psi/kernels/device.cpp +++ b/source/module_psi/kernels/device.cpp @@ -27,7 +27,9 @@ static bool is_init = false; template<> AbacusDevice_t get_device_type (const DEVICE_CPU* dev) { return CpuDevice; } - +template<> std::string get_current_precision(const double* var) { + return "double"; +} template<> std::string get_current_precision (const std::complex * var) { return "single"; } diff --git a/source/module_psi/kernels/device.h b/source/module_psi/kernels/device.h index 4e75ca8a926..1f2bcb2e61d 100644 --- a/source/module_psi/kernels/device.h +++ b/source/module_psi/kernels/device.h @@ -28,7 +28,7 @@ namespace device { template AbacusDevice_t get_device_type (const Device* dev); -template std::string get_current_precision (const std::complex* var); +template std::string get_current_precision(const T* var); template void print_device_info (const Device* dev, std::ofstream& ofs_device) {return;} diff --git a/source/module_ri/Exx_LRI.h b/source/module_ri/Exx_LRI.h index 06fd84d5887..7db982a2225 100644 --- a/source/module_ri/Exx_LRI.h +++ b/source/module_ri/Exx_LRI.h @@ -22,10 +22,10 @@ class Local_Orbital_Charge; class Parallel_Orbitals; - template + template class RPA_LRI; - template + template class Exx_LRI_Interface; template @@ -71,8 +71,10 @@ class Exx_LRI int two_level_step = 0; Mix_DMk_2D mix_DMk_2D; - friend class RPA_LRI; - friend class Exx_LRI_Interface; + friend class RPA_LRI; + friend class RPA_LRI, Tdata>; + friend class Exx_LRI_Interface; + friend class Exx_LRI_Interface, Tdata>; }; #include "Exx_LRI.hpp" diff --git a/source/module_ri/Exx_LRI_interface.h b/source/module_ri/Exx_LRI_interface.h index cbb085f389a..b9935c499c9 100644 --- a/source/module_ri/Exx_LRI_interface.h +++ b/source/module_ri/Exx_LRI_interface.h @@ -10,7 +10,7 @@ namespace elecstate class ElecState; } -template +template class Exx_LRI_Interface { public: @@ -39,7 +39,7 @@ class Exx_LRI_Interface /// @brief: in do_after_converge: add exx operators; do DM mixing if seperate loop bool exx_after_converge( - hamilt::Hamilt>& hamilt, + hamilt::Hamilt& hamilt, LCAO_Matrix& lm, const Local_Orbital_Charge& loc, const K_Vectors& kv, diff --git a/source/module_ri/Exx_LRI_interface.hpp b/source/module_ri/Exx_LRI_interface.hpp index 18df563c8b9..3eb24d326f6 100644 --- a/source/module_ri/Exx_LRI_interface.hpp +++ b/source/module_ri/Exx_LRI_interface.hpp @@ -4,8 +4,8 @@ #include "module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h" #include "module_hamilt_lcao/hamilt_lcaodft/operator_lcao/op_exx_lcao.h" -template -void Exx_LRI_Interface::write_Hexxs(const std::string &file_name) const +template +void Exx_LRI_Interface::write_Hexxs(const std::string& file_name) const { ModuleBase::TITLE("Exx_LRI","write_Hexxs"); ModuleBase::timer::tick("Exx_LRI", "write_Hexxs"); @@ -15,8 +15,8 @@ void Exx_LRI_Interface::write_Hexxs(const std::string &file_name) const ModuleBase::timer::tick("Exx_LRI", "write_Hexxs"); } -template -void Exx_LRI_Interface::read_Hexxs(const std::string &file_name) +template +void Exx_LRI_Interface::read_Hexxs(const std::string& file_name) { ModuleBase::TITLE("Exx_LRI","read_Hexxs"); ModuleBase::timer::tick("Exx_LRI", "read_Hexxs"); @@ -25,8 +25,8 @@ void Exx_LRI_Interface::read_Hexxs(const std::string &file_name) iar(exx_lri->Hexxs); ModuleBase::timer::tick("Exx_LRI", "read_Hexxs"); } -template -void Exx_LRI_Interface::exx_beforescf(const K_Vectors& kv, const Charge_Mixing& chgmix) +template +void Exx_LRI_Interface::exx_beforescf(const K_Vectors& kv, const Charge_Mixing& chgmix) { #ifdef __MPI if ( GlobalC::exx_info.info_global.cal_exx ) @@ -70,8 +70,8 @@ void Exx_LRI_Interface::exx_beforescf(const K_Vectors& kv, const Charge_M #endif // __MPI } -template -void Exx_LRI_Interface::exx_eachiterinit(const Local_Orbital_Charge& loc, const Charge_Mixing& chgmix, const int& iter) +template +void Exx_LRI_Interface::exx_eachiterinit(const Local_Orbital_Charge& loc, const Charge_Mixing& chgmix, const int& iter) { if (GlobalC::exx_info.info_global.cal_exx) { @@ -88,8 +88,8 @@ void Exx_LRI_Interface::exx_eachiterinit(const Local_Orbital_Charge& loc, } } -template -void Exx_LRI_Interface::exx_hamilt2density(elecstate::ElecState& elec, const Parallel_Orbitals& pv) +template +void Exx_LRI_Interface::exx_hamilt2density(elecstate::ElecState& elec, const Parallel_Orbitals& pv) { // Peize Lin add 2020.04.04 if (XC_Functional::get_func_type() == 4 || XC_Functional::get_func_type() == 5) @@ -113,9 +113,9 @@ void Exx_LRI_Interface::exx_hamilt2density(elecstate::ElecState& elec, co } } -template -bool Exx_LRI_Interface::exx_after_converge( - hamilt::Hamilt>& hamilt, +template +bool Exx_LRI_Interface::exx_after_converge( + hamilt::Hamilt& hamilt, LCAO_Matrix& lm, const Local_Orbital_Charge& loc, const K_Vectors& kv, diff --git a/source/module_ri/RPA_LRI.h b/source/module_ri/RPA_LRI.h index 5ada94e5d1b..00f5b9690be 100644 --- a/source/module_ri/RPA_LRI.h +++ b/source/module_ri/RPA_LRI.h @@ -23,7 +23,7 @@ class Local_Orbital_Charge; class Parallel_Orbitals; class K_Vectors; -template class RPA_LRI +template class RPA_LRI { private: using TA = int; @@ -45,9 +45,9 @@ template class RPA_LRI const K_Vectors& kv, const Parallel_Orbitals& pv); void out_for_RPA(const Parallel_Orbitals& parav, - const psi::Psi> &psi, + const psi::Psi& psi, const elecstate::ElecState *pelec); - void out_eigen_vector(const Parallel_Orbitals ¶v, const psi::Psi> &psi); + void out_eigen_vector(const Parallel_Orbitals& parav, const psi::Psi& psi); void out_struc(); void out_bands(const elecstate::ElecState *pelec); diff --git a/source/module_ri/RPA_LRI.hpp b/source/module_ri/RPA_LRI.hpp index f6e57574fcf..20bc49569f5 100644 --- a/source/module_ri/RPA_LRI.hpp +++ b/source/module_ri/RPA_LRI.hpp @@ -11,7 +11,7 @@ #include #include -template void RPA_LRI::init(const MPI_Comm &mpi_comm_in, const K_Vectors &kv_in) +template void RPA_LRI::init(const MPI_Comm& mpi_comm_in, const K_Vectors& kv_in) { ModuleBase::TITLE("RPA_LRI", "init"); ModuleBase::timer::tick("RPA_LRI", "init"); @@ -25,7 +25,7 @@ template void RPA_LRI::init(const MPI_Comm &mpi_comm_in, // exx_lri_rpa.cv = exx_lri_rpa.cv; } -template void RPA_LRI::cal_rpa_cv() +template void RPA_LRI::cal_rpa_cv() { std::vector atoms(GlobalC::ucell.nat); for (int iat = 0; iat < GlobalC::ucell.nat; ++iat) @@ -57,8 +57,8 @@ template void RPA_LRI::cal_rpa_cv() this->Cs_period = RI::RI_Tools::cal_period(Cs, period); } -template -void RPA_LRI::cal_postSCF_exx(const Local_Orbital_Charge& loc, +template +void RPA_LRI::cal_postSCF_exx(const Local_Orbital_Charge& loc, const MPI_Comm& mpi_comm_in, const K_Vectors& kv, const Parallel_Orbitals& pv) @@ -75,9 +75,9 @@ void RPA_LRI::cal_postSCF_exx(const Local_Orbital_Charge& loc, // cout<<"postSCF_Eexx: "< -void RPA_LRI::out_for_RPA(const Parallel_Orbitals ¶v, - const psi::Psi> &psi, +template +void RPA_LRI::out_for_RPA(const Parallel_Orbitals& parav, + const psi::Psi& psi, const elecstate::ElecState *pelec) { ModuleBase::TITLE("DFT_RPA_interface", "out_for_RPA"); @@ -100,8 +100,8 @@ void RPA_LRI::out_for_RPA(const Parallel_Orbitals ¶v, return; } -template -void RPA_LRI::out_eigen_vector(const Parallel_Orbitals ¶v, const psi::Psi> &psi) +template +void RPA_LRI::out_eigen_vector(const Parallel_Orbitals& parav, const psi::Psi& psi) { ModuleBase::TITLE("DFT_RPA_interface", "out_eigen_vector"); @@ -156,7 +156,7 @@ void RPA_LRI::out_eigen_vector(const Parallel_Orbitals ¶v, const psi: return; } -template void RPA_LRI::out_struc() +template void RPA_LRI::out_struc() { if (GlobalV::MY_RANK != 0) return; @@ -189,7 +189,7 @@ template void RPA_LRI::out_struc() return; } -template void RPA_LRI::out_bands(const elecstate::ElecState *pelec) +template void RPA_LRI::out_bands(const elecstate::ElecState* pelec) { ModuleBase::TITLE("DFT_RPA_interface", "out_bands"); if (GlobalV::MY_RANK != 0) @@ -222,7 +222,7 @@ template void RPA_LRI::out_bands(const elecstate::ElecSt return; } -template void RPA_LRI::out_Cs() +template void RPA_LRI::out_Cs() { std::stringstream ss; ss << "Cs_data_" << GlobalV::MY_RANK << ".txt"; @@ -253,7 +253,7 @@ template void RPA_LRI::out_Cs() return; } -template void RPA_LRI::out_coulomb_k() +template void RPA_LRI::out_coulomb_k() { int all_mu = 0; vector mu_shift(GlobalC::ucell.nat); @@ -315,7 +315,7 @@ template void RPA_LRI::out_coulomb_k() } // template -// void RPA_LRI::init(const MPI_Comm &mpi_comm_in) +// void RPA_LRI::init(const MPI_Comm &mpi_comm_in) // { // if(this->info == this->exx.info) // { @@ -343,7 +343,7 @@ template void RPA_LRI::out_coulomb_k() // } // template -// void RPA_LRI::cal_rpa_ions() +// void RPA_LRI::cal_rpa_ions() // { // // this->rpa_lri.set_parallel(this->mpi_comm, atoms_pos, latvec, period);