Skip to content

Commit 83c89c4

Browse files
authored
Libxc: 7.0.0 -> 7.1.2 (toolchain); fix external parameter handling (deepmodeling#7655)
* Toolchain: libxc 7.0.0 -> 7.1.2 * Fix out-of-bounds read in libxc interface * Require exact Libxc external parameter count * Use Libxc defaults unless parameters are explicitly overridden
1 parent 64e0f34 commit 83c89c4

7 files changed

Lines changed: 76 additions & 75 deletions

File tree

docs/advanced/input_files/input-main.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,18 +1232,16 @@
12321232
### xc_exch_ext
12331233

12341234
- **Type**: Integer followed by Real values
1235-
- **Description**: Customized parameterization on the exchange part of XC functional. The first value should be the LibXC ID of the original functional, and latter values are external parameters. Default values are those of Perdew-Burke-Ernzerhof (PBE) functional. For more information on LibXC ID of functionals, please refer to LibXC. For parameters of functionals of interest, please refer to the source code of LibXC, such as PBE functional interface in LibXC: gga_x_pbe.c.
1235+
- **Description**: Customized parameterization of the exchange part of an XC functional. The first value should be the Libxc ID of the original functional, followed by the complete list of external parameters required by the linked Libxc version. If unset, Libxc's own default parameters are used. For functional IDs and parameter definitions, refer to the Libxc documentation and source code.
12361236

12371237
> Note: Solely setting this keyword will take no effect on XC functionals. One should also set dft_functional to the corresponding functional to apply the customized parameterization. Presently this feature can only support parameterization on one exchange functional.
1238-
- **Default**: 101 0.8040 0.2195149727645171
12391238
12401239
### xc_corr_ext
12411240

12421241
- **Type**: Integer followed by Real values
1243-
- **Description**: Customized parameterization on the correlation part of XC functional. The first value should be the LibXC ID of the original functional, and latter values are external parameters. Default values are those of Perdew-Burke-Ernzerhof (PBE) functional. For more information on LibXC ID of functionals, please refer to LibXC. For parameters of functionals of interest, please refer to the source code of LibXC, such as PBE functional interface in LibXC: gga_c_pbe.c.
1242+
- **Description**: Customized parameterization of the correlation part of an XC functional. The first value should be the Libxc ID of the original functional, followed by the complete list of external parameters required by the linked Libxc version. If unset, Libxc's own default parameters are used. For functional IDs and parameter definitions, refer to the Libxc documentation and source code.
12441243

12451244
> Note: Solely setting this keyword will take no effect on XC functionals. One should also set dft_functional to the corresponding functional to apply the customized parameterization. Presently this feature can only support parameterization on one correlation functional.
1246-
- **Default**: 130 0.06672455060314922 0.031090690869654895034 1.0
12471245
12481246
### pseudo_rcut
12491247

docs/parameters.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,20 +621,20 @@ parameters:
621621
category: Electronic structure
622622
type: Integer followed by Real values
623623
description: |
624-
Customized parameterization on the exchange part of XC functional. The first value should be the LibXC ID of the original functional, and latter values are external parameters. Default values are those of Perdew-Burke-Ernzerhof (PBE) functional. For more information on LibXC ID of functionals, please refer to LibXC. For parameters of functionals of interest, please refer to the source code of LibXC, such as PBE functional interface in LibXC: gga_x_pbe.c.
624+
Customized parameterization of the exchange part of an XC functional. The first value should be the Libxc ID of the original functional, followed by the complete list of external parameters required by the linked Libxc version. If unset, Libxc's own default parameters are used. For functional IDs and parameter definitions, refer to the Libxc documentation and source code.
625625
626626
[NOTE] Solely setting this keyword will take no effect on XC functionals. One should also set dft_functional to the corresponding functional to apply the customized parameterization. Presently this feature can only support parameterization on one exchange functional.
627-
default_value: 101 0.8040 0.2195149727645171
627+
default_value: ""
628628
unit: ""
629629
availability: ""
630630
- name: xc_corr_ext
631631
category: Electronic structure
632632
type: Integer followed by Real values
633633
description: |
634-
Customized parameterization on the correlation part of XC functional. The first value should be the LibXC ID of the original functional, and latter values are external parameters. Default values are those of Perdew-Burke-Ernzerhof (PBE) functional. For more information on LibXC ID of functionals, please refer to LibXC. For parameters of functionals of interest, please refer to the source code of LibXC, such as PBE functional interface in LibXC: gga_c_pbe.c.
634+
Customized parameterization of the correlation part of an XC functional. The first value should be the Libxc ID of the original functional, followed by the complete list of external parameters required by the linked Libxc version. If unset, Libxc's own default parameters are used. For functional IDs and parameter definitions, refer to the Libxc documentation and source code.
635635
636636
[NOTE] Solely setting this keyword will take no effect on XC functionals. One should also set dft_functional to the corresponding functional to apply the customized parameterization. Presently this feature can only support parameterization on one correlation functional.
637-
default_value: 130 0.06672455060314922 0.031090690869654895034 1.0
637+
default_value: ""
638638
unit: ""
639639
availability: ""
640640
- name: pseudo_rcut

source/source_hamilt/module_xc/libxc_setup.cpp

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <regex>
1515
#include <map>
1616
#include <algorithm>
17-
#include <cassert>
1817

1918
bool not_supported_xc_with_laplacian(const std::string& xc_func_in)
2019
{
@@ -200,7 +199,7 @@ const std::vector<double> in_built_xc_func_ext_params(const int id,
200199
#ifdef __EXX
201200
// hybrid functionals
202201
case XC_HYB_GGA_XC_PBEH:
203-
return {hybrid_alpha, hse_omega, hse_omega};
202+
return {hybrid_alpha};
204203
case XC_HYB_GGA_XC_HSE06:
205204
return {hybrid_alpha, hse_omega, hse_omega};
206205
// short-range of B88_X
@@ -262,20 +261,19 @@ const std::vector<double> in_built_xc_func_ext_params(const int id,
262261

263262
const std::vector<double> external_xc_func_ext_params(const int id)
264263
{
265-
const std::map<int, std::vector<double>> mymap = {
266-
{
267-
PARAM.inp.xc_exch_ext[0],
268-
std::vector<double>(PARAM.inp.xc_exch_ext.begin()+1,
269-
PARAM.inp.xc_exch_ext.end())
270-
},
271-
{
272-
PARAM.inp.xc_corr_ext[0],
273-
std::vector<double>(PARAM.inp.xc_corr_ext.begin()+1,
274-
PARAM.inp.xc_corr_ext.end())
275-
}
276-
};
277-
auto it = mymap.find(id);
278-
return (it != mymap.end()) ? it->second : std::vector<double>{};
264+
const auto& exch_ext = PARAM.inp.xc_exch_ext;
265+
if (!exch_ext.empty() && static_cast<int>(exch_ext.front()) == id)
266+
{
267+
return {exch_ext.begin() + 1, exch_ext.end()};
268+
}
269+
270+
const auto& corr_ext = PARAM.inp.xc_corr_ext;
271+
if (!corr_ext.empty() && static_cast<int>(corr_ext.front()) == id)
272+
{
273+
return {corr_ext.begin() + 1, corr_ext.end()};
274+
}
275+
276+
return {};
279277
}
280278

281279
std::vector<xc_func_type>
@@ -290,33 +288,32 @@ XC_Functional_Libxc::init_func(const std::vector<int> &func_id,
290288
funcs.push_back({}); // create placeholder
291289
xc_func_init(&funcs.back(), id, xc_polarized); // instantiate the XC term
292290

293-
// search for external parameters
294-
const std::vector<double> in_built_ext_params = in_built_xc_func_ext_params(id, hybrid_alpha, hse_omega);
295-
const std::vector<double> external_ext_params = external_xc_func_ext_params(id);
296-
// for temporary use, I name their size as n1 and n2
297-
const int n1 = in_built_ext_params.size();
298-
const int n2 = external_ext_params.size();
291+
// Search for external parameters. User-supplied parameters take precedence
292+
// over ABACUS built-in overrides.
293+
const std::vector<double> in_built_ext_params
294+
= in_built_xc_func_ext_params(id, hybrid_alpha, hse_omega);
295+
const std::vector<double> external_ext_params
296+
= external_xc_func_ext_params(id);
297+
const std::vector<double>& requested_ext_params
298+
= external_ext_params.empty() ? in_built_ext_params : external_ext_params;
299299

300-
// #ifdef __DEBUG // will the following assertion cause performance issue?
301-
// assert the number of parameters should be either zero or the value from
302-
// libxc function xc_func_info_get_n_ext_params, this is to avoid the undefined
303-
// behavior of illegal memory access
304-
const xc_func_info_type* info = xc_func_get_info(&funcs.back());
305-
const int nref = xc_func_info_get_n_ext_params(info);
306-
assert ((n1 == 0) || (n1 == nref) || (n2 == 0) || (n2 == nref));
307-
// #endif
300+
if (!requested_ext_params.empty())
301+
{
302+
const xc_func_info_type* info = xc_func_get_info(&funcs.back());
303+
const int nref = xc_func_info_get_n_ext_params(info);
308304

309-
// external overwrites in-built if the same functional id is found in both maps
310-
const double* xc_func_ext_params =
311-
(n2 > 0) ? external_ext_params.data() :
312-
(n1 > 0) ? in_built_ext_params.data() :
313-
nullptr; // nullptr if no external parameters are found
305+
// xc_func_set_ext_params() reads exactly nref entries
306+
if (requested_ext_params.size() != static_cast<std::size_t>(nref))
307+
{
308+
ModuleBase::WARNING_QUIT(
309+
"XC_Functional_Libxc::init_func",
310+
"Invalid number of external parameters for Libxc functional id "
311+
+ std::to_string(id) + ": got "
312+
+ std::to_string(requested_ext_params.size())
313+
+ ", expected " + std::to_string(nref) + ".");
314+
}
314315

315-
// if there are no external parameters, do nothing, otherwise we set
316-
if(xc_func_ext_params != nullptr)
317-
{
318-
// set the external parameters
319-
xc_func_set_ext_params(&funcs.back(), const_cast<double*>(xc_func_ext_params));
316+
xc_func_set_ext_params(&funcs.back(), requested_ext_params.data());
320317
}
321318
}
322319
return funcs;

source/source_io/module_parameter/input_parameter.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -722,14 +722,12 @@ struct Input_para
722722
*
723723
* Likewise, the correlation part can be found in corresponding files.
724724
*
725-
* PBE functional is used as the default functional for XCPNet.
725+
* These vectors are empty unless the user explicitly requests an
726+
* override. This leaves the version-specific default parameters under
727+
* Libxc's control.
726728
*/
727-
// src/gga_x_pbe.c
728-
std::vector<double> xc_exch_ext = {
729-
101, 0.8040, 0.2195149727645171};
730-
// src/gga_c_pbe.c
731-
std::vector<double> xc_corr_ext = {
732-
130, 0.06672455060314922, 0.031090690869654895034, 1.00000};
729+
std::vector<double> xc_exch_ext = {};
730+
std::vector<double> xc_corr_ext = {};
733731

734732
// ============== #Parameters (24.td-ofdft) ===========================
735733
bool of_cd = false; ///< add CD potential or not

source/source_io/module_parameter/read_input_item_elec_stru.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,14 @@ The other way is only available when compiling with LIBXC, and it allows for sup
354354
}
355355
{
356356
Input_Item item("xc_exch_ext");
357-
item.annotation = "placeholder for xcpnet exchange functional";
357+
item.annotation = "customize Libxc exchange functional parameters";
358358
item.category = "Electronic structure";
359359
item.type = "Integer followed by Real values";
360-
item.description = "Customized parameterization on the exchange part of XC functional. The first value should be the LibXC ID of the original functional, and latter values are external parameters. Default values are those of Perdew-Burke-Ernzerhof (PBE) functional. For more information on LibXC ID of functionals, please refer to LibXC. For parameters of functionals of interest, please refer to the source code of LibXC, such as PBE functional interface in LibXC: gga_x_pbe.c."
360+
item.description = "Customized parameterization of the exchange part of an XC functional. The first value should be the Libxc ID of the original functional, followed by the complete list of external parameters required by the linked Libxc version. If unset, Libxc's own default parameters are used. For functional IDs and parameter definitions, refer to the Libxc documentation and source code."
361361
"\n\n[NOTE] Solely setting this keyword will take no effect on XC functionals. One should also set "
362362
"dft_functional to the corresponding functional to apply the customized parameterization. "
363363
"Presently this feature can only support parameterization on one exchange functional.";
364-
item.default_value = "101 0.8040 0.2195149727645171";
364+
item.default_value = "";
365365
item.unit = "";
366366
item.availability = "";
367367
item.read_value = [](const Input_Item& item, Parameter& para) {
@@ -371,10 +371,15 @@ The other way is only available when compiling with LIBXC, and it allows for sup
371371
[](const std::string& str) { return std::stod(str); });
372372
};
373373
item.check_value = [](const Input_Item& item, const Parameter& para) {
374-
// at least one value should be set
375-
if (para.input.xc_exch_ext.empty())
374+
if (!item.is_read())
375+
{
376+
return;
377+
}
378+
if (para.input.xc_exch_ext.size() < 2)
376379
{
377-
ModuleBase::WARNING_QUIT("ReadInput", "xc_exch_ext should not be empty.");
380+
ModuleBase::WARNING_QUIT(
381+
"ReadInput",
382+
"xc_exch_ext requires a Libxc ID followed by external parameters.");
378383
}
379384
// the first value is actually an integer, not a double
380385
const double libxc_id_dbl = para.input.xc_exch_ext[0];
@@ -397,14 +402,14 @@ The other way is only available when compiling with LIBXC, and it allows for sup
397402
}
398403
{
399404
Input_Item item("xc_corr_ext");
400-
item.annotation = "placeholder for xcpnet exchange functional";
405+
item.annotation = "customize Libxc correlation functional parameters";
401406
item.category = "Electronic structure";
402407
item.type = "Integer followed by Real values";
403-
item.description = "Customized parameterization on the correlation part of XC functional. The first value should be the LibXC ID of the original functional, and latter values are external parameters. Default values are those of Perdew-Burke-Ernzerhof (PBE) functional. For more information on LibXC ID of functionals, please refer to LibXC. For parameters of functionals of interest, please refer to the source code of LibXC, such as PBE functional interface in LibXC: gga_c_pbe.c."
408+
item.description = "Customized parameterization of the correlation part of an XC functional. The first value should be the Libxc ID of the original functional, followed by the complete list of external parameters required by the linked Libxc version. If unset, Libxc's own default parameters are used. For functional IDs and parameter definitions, refer to the Libxc documentation and source code."
404409
"\n\n[NOTE] Solely setting this keyword will take no effect on XC functionals. One should also set "
405410
"dft_functional to the corresponding functional to apply the customized parameterization. "
406411
"Presently this feature can only support parameterization on one correlation functional.";
407-
item.default_value = "130 0.06672455060314922 0.031090690869654895034 1.0";
412+
item.default_value = "";
408413
item.unit = "";
409414
item.availability = "";
410415
item.read_value = [](const Input_Item& item, Parameter& para) {
@@ -414,10 +419,15 @@ The other way is only available when compiling with LIBXC, and it allows for sup
414419
[](const std::string& str) { return std::stod(str); });
415420
};
416421
item.check_value = [](const Input_Item& item, const Parameter& para) {
417-
// at least one value should be set
418-
if (para.input.xc_corr_ext.empty())
422+
if (!item.is_read())
423+
{
424+
return;
425+
}
426+
if (para.input.xc_corr_ext.size() < 2)
419427
{
420-
ModuleBase::WARNING_QUIT("ReadInput", "xc_corr_ext should not be empty.");
428+
ModuleBase::WARNING_QUIT(
429+
"ReadInput",
430+
"xc_corr_ext requires a Libxc ID followed by external parameters.");
421431
}
422432
// the first value is actually an integer, not a double
423433
const double libxc_id_dbl = para.input.xc_corr_ext[0];

toolchain/scripts/package_versions.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ fftw_main_sha256="5630c24cdeb33b131612f7eb4b1a9934234754f9f388ff8617458d0be6f239
6868
fftw_alt_ver="3.3.10"
6969
fftw_alt_sha256="56c932549852cddcfafdab3820b0200c7742675be92179e59e6215b340e26467"
7070

71-
# LibXC (supports dual versions) - main=7.0.0, alt=6.2.2
72-
libxc_main_ver="7.0.0"
73-
libxc_main_sha256="e9ae69f8966d8de6b7585abd9fab588794ada1fab8f689337959a35abbf9527d"
74-
libxc_alt_ver="6.2.2"
75-
libxc_alt_sha256="f72ed08af7b9dff5f57482c5f97bff22c7dc49da9564bc93871997cbda6dacf3"
71+
# LibXC (supports dual versions) - main=7.1.0, alt=7.0.0
72+
libxc_main_ver="7.1.2"
73+
libxc_main_sha256="3915fac94416e4c415534223ea492ad2663f928acf27e98662c861b094a6c306"
74+
libxc_alt_ver="7.0.0"
75+
libxc_alt_sha256="e9ae69f8966d8de6b7585abd9fab588794ada1fab8f689337959a35abbf9527d"
7676

7777
# ScaLAPACK (supports dual versions) - main=2.2.2, alt=2.2.1
7878
scalapack_main_ver="2.2.3"

toolchain/scripts/stage3/install_libxc.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,16 @@ case "$with_libxc" in
6161
[ -d libxc-${libxc_ver} ] && rm -rf libxc-${libxc_ver}
6262
tar -xjf ${libxc_pkg}
6363
cd libxc-${libxc_ver}
64-
# using cmake method to install libxc is neccessary for abacus
6564
mkdir build
6665
cd build
6766
cmake \
6867
-DCMAKE_BUILD_TYPE=Release \
6968
-DCMAKE_INSTALL_PREFIX=${pkg_install_dir} \
70-
-DBUILD_SHARED_LIBS=YES \
69+
-DBUILD_SHARED_LIBS=ON \
7170
-DCMAKE_INSTALL_LIBDIR=lib \
7271
-DCMAKE_VERBOSE_MAKEFILE=ON \
7372
-DENABLE_FORTRAN=ON \
7473
-DENABLE_PYTHON=OFF \
75-
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
7674
-DBUILD_TESTING=OFF .. \
7775
> configure.log 2>&1 || tail -n ${LOG_LINES} configure.log
7876
make -j $(get_nprocs) > make.log 2>&1 || tail -n ${LOG_LINES} make.log

0 commit comments

Comments
 (0)