Add initial parameter gradient test

The system is a Helium atom with a bspline e-e jastrow with 4 parameters.

The test uses a new QMC_RUN_AND_CHECK_CUSTOM_SCALAR function.
This test uses the --name, --ref-value, --ref-error options to
check_scalars.py added in #2640 in order to test arbitrarily named
values.
The new function uses named arguments that are handled with
cmake_parse_arguments. This should make it easier to add new
functionality via new named arguments in the future.
This commit is contained in:
Mark Dewing 2020-10-08 14:59:44 -05:00
parent 0ddd2f1dec
commit 9aa0781f15
4 changed files with 205 additions and 0 deletions

View File

@ -134,6 +134,8 @@ ENDFUNCTION()
IF (QMC_NO_SLOW_CUSTOM_TESTING_COMMANDS)
FUNCTION(QMC_RUN_AND_CHECK)
ENDFUNCTION()
FUNCTION(QMC_RUN_AND_CHECK_CUSTOM_SCALAR)
ENDFUNCTION()
FUNCTION(SIMPLE_RUN_AND_CHECK)
ENDFUNCTION()
ELSE (QMC_NO_SLOW_CUSTOM_TESTING_COMMANDS)
@ -232,6 +234,92 @@ FUNCTION(QMC_RUN_AND_CHECK BASE_NAME BASE_DIR PREFIX INPUT_FILE PROCS THREADS SH
ENDFUNCTION()
# Add a test run and associated scalar checks for a custom named scalar
# Arguments
# BASE_NAME - name of test (number of MPI processes, number of threads, and value to check (if applicable)
# will be appended to get the full test name)
# BASE_DIR - source location of test input files
# PREFIX - prefix for output files
# INPUT_FILE - XML input file to QMCPACK
# PROCS - number of MPI processes (default: 1)
# THREADS - number of OpenMP threads (default: 1)
# SERIES - series index to compute (default: 0)
# SCALAR_VALUES - name of list of output values to check with check_scalars.py
# The list entries contain consecutively the name, the value, and the error.
# The name of the variable is passed (instead of the value) in case future support
# for multiple SERIES/SCALAR_VALUES pairs is added
function(QMC_RUN_AND_CHECK_CUSTOM_SCALAR)
set(OPTIONS SHOULD_FAIL)
set(ONE_VALUE_ARGS BASE_NAME BASE_DIR PREFIX INPUT_FILE PROCS THREADS SERIES SCALAR_VALUES)
# Eventually many want to support multiple SERIES/SCALAR_VALUES pairs
#SET(MULTI_VALUE_ARGS SERIES SCALAR_VALUES)
cmake_parse_arguments(QRC "${options}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN})
set(PROCS 1)
if (QRC_PROCS)
set(PROCS ${QRC_PROCS})
endif()
set(THREADS 1)
if (QRC_THREADS)
set(THREADS ${QRC_THREADS})
endif()
set(BASE_NAME ${QRC_BASE_NAME})
set(BASE_DIR ${QRC_BASE_DIR})
set(PREFIX ${QRC_PREFIX})
set(INPUT_FILE ${QRC_INPUT_FILE})
set( TEST_ADDED FALSE )
set( TEST_LABELS "")
set( FULL_NAME "${BASE_NAME}-${PROCS}-${THREADS}" )
message_verbose("Adding test ${FULL_NAME}")
RUN_QMC_APP(${FULL_NAME} ${BASE_DIR} ${PROCS} ${THREADS} TEST_ADDED TEST_LABELS ${INPUT_FILE})
if ( TEST_ADDED )
set_property(TEST ${FULL_NAME} APPEND PROPERTY LABELS "QMCPACK")
endif()
if ( TEST_ADDED AND SHOULD_FAIL)
set_property(TEST ${FULL_NAME} APPEND PROPERTY WILL_FAIL TRUE)
endif()
if ( TEST_ADDED AND NOT SHOULD_FAIL)
# Derefence the list of scalar values by variable name
set(SCALAR_VALUES "${${QRC_SCALAR_VALUES}}")
list(LENGTH SCALAR_VALUES listlen)
math(EXPR listlen2 "${listlen}-1")
foreach(sv_idx RANGE 0 ${listlen2} 3)
math(EXPR sv_idx_p1 "${sv_idx}+1")
math(EXPR sv_idx_p2 "${sv_idx}+2")
list(GET SCALAR_VALUES ${sv_idx} SCALAR_NAME)
list(GET SCALAR_VALUES ${sv_idx_p1} SCALAR_VALUE)
list(GET SCALAR_VALUES ${sv_idx_p2} SCALAR_ERROR)
set(SERIES 0)
if(QRC_SERIES)
set(SERIES ${QRC_SERIES})
set( TEST_NAME "${FULL_NAME}-${SERIES}-${SCALAR_NAME}" )
else()
set( TEST_NAME "${FULL_NAME}-${SCALAR_NAME}" )
endif()
set(CHECK_CMD ${CMAKE_SOURCE_DIR}/tests/scripts/check_scalars.py --ns 3 --series ${SERIES} -p ${PREFIX} -e 2 --name ${SCALAR_NAME} --ref-value ${SCALAR_VALUE} --ref-error ${SCALAR_ERROR})
add_test( NAME ${TEST_NAME}
COMMAND ${CHECK_CMD}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${FULL_NAME}"
)
set_property( TEST ${TEST_NAME} APPEND PROPERTY DEPENDS ${FULL_NAME} )
set_property( TEST ${TEST_NAME} APPEND PROPERTY LABELS "QMCPACK-checking-results" )
set_property( TEST ${TEST_NAME} APPEND PROPERTY LABELS ${TEST_LABELS} )
endforeach()
endif()
endfunction()
function(SIMPLE_RUN_AND_CHECK base_name base_dir input_file procs threads check_script)

View File

@ -20,3 +20,4 @@ SUBDIRS("FeCO6_b3lyp_pyscf")
SUBDIRS("CHN_ae")
SUBDIRS("LiH_ae_MSD")
SUBDIRS("He_ae")
SUBDIRS("He_param")

View File

@ -0,0 +1,19 @@
IF (NOT QMC_CUDA)
LIST(APPEND HE_BSPLINE_PARAM jud_0 -0.121914 0.0014) # scalar name, value, error
LIST(APPEND HE_BSPLINE_PARAM jud_1 0.069689 0.0015)
LIST(APPEND HE_BSPLINE_PARAM jud_2 0.051412 0.00031)
LIST(APPEND HE_BSPLINE_PARAM jud_3 0.000812 0.000038)
QMC_RUN_AND_CHECK_CUSTOM_SCALAR(BASE_NAME He_param_grad
BASE_DIR "${CMAKE_SOURCE_DIR}/tests/molecules/He_param"
PREFIX He_param_grad.param
INPUT_FILE He_param_grad.xml
PROCS 1
THREADS 16
SERIES 0
SCALAR_VALUES HE_BSPLINE_PARAM
)
ELSE()
MESSAGE_VERBOSE("Skipping He_param tests because parameter output is not supported by CUDA build (QMC_CUDA=1)")
ENDIF()

View File

@ -0,0 +1,97 @@
<?xml version="1.0"?>
<simulation>
<project id="He_param_grad" series="0"/>
<!-- Location of atoms -->
<particleset name="ion0" size="1">
<group name="He">
<parameter name="charge">2</parameter>
</group>
<attrib name="position" datatype="posArray">
0.0 0.0 0.0
</attrib>
</particleset>
<!-- Randomly create electrons around the atomic position -->
<particleset name="e" random="yes" randomsrc="ion0">
<group name="u" size="1">
<parameter name="charge">-1</parameter>
</group>
<group name="d" size="1">
<parameter name="charge">-1</parameter>
</group>
</particleset>
<!-- Trial wavefunction - use Slater determinant multiplied by a Jastrow factor -->
<wavefunction name="psi0" target="e">
<!-- Electron-electron Jastrow using B-splines -->
<!-- For two electron system, only have up-down interaction -->
<jastrow name="Jee" type="Two-Body" function="Bspline">
<!-- 'rcut' is the cutoff (in atomic units) beyond which the jastrow factor is zero -->
<!-- 'size' is the number of knots in the spline inside the interval [0, rcut].
This should match the number of coefficients in the array -->
<correlation rcut="10" size="4" speciesA="u" speciesB="d">
<coefficients id="jud" type="Array">0.0 0.0 0.0 0.0</coefficients>
</correlation>
</jastrow>
<determinantset type="MO" key="STO" transform="no" source="ion0">
<!-- Use a single Slater Type Orbital (STO) for the basis. Cusp condition is correct. -->
<basisset>
<atomicBasisSet type="STO" elementType="He">
<basisGroup rid="R0" n="1" l="0" m="0" type="Slater">
<radfunc exponent="2.0"/>
</basisGroup>
</atomicBasisSet>
</basisset>
<slaterdeterminant>
<determinant id="updet" spin="1" size="1">
<coefficient id="updetC" type="Array" size="1">
1.0
</coefficient>
</determinant>
<determinant id="downdet" spin="-1" size="1">
<coefficient id="downdetC" type="Array" size="1">
1.0
</coefficient>
</determinant>
</slaterdeterminant>
</determinantset>
</wavefunction>
<!-- Hamiltonian - the energy of interactions between particles -->
<hamiltonian name="h0" type="generic" target="e">
<!-- Electon-electron -->
<pairpot name="ElecElec" type="coulomb" source="e" target="e"/>
<!-- Electon-ion -->
<pairpot name="Coulomb" type="coulomb" source="ion0" target="e"/>
<!-- Ion-ion (not needed for a single atom) -->
<!--<constant name="IonIon" type="coulomb" source="ion0" target="ion0"/>-->
</hamiltonian>
<!-- QMC method(s) to run -->
<loop max="10">
<qmc method="opt_batch" move="pbyp" checkpoint="-1" gpu="no">
<optimize method="test" output_param_file="yes"/>
<parameter name="blocks"> 100 </parameter>
<parameter name="warmupsteps"> 25 </parameter>
<parameter name="steps"> 10 </parameter>
<parameter name="substeps"> 20 </parameter>
<parameter name="timestep"> 0.5 </parameter>
<parameter name="samples"> 1000 </parameter>
<parameter name="stepsbetweensamples"> 1 </parameter>
<cost name="energy"> 1.0 </cost>
<cost name="reweightedvariance"> 0.00 </cost>
</qmc>
</loop>
</simulation>