From d51377d1598e8fe5791c7dfcb95015f6d776698c Mon Sep 17 00:00:00 2001 From: linpz Date: Tue, 24 Mar 2026 16:40:51 +0800 Subject: [PATCH 1/5] Feature: add OpenMP in XC_Functional_Libxc::v_xc_libxc() --- .../module_xc/xc_functional_libxc_vxc.cpp | 74 +++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp index e9001c7e4b..43a487cc93 100644 --- a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp +++ b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp @@ -93,33 +93,42 @@ std::tuple XC_Functional_Libxc::v_xc_libxc( / std::vector exc ( nrxx ); std::vector vrho ( nrxx * nspin ); std::vector vsigma( nrxx * ((1==nspin)?1:3) ); - switch( func.info->family ) + + ModuleBase::timer::start("Libxc","xc_lda/gga_exc_vxc"); + constexpr int batch_size = 1024; + #ifdef _OPENMP + #pragma omp parallel for schedule(static, batch_size) + #endif + for( int ibatch = 0; ibatch < nrxx; ibatch += batch_size ) { - case XC_FAMILY_LDA: - // call Libxc function: xc_lda_exc_vxc - xc_lda_exc_vxc( &func, nrxx, rho.data(), - exc.data(), vrho.data() ); - break; - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - // call Libxc function: xc_gga_exc_vxc - xc_gga_exc_vxc( &func, nrxx, rho.data(), sigma.data(), - exc.data(), vrho.data(), vsigma.data() ); - break; - default: - throw std::domain_error("func.info->family ="+std::to_string(func.info->family) - +" unfinished in "+std::string(__FILE__)+" line "+std::to_string(__LINE__)); - break; + const int ir_end = std::min(ibatch + batch_size, nrxx); + const int npts = ir_end - ibatch; + + switch( func.info->family ) + { + case XC_FAMILY_LDA: + xc_lda_exc_vxc( &func, npts, rho.data() + ibatch, + exc.data() + ibatch, vrho.data() + ibatch * nspin ); + break; + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + xc_gga_exc_vxc( &func, npts, rho.data() + ibatch, sigma.data() + ibatch, + exc.data() + ibatch, vrho.data() + ibatch * nspin, vsigma.data() + ibatch * ((1==nspin)?1:3) ); + break; + default: + throw std::domain_error("func.info->family ="+std::to_string(func.info->family) + +" unfinished in "+std::string(__FILE__)+" line "+std::to_string(__LINE__)); + } } + ModuleBase::timer::end("Libxc","xc_lda/gga_exc_vxc"); // added by jghan, 2024-10-10 double factor = 1.0; - if( scaling_factor == nullptr ) { ; - } else + if( scaling_factor ) { auto pair_factor = scaling_factor->find(func.info->number); - if( pair_factor != scaling_factor->end() ) { factor = pair_factor->second; -} + if( pair_factor != scaling_factor->end() ) + { factor = pair_factor->second; } } // time factor is added by jghan, 2024-10-10 @@ -268,8 +277,29 @@ std::tuple XC_Functional_Li for ( xc_func_type &func : funcs ) { assert(func.info->family == XC_FAMILY_MGGA); - xc_mgga_exc_vxc(&func, nrxx, rho.data(), sigma.data(), sigma.data(), - kin_r.data(), exc.data(), vrho.data(), vsigma.data(), vlapl.data(), vtau.data()); + + ModuleBase::timer::start("Libxc","xc_mgga_exc_vxc"); + constexpr int batch_size = 1024; + #ifdef _OPENMP + #pragma omp parallel for schedule(static, batch_size) + #endif + for( int ibatch = 0; ibatch < nrxx; ibatch += batch_size ) + { + const int ir_end = std::min(ibatch + batch_size, nrxx); + const int npts = ir_end - ibatch; + + xc_mgga_exc_vxc(&func, npts, + rho.data() + ibatch, + sigma.data() + ibatch, + sigma.data() + ibatch, + kin_r.data() + ibatch * nspin, + exc.data() + ibatch, + vrho.data() + ibatch * nspin, + vsigma.data() + ibatch * ((1==nspin)?1:3), + vlapl.data() + ibatch * nspin, + vtau.data() + ibatch * nspin); + } + ModuleBase::timer::end("Libxc","xc_mgga_exc_vxc"); //process etxc for( int is=0; is!=nspin; ++is ) From 67491a634f1ead6f0c6241ea6bbb5ac842f49d88 Mon Sep 17 00:00:00 2001 From: linpz Date: Thu, 26 Mar 2026 16:20:47 +0800 Subject: [PATCH 2/5] update OpenMP in XC_Functional_Libxc::v_xc_libxc() --- .../module_xc/xc_functional_libxc_vxc.cpp | 62 +++++++++++-------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp index 43a487cc93..baa088a27a 100644 --- a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp +++ b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp @@ -95,25 +95,35 @@ std::tuple XC_Functional_Libxc::v_xc_libxc( / std::vector vsigma( nrxx * ((1==nspin)?1:3) ); ModuleBase::timer::start("Libxc","xc_lda/gga_exc_vxc"); - constexpr int batch_size = 1024; + constexpr int nr_batch_size = 1024; #ifdef _OPENMP - #pragma omp parallel for schedule(static, batch_size) + #pragma omp parallel for schedule(static, nr_batch_size) #endif - for( int ibatch = 0; ibatch < nrxx; ibatch += batch_size ) + for( int ir_start = 0; ir_start < nrxx; ir_start += nr_batch_size ) { - const int ir_end = std::min(ibatch + batch_size, nrxx); - const int npts = ir_end - ibatch; + const int ir_end = std::min(ir_start + nr_batch_size, nrxx); + const int nrxx_thread = ir_end - ir_start; switch( func.info->family ) { case XC_FAMILY_LDA: - xc_lda_exc_vxc( &func, npts, rho.data() + ibatch, - exc.data() + ibatch, vrho.data() + ibatch * nspin ); + xc_lda_exc_vxc( + &func, + nrxx_thread, + rho.data() + ir_start, + exc.data() + ir_start, + vrho.data() + ir_start * nspin ); break; case XC_FAMILY_GGA: case XC_FAMILY_HYB_GGA: - xc_gga_exc_vxc( &func, npts, rho.data() + ibatch, sigma.data() + ibatch, - exc.data() + ibatch, vrho.data() + ibatch * nspin, vsigma.data() + ibatch * ((1==nspin)?1:3) ); + xc_gga_exc_vxc( + &func, + nrxx_thread, + rho.data() + ir_start, + sigma.data() + ir_start * ((1==nspin)?1:3), + exc.data() + ir_start, + vrho.data() + ir_start * nspin, + vsigma.data() + ir_start * ((1==nspin)?1:3) ); break; default: throw std::domain_error("func.info->family ="+std::to_string(func.info->family) @@ -279,25 +289,27 @@ std::tuple XC_Functional_Li assert(func.info->family == XC_FAMILY_MGGA); ModuleBase::timer::start("Libxc","xc_mgga_exc_vxc"); - constexpr int batch_size = 1024; + constexpr int nr_batch_size = 1024; #ifdef _OPENMP - #pragma omp parallel for schedule(static, batch_size) + #pragma omp parallel for schedule(static, nr_batch_size) #endif - for( int ibatch = 0; ibatch < nrxx; ibatch += batch_size ) + for( int ir_start = 0; ir_start < nrxx; ir_start += nr_batch_size ) { - const int ir_end = std::min(ibatch + batch_size, nrxx); - const int npts = ir_end - ibatch; - - xc_mgga_exc_vxc(&func, npts, - rho.data() + ibatch, - sigma.data() + ibatch, - sigma.data() + ibatch, - kin_r.data() + ibatch * nspin, - exc.data() + ibatch, - vrho.data() + ibatch * nspin, - vsigma.data() + ibatch * ((1==nspin)?1:3), - vlapl.data() + ibatch * nspin, - vtau.data() + ibatch * nspin); + const int ir_end = std::min(ir_start + nr_batch_size, nrxx); + const int nrxx_thread = ir_end - ir_start; + + xc_mgga_exc_vxc( + &func, + nrxx_thread, + rho.data() + ir_start, + sigma.data() + ir_start * ((1==nspin)?1:3), + sigma.data() + ir_start * ((1==nspin)?1:3), + kin_r.data() + ir_start * nspin, + exc.data() + ir_start, + vrho.data() + ir_start * nspin, + vsigma.data() + ir_start * ((1==nspin)?1:3), + vlapl.data() + ir_start * nspin, + vtau.data() + ir_start * nspin); } ModuleBase::timer::end("Libxc","xc_mgga_exc_vxc"); From 04758f0ff94c19d7ac60b647324481d75e9e8cfc Mon Sep 17 00:00:00 2001 From: linpz Date: Fri, 27 Mar 2026 01:51:08 +0800 Subject: [PATCH 3/5] remove OpenMP in XC_Functional_Libxc::v_xc_meta() --- .../module_xc/xc_functional_libxc_vxc.cpp | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp index baa088a27a..c5238cc086 100644 --- a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp +++ b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp @@ -289,28 +289,8 @@ std::tuple XC_Functional_Li assert(func.info->family == XC_FAMILY_MGGA); ModuleBase::timer::start("Libxc","xc_mgga_exc_vxc"); - constexpr int nr_batch_size = 1024; - #ifdef _OPENMP - #pragma omp parallel for schedule(static, nr_batch_size) - #endif - for( int ir_start = 0; ir_start < nrxx; ir_start += nr_batch_size ) - { - const int ir_end = std::min(ir_start + nr_batch_size, nrxx); - const int nrxx_thread = ir_end - ir_start; - - xc_mgga_exc_vxc( - &func, - nrxx_thread, - rho.data() + ir_start, - sigma.data() + ir_start * ((1==nspin)?1:3), - sigma.data() + ir_start * ((1==nspin)?1:3), - kin_r.data() + ir_start * nspin, - exc.data() + ir_start, - vrho.data() + ir_start * nspin, - vsigma.data() + ir_start * ((1==nspin)?1:3), - vlapl.data() + ir_start * nspin, - vtau.data() + ir_start * nspin); - } + xc_mgga_exc_vxc(&func, nrxx, rho.data(), sigma.data(), sigma.data(), + kin_r.data(), exc.data(), vrho.data(), vsigma.data(), vlapl.data(), vtau.data()); ModuleBase::timer::end("Libxc","xc_mgga_exc_vxc"); //process etxc From f0bd3c913c7665120d1e2cad9a1895134e761c7f Mon Sep 17 00:00:00 2001 From: linpz Date: Sat, 28 Mar 2026 16:06:00 +0800 Subject: [PATCH 4/5] update OpenMP in XC_Functional_Libxc::v_xc_libxc() --- .../module_xc/xc_functional_libxc_vxc.cpp | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp index c5238cc086..cb7f08da26 100644 --- a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp +++ b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp @@ -95,27 +95,38 @@ std::tuple XC_Functional_Libxc::v_xc_libxc( / std::vector vsigma( nrxx * ((1==nspin)?1:3) ); ModuleBase::timer::start("Libxc","xc_lda/gga_exc_vxc"); - constexpr int nr_batch_size = 1024; - #ifdef _OPENMP - #pragma omp parallel for schedule(static, nr_batch_size) - #endif - for( int ir_start = 0; ir_start < nrxx; ir_start += nr_batch_size ) + switch( func.info->family ) { - const int ir_end = std::min(ir_start + nr_batch_size, nrxx); - const int nrxx_thread = ir_end - ir_start; - - switch( func.info->family ) + case XC_FAMILY_LDA: { - case XC_FAMILY_LDA: + constexpr int nr_batch_size = 1024; + #ifdef _OPENMP + #pragma omp parallel for schedule(static, nr_batch_size) + #endif + for( int ir_start = 0; ir_start < nrxx; ir_start += nr_batch_size ) + { + const int ir_end = std::min(ir_start + nr_batch_size, nrxx); + const int nrxx_thread = ir_end - ir_start; xc_lda_exc_vxc( &func, nrxx_thread, rho.data() + ir_start, exc.data() + ir_start, vrho.data() + ir_start * nspin ); - break; - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: + } + break; + } + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + { + constexpr int nr_batch_size = 1024; + #ifdef _OPENMP + #pragma omp parallel for schedule(static, nr_batch_size) + #endif + for( int ir_start = 0; ir_start < nrxx; ir_start += nr_batch_size ) + { + const int ir_end = std::min(ir_start + nr_batch_size, nrxx); + const int nrxx_thread = ir_end - ir_start; xc_gga_exc_vxc( &func, nrxx_thread, @@ -124,10 +135,14 @@ std::tuple XC_Functional_Libxc::v_xc_libxc( / exc.data() + ir_start, vrho.data() + ir_start * nspin, vsigma.data() + ir_start * ((1==nspin)?1:3) ); - break; - default: - throw std::domain_error("func.info->family ="+std::to_string(func.info->family) - +" unfinished in "+std::string(__FILE__)+" line "+std::to_string(__LINE__)); + } + break; + } + default: + { + throw std::domain_error("func.info->family ="+std::to_string(func.info->family) + +" unfinished in "+std::string(__FILE__)+" line "+std::to_string(__LINE__)); + } } ModuleBase::timer::end("Libxc","xc_lda/gga_exc_vxc"); From ec0e7c05a84c72431662dc9d1bcbba6cef5b2342 Mon Sep 17 00:00:00 2001 From: linpz Date: Fri, 3 Apr 2026 23:10:27 +0800 Subject: [PATCH 5/5] fix bug in OpenMP XC_Functional_Libxc::v_xc_libxc() --- .../module_xc/xc_functional_libxc_vxc.cpp | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp index cb7f08da26..2170357ac8 100644 --- a/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp +++ b/source/source_hamilt/module_xc/xc_functional_libxc_vxc.cpp @@ -110,7 +110,7 @@ std::tuple XC_Functional_Libxc::v_xc_libxc( / xc_lda_exc_vxc( &func, nrxx_thread, - rho.data() + ir_start, + rho.data() + ir_start * nspin, exc.data() + ir_start, vrho.data() + ir_start * nspin ); } @@ -130,7 +130,7 @@ std::tuple XC_Functional_Libxc::v_xc_libxc( / xc_gga_exc_vxc( &func, nrxx_thread, - rho.data() + ir_start, + rho.data() + ir_start * nspin, sigma.data() + ir_start * ((1==nspin)?1:3), exc.data() + ir_start, vrho.data() + ir_start * nspin, @@ -290,12 +290,10 @@ std::tuple XC_Functional_Li #endif for( int ir=0; ir XC_Functional_Li assert(func.info->family == XC_FAMILY_MGGA); ModuleBase::timer::start("Libxc","xc_mgga_exc_vxc"); - xc_mgga_exc_vxc(&func, nrxx, rho.data(), sigma.data(), sigma.data(), - kin_r.data(), exc.data(), vrho.data(), vsigma.data(), vlapl.data(), vtau.data()); + constexpr int nr_batch_size = 1024; + #ifdef _OPENMP + #pragma omp parallel for schedule(static, nr_batch_size) + #endif + for( int ir_start = 0; ir_start < nrxx; ir_start += nr_batch_size ) + { + const int ir_end = std::min(ir_start + nr_batch_size, nrxx); + const int nrxx_thread = ir_end - ir_start; + xc_mgga_exc_vxc( + &func, + nrxx_thread, + rho.data() + ir_start * nspin, + sigma.data() + ir_start * ((1==nspin)?1:3), + sigma.data() + ir_start * ((1==nspin)?1:3), + kin_r.data() + ir_start * nspin, + exc.data() + ir_start, + vrho.data() + ir_start * nspin, + vsigma.data() + ir_start * ((1==nspin)?1:3), + vlapl.data() + ir_start * nspin, + vtau.data() + ir_start * nspin); + } ModuleBase::timer::end("Libxc","xc_mgga_exc_vxc"); //process etxc