1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2025-03-04 06:10:23 +01:00

Merge pull request #168 from TREX-CoE/det-checks

Fix text backend for determinants + check consistency of determinants
This commit is contained in:
Evgeny Posenitskiy 2025-01-02 22:14:37 +01:00 committed by GitHub
commit ccb9bf8587
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 293 additions and 107 deletions

View File

@ -71,7 +71,7 @@ jobs:
run: make -j2
- name: check TREXIO
run: make -j2 check
run: make -j2 check # Non-parallel run
- name: Archive test log file
if: failure()

View File

@ -43,6 +43,7 @@ AC_SUBST([UNAME])
# Fortran API [default: --with-fortran], do not disable in the dev mode
AC_PROG_FC
AC_ARG_WITH(fortran, [AS_HELP_STRING([--without-fortran],[do not test and install the Fortran API])], ok=$withval, ok=yes)
AS_IF([test "$ok" = "yes"],[
AC_FC_FREEFORM
@ -52,9 +53,9 @@ AS_IF([test "$ok" = "yes"],[
# Specific options required with some compilers
AS_CASE([$FC],
[*gfortran*], [FCFLAGS="$FCFLAGS -fPIC"],
[*flang*], [FCFLAGS="$FCFLAGS -fPIC"],
[*ifort*], [FCFLAGS="$FCFLAGS -fPIC"],
[*gfortran*], [FCFLAGS="$FCFLAGS -g -fPIC"],
[*flang*], [FCFLAGS="$FCFLAGS -g -fPIC"],
[*ifort*], [FCFLAGS="$FCFLAGS -g -fPIC"],
[])
])

View File

@ -6,6 +6,62 @@ import trexio
from benzene_data import *
# this function is copied from the trexio-tools github repository (BSD-3 license):
# https://github.com/TREX-CoE/trexio_tools/blob/master/src/trexio_tools/group_tools/determinant.py
def to_determinant_list(orbital_list: list, int64_num: int) -> list:
"""
Convert a list of occupied orbitals from the `orbital_list`
into a list of Slater determinants (in their bit string representation).
Orbitals in the `orbital_list` should be 0-based, namely the lowest orbital has index 0, not 1.
int64_num is the number of 64-bit integers needed to represent a Slater determinant bit string.
It depends on the number of molecular orbitals as follows: int64_num = int((mo_num-1)/64) + 1
"""
if not isinstance(orbital_list, list):
raise TypeError(f"orbital_list should be a list, not {type(orbital_list)}")
det_list = []
bitfield = 0
shift = 0
# since orbital indices are 0-based but the code below works for 1-based --> increment the input indices by +1
orb_list_upshifted = [ orb+1 for orb in orbital_list]
# orbital list has to be sorted in increasing order for the bitfields to be set correctly
orb_list_sorted = sorted(orb_list_upshifted)
for orb in orb_list_sorted:
if orb-shift > 64:
# this removes the 0 bit from the beginning of the bitfield
bitfield = bitfield >> 1
# append a bitfield to the list
det_list.append(bitfield)
bitfield = 0
modulo = int((orb-1)/64)
shift = modulo*64
bitfield |= (1 << (orb-shift))
# this removes the 0 bit from the beginning of the bitfield
bitfield = bitfield >> 1
det_list.append(bitfield)
#print('Popcounts: ', [bin(d).count('1') for d in det_list)
#print('Bitfields: ', [bin(d) for d in det_list])
bitfield_num = len(det_list)
if bitfield_num > int64_num:
raise Exception(f'Number of bitfields {bitfield_num} cannot be more than the int64_num {int64_num}.')
if bitfield_num < int64_num:
for _ in range(int64_num - bitfield_num):
print("Appending an empty bitfield.")
det_list.append(0)
return det_list
def clean(back_end, filename):
"""Remove test files."""
if back_end == trexio.TREXIO_HDF5:
@ -206,16 +262,36 @@ class TestIO:
"""Write CI determinants and coefficients."""
self.open()
# write mo_num (needed later to write determinants)
trexio.write_mo_num(self.test_file, mo_num)
MO_NUM_TEST = 100
trexio.write_mo_num(self.test_file, MO_NUM_TEST)
# get the number of bit-strings per spin component
INT64_NUM_TEST = int((MO_NUM_TEST-1)/64) + 1
int_num = trexio.get_int64_num(self.test_file)
assert int_num == int64_num
assert int_num == INT64_NUM_TEST
# write the number of up and down electrons
trexio.write_electron_up_num(self.test_file, 4)
trexio.write_electron_dn_num(self.test_file, 3)
# orbital lists
orb_list_up = [0,1,2,3]
orb_list_dn = [0,1,2]
# data to write
DET_NUM_TEST = 100
det_up = to_determinant_list(orb_list_up, INT64_NUM_TEST)
det_dn = to_determinant_list(orb_list_dn, INT64_NUM_TEST)
det_list = []
coeff_list = []
for i in range(DET_NUM_TEST):
det_list.append(det_up + det_dn)
coeff_list.append(3.14 + float(i))
# write the data for the ground state
offset = 0
trexio.write_state_id(self.test_file, 0)
trexio.write_determinant_list(self.test_file, offset, det_num, dets)
trexio.write_determinant_list(self.test_file, offset, DET_NUM_TEST, det_list)
assert trexio.has_determinant_list(self.test_file)
trexio.write_determinant_coefficient(self.test_file, offset, det_num, coeffs)
trexio.write_determinant_coefficient(self.test_file, offset, DET_NUM_TEST, coeff_list)
assert trexio.has_determinant_coefficient(self.test_file)
# manually check the consistency between coefficient_size and number of determinants
assert trexio.read_determinant_coefficient_size(self.test_file) == trexio.read_determinant_num(self.test_file)
@ -350,26 +426,6 @@ class TestIO:
if self.test_file.isOpen:
self.test_file.close()
def test_determinant_read(self):
"""Read the CI determinants."""
self.open(mode='r')
# read determinants (list of ints and float coefficients)
buf_size = 100
offset_file = 0
# read full buf_size (i.e. the one that does not reach EOF)
dets_np, read_buf_size, eof = trexio.read_determinant_list(self.test_file, offset_file, buf_size)
#print(f'First complete read of determinant list: {read_buf_size}')
assert not eof
assert read_buf_size == buf_size
assert dets_np[0][0] == 0
assert dets_np[read_buf_size-1][int64_num*2-1] == read_buf_size * int64_num * 2- 1
coefficients_np, read_buf_size, eof = trexio.read_determinant_coefficient(self.test_file, offset_file, buf_size)
#print(f'First complete read of determinant coefficients: {read_buf_size}')
assert not eof
assert read_buf_size == buf_size
if self.test_file.isOpen:
self.test_file.close()
def test_array_str_read(self):
"""Read an array of strings."""

View File

@ -32,7 +32,7 @@ with open('../../trex.json','r') as f:
res += line.rstrip()+'\n'
res += "*/"
return res
#+end_src
#+end_src
#+RESULTS: trex_json
:results:
@ -470,6 +470,7 @@ __trexio_path__ = None
| ~TREXIO_INVALID_STATE~ | 35 | 'Inconsistent state of the file' |
| ~TREXIO_VERSION_PARSING_ISSUE~ | 36 | 'Failed to parse package_version' |
| ~TREXIO_PHASE_CHANGE~ | 37 | 'The function succeeded with a change of sign' |
| ~TREXIO_INVALID_MO_INDEX~ | 38 | 'Invalid MO index' |
# We need to force Emacs not to indent the Python code:
# -*- org-src-preserve-indentation: t
@ -554,6 +555,7 @@ return '\n'.join(result)
#define TREXIO_INVALID_STATE ((trexio_exit_code) 35)
#define TREXIO_VERSION_PARSING_ISSUE ((trexio_exit_code) 36)
#define TREXIO_PHASE_CHANGE ((trexio_exit_code) 37)
#define TREXIO_INVALID_MO_INDEX ((trexio_exit_code) 38)
#+end_src
#+begin_src f90 :tangle prefix_fortran.f90 :exports none
@ -596,6 +598,7 @@ return '\n'.join(result)
integer(trexio_exit_code), parameter :: TREXIO_INVALID_STATE = 35
integer(trexio_exit_code), parameter :: TREXIO_VERSION_PARSING_ISSUE = 36
integer(trexio_exit_code), parameter :: TREXIO_PHASE_CHANGE = 37
integer(trexio_exit_code), parameter :: TREXIO_INVALID_MO_INDEX = 38
#+end_src
#+begin_src python :tangle prefix_python.py :exports none
@ -639,6 +642,7 @@ return '\n'.join(result)
TREXIO_INVALID_STATE = 35
TREXIO_VERSION_PARSING_ISSUE = 36
TREXIO_PHASE_CHANGE = 37
TREXIO_INVALID_MO_INDEX = 38
#+end_src
:end:
@ -5182,11 +5186,7 @@ end interface
integer(c_int32_t), intent(in), value :: max_str_len
character(len=*), intent(in) :: str
character(len=len_trim(str)+1) :: str_c
str_c = trim(str) // c_null_char
trexio_write_$group_str$ = trexio_write_$group_str$_c(trex_file, str_c, max_str_len)
trexio_write_$group_str$ = trexio_write_$group_str$_c(trex_file, trim(str) // c_null_char, max_str_len)
end function trexio_write_$group_str$
#+end_src
@ -5398,7 +5398,10 @@ trexio_read_determinant_list (trexio_t* const file, const int64_t offset_file, i
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (dset == NULL) return TREXIO_INVALID_ARG_2;
if (offset_file < 0) return TREXIO_INVALID_ARG_2;
if (buffer_size_read == NULL) return TREXIO_INVALID_ARG_3;
if (*buffer_size_read < 0) return TREXIO_INVALID_ARG_3;
if (dset == NULL) return TREXIO_INVALID_ARG_4;
if (trexio_has_determinant_list(file) != TREXIO_SUCCESS) return TREXIO_DSET_MISSING;
/* Get the number of int bit fields per determinant */
@ -5453,13 +5456,21 @@ trexio_read_safe_determinant_list (trexio_t* const file, const int64_t offset_fi
}
#+end_src
When writing a determinant list, the indices of the MOs are checked. If they
are out of bounds (<0 or >= mo_num), the error ~TREXIO_INVALID_MO_INDEX~ is returned.
If the number of orbitals in up-spin or down-spin determinants is different from
the number of up-spin and down-spin electrons, the error ~TREXIO_INVALID_ELECTRON_NUM~
is returned.
#+begin_src c :tangle write_determinant_front.c
trexio_exit_code
trexio_write_determinant_list (trexio_t* const file, const int64_t offset_file, const int64_t buffer_size, const int64_t* dset)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (dset == NULL) return TREXIO_INVALID_ARG_2;
if (offset_file < 0) return TREXIO_INVALID_ARG_2;
if (buffer_size <= 0) return TREXIO_INVALID_ARG_3;
if (dset == NULL) return TREXIO_INVALID_ARG_4;
/* Get the number of int bit fields per determinant */
int32_t int_num = 0;
@ -5471,6 +5482,59 @@ trexio_write_determinant_list (trexio_t* const file, const int64_t offset_file,
assert(file->back_end < TREXIO_INVALID_BACK_END);
/* Read the number of mos */
int64_t mo_num = 0L;
rc = trexio_read_mo_num_64(file, &mo_num);
if (rc != TREXIO_SUCCESS) return rc;
// Read up/dn num
int32_t nup = 0;
rc = trexio_read_electron_up_num(file, &nup);
if (rc != TREXIO_SUCCESS) return rc;
int32_t ndn = 0;
rc = trexio_read_electron_dn_num(file, &ndn);
if (rc != TREXIO_SUCCESS) return rc;
/* Check all determinants */
int32_t occ_num_up = 0;
int32_t occ_num_dn = 0;
/* list_up contains first the up-spin orbitals, then the down-spin */
int32_t* list_up = (int32_t*) calloc(nup+ndn,sizeof(int32_t));
if (list_up == NULL) {
return TREXIO_ALLOCATION_FAILED;
}
int32_t* list_dn = &(list_up[nup]);
for (int64_t i=0 ; i<buffer_size ; i+= 2*int_num) {
rc = trexio_to_orbital_list_up_dn(int_num, &dset[i],
list_up, list_dn,
&occ_num_up, &occ_num_dn);
if (rc != TREXIO_SUCCESS) {
free(list_up);
return rc;
}
if (occ_num_up != nup || occ_num_dn != ndn) {
free(list_up);
return TREXIO_INVALID_ELECTRON_NUM;
}
for (int32_t j=0 ; j<nup+ndn ; ++j) {
if (list_up[j] < 0 || list_up[j] >= mo_num) {
free(list_up);
return TREXIO_INVALID_MO_INDEX;
}
}
}
free(list_up);
/* Up to this point, all the determinants have been checked to
have the correct sizes (number of electrons), and MOs in the
correct range */
switch (file->back_end) {
case TREXIO_TEXT:
@ -5868,18 +5932,18 @@ trexio_exit_code trexio_convert_nao_radius_py (const double r,
double* grid_r, int32_t n_grid_r, double* const log_r_out);
trexio_exit_code trexio_evaluate_nao_radial (const int32_t shell_index,
const double r, const int32_t* const grid_start, const int32_t* const grid_size,
const double* const grid_r, const double* const interpolator,
const double* const grid_r, const double* const interpolator,
const double* const normalization, double* const amplitude);
trexio_exit_code trexio_evaluate_nao_radial_all (const int32_t shell_num,
const int32_t* const nucleus_index, const double* const nucleus_coords,
const int32_t* const grid_start, const int32_t* const grid_size,
const double* const grid_r, const double* const interpolator, const double* const normalization,
const int32_t* const nucleus_index, const double* const nucleus_coords,
const int32_t* const grid_start, const int32_t* const grid_size,
const double* const grid_r, const double* const interpolator, const double* const normalization,
const double rx, const double ry, const double rz, double* const amplitude);
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
const double r, int64_t* grid_start, int n_grid_st, int64_t* grid_size,
int n_grid_si, double* grid_r, int n_grid_r, double* interpolator,
int n_grid_si, double* grid_r, int n_grid_r, double* interpolator,
int n_interp, double* normalization, int n_norm, double* const amplitude);
trexio_exit_code trexio_evaluate_nao_radial_all_py (const int32_t shell_num,
@ -6079,7 +6143,7 @@ trexio_evaluate_nao_radial (const int32_t shell_index, const double r, const int
const int32_t i0 = 4*grid_start[shell_index];
// Convert radius to logarithmic units
// Convert radius to logarithmic units
double r_log = 0.0;
trexio_convert_nao_radius_64 (r, grid_r + grid_start[shell_index], &r_log);
int32_t i_log = (int32_t) r_log;
@ -6100,7 +6164,7 @@ trexio_evaluate_nao_radial (const int32_t shell_index, const double r, const int
trexio_exit_code
trexio_evaluate_nao_radial_all (const int32_t shell_num, const int32_t* const nucleus_index, const double* const nucleus_coords, const int32_t* const grid_start,
const int32_t* const grid_size, const double* const grid_r, const double* const interpolator,
const int32_t* const grid_size, const double* const grid_r, const double* const interpolator,
const double* const normalization, const double rx, const double ry, const double rz, double* const amplitude)
{
if (shell_num < 0) return TREXIO_INVALID_ARG_1;
@ -6122,7 +6186,7 @@ trexio_evaluate_nao_radial_all (const int32_t shell_num, const int32_t* const nu
const double r = sqrt(dx*dx + dy*dy + dz*dz);
// All possibly reported errors have been caught above
rc = trexio_evaluate_nao_radial(shell_index, r, grid_start,
rc = trexio_evaluate_nao_radial(shell_index, r, grid_start,
grid_size, grid_r, interpolator, normalization, &amplitude[shell_index]);
if (rc != TREXIO_SUCCESS)
@ -6132,9 +6196,9 @@ trexio_evaluate_nao_radial_all (const int32_t shell_num, const int32_t* const nu
return TREXIO_SUCCESS;
}
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
const double r, int64_t* grid_start, int n_grid_st,
int64_t* grid_size, int n_grid_si, double* grid_r, int n_grid_r,
int64_t* grid_size, int n_grid_si, double* grid_r, int n_grid_r,
double* interpolator, int n_interp, double* normalization, int n_norm, double* const amplitude)
{
// Code needs to be copied because of the use of int64_t mandated by Python
@ -6149,7 +6213,7 @@ trexio_exit_code trexio_evaluate_nao_radial_py (const int shell_index,
const int32_t i0 = 4*grid_start[shell_index];
// Convert radius to logarithmic units
// Convert radius to logarithmic units
double r_log = 0.0;
trexio_convert_nao_radius_64 (r, grid_r + grid_start[shell_index], &r_log);
int32_t i_log = (int32_t) r_log;
@ -6197,7 +6261,7 @@ trexio_exit_code trexio_evaluate_nao_radial_all_py (const int32_t shell_num,
const double r = sqrt(dx*dx + dy*dy + dz*dz);
// All possibly reported errors have been caught above
rc = trexio_evaluate_nao_radial_py(shell_index, r, grid_start, n_grid_st,
rc = trexio_evaluate_nao_radial_py(shell_index, r, grid_start, n_grid_st,
grid_size, n_grid_si, grid_r, n_grid_r, interpolator, n_interp, normalization, n_norm, &amplitudes[shell_index]);
if (rc != TREXIO_SUCCESS)
return rc;
@ -6501,14 +6565,14 @@ def to_orbital_list_up_dn(n_int: int, determinant: list) -> tuple:
def convert_nao_radius(r: float, grid_r) -> float:
"""Converts the radius r as a distance from a nucleus to the shell
s logarithmic grid.
Input:
~r~ - the radius to be converted
~grid_r~ - The radial grid of the shell. Note that this is only the
grid of the shell of interest, not the array of all shells.
Returns:
Float that gives the radius in the shell's logarithmic units
Float that gives the radius in the shell's logarithmic units
Raises:
- Exception from AssertionError if TREXIO return code ~rc~ is different from TREXIO_SUCCESS and prints the error message using trexio_string_of_error.
@ -6525,7 +6589,7 @@ def convert_nao_radius(r: float, grid_r) -> float:
def evaluate_nao_radial(shell_index, r, grid_start, grid_size, grid_r, interpolator, normalization) -> float:
"""Evaluates the radial function of a given NAO shell at a distance from its center.
Input:
~shell_index~ - index of the shell of interest
~r~ - distance from the shell center
@ -6538,7 +6602,7 @@ def evaluate_nao_radial(shell_index, r, grid_start, grid_size, grid_r, interpola
~normalization~ - array of radial function normalization constants.
Returns:
Value of the spline at the given radius
Value of the spline at the given radius
Raises:
- Error from AssertionError if TREXIO return code ~rc~ is different from TREXIO_SUCCESS and prints the error message using trexio_string_of_error.
@ -6555,7 +6619,7 @@ def evaluate_nao_radial(shell_index, r, grid_start, grid_size, grid_r, interpola
def evaluate_nao_radial_all(nucleus_index, nucleus_coords, grid_start,
grid_size, grid_r, interpolator, normalization, r) -> float:
"""Evaluates the radial functions of all NAO shells at a given position in space.
Input:
~nucleus_index~ - array giving the centers of the NAO
~nucleus_coords~ - array giving the coordinates of the NAO centers
@ -6569,7 +6633,7 @@ def evaluate_nao_radial_all(nucleus_index, nucleus_coords, grid_start,
~r~ - the position in space at which the functions are evaluated
Returns:
Array of spline values at ~r~
Array of spline values at ~r~
Raises:
- Error if ~r~ is not three dimensional
@ -6612,11 +6676,9 @@ contains
character, intent(in), value :: mode
integer(trexio_back_end_t), intent(in), value :: back_end
integer(trexio_exit_code), intent(out) :: rc_open
character(len=len_trim(filename)+1) :: filename_c
integer(trexio_exit_code) :: rc
filename_c = trim(filename) // c_null_char
trexio_open = trexio_open_c(filename_c, mode, back_end, rc_open)
trexio_open = trexio_open_c(trim(filename) // c_null_char, mode, back_end, rc_open)
if (trexio_open == 0_8 .or. rc_open /= TREXIO_SUCCESS) then
return
endif
@ -6636,10 +6698,8 @@ contains
integer(trexio_exit_code) function trexio_inquire (filename)
implicit none
character(len=*), intent(in) :: filename
character(len=len_trim(filename)+1) :: filename_c
filename_c = trim(filename) // c_null_char
trexio_inquire = trexio_inquire_c(filename_c)
trexio_inquire = trexio_inquire_c(trim(filename) // c_null_char)
end function trexio_inquire
#+end_src
@ -6650,12 +6710,8 @@ contains
implicit none
character(len=*), intent(in) :: source
character(len=*), intent(in) :: destination
character(len=len_trim(source)+1) :: source_c
character(len=len_trim(destination)+1) :: destination_c
source_c = trim(source) // c_null_char
destination_c = trim(destination) // c_null_char
trexio_cp = trexio_cp_c(source_c, destination_c)
trexio_cp = trexio_cp_c(trim(source) // c_null_char, trim(destination) // c_null_char)
end function trexio_cp
#+end_src

View File

@ -1660,12 +1660,12 @@ trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file,
if (f == NULL) return TREXIO_FILE_ERROR;
/* Specify the line length in order to offset properly.
Each 64-bit integer takes at most 10 slots and requires one space,
Each 64-bit integer takes at most 20 slots and requires one space,
we have int_num integers per up-spin determinant,
then this number is doubled because we have the same number for down-spin electrons,
and then one newline char.
,*/
uint64_t line_length = dims[1]*11UL + 1UL; // 10 digits per int64_t bitfield + 1 space = 11 spots + 1 newline char
uint64_t line_length = dims[1]*21UL + 1UL; // 20 digits per int64_t bitfield + 1 space = 11 spots + 1 newline char
/* Offset in the file according to the provided value of offset_file and optimal line_length */
fseek(f, (long) offset_file * line_length, SEEK_SET);
@ -1677,7 +1677,7 @@ trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file,
uint32_t buf_size = sizeof(buffer);
/* Parameters to post-process the buffer and to get bit fields integers */
uint64_t accum = 0UL;
uint32_t shift_int64 = 11U;
uint32_t shift_int64 = 21U;
/* Counter for number of elements beind processed */
uint64_t count = 0UL;
for (uint64_t i=0UL; i < dims[0]; ++i) {
@ -1697,7 +1697,7 @@ trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file,
Thus, we parse the buffer string int_num*2 times to get the bit field determinants.
,*/
for (uint32_t j=0; j < (uint32_t) dims[1]; ++j) {
rc = sscanf(buffer+accum, "%10" SCNd64, list + dims[1]*i + j);
rc = sscanf(buffer+accum, "%20" SCNd64, list + dims[1]*i + j);
if (rc <= 0) {
fclose(f);
return TREXIO_FAILURE;
@ -1747,7 +1747,7 @@ trexio_exit_code trexio_text_write_determinant_list(trexio_t* const file,
/* The loop below is needed to write a line with int bit fields for alpha and beta electrons */
for (uint32_t j=0; j < (uint32_t) dims[1]; ++j) {
rc = fprintf(f, "%10" PRId64 " ", *(list + i*dims[1] + j));
rc = fprintf(f, "%20" PRId64 " ", *(list + i*dims[1] + j));
if (rc <= 0) {
fclose(f);
return TREXIO_FAILURE;

View File

@ -32,6 +32,16 @@ static int test_write_determinant (const char* file_name, const back_end_t backe
assert(rc == TREXIO_SUCCESS);
}
// write number of up and down electrons for checking consistency of determinants
if (trexio_has_electron_up_num(file) == TREXIO_HAS_NOT) {
rc = trexio_write_electron_up_num(file, 4);
assert(rc == TREXIO_SUCCESS);
}
if (trexio_has_electron_dn_num(file) == TREXIO_HAS_NOT) {
rc = trexio_write_electron_dn_num(file, 3);
assert(rc == TREXIO_SUCCESS);
}
// get the number of int64 bit fields per determinant
int int_num;
rc = trexio_get_int64_num(file, &int_num);
@ -96,7 +106,6 @@ static int test_write_determinant (const char* file_name, const back_end_t backe
// free the allocated memeory
free(det_list);
free(det_coef);
printf("write determinants OK\n");
/*================= END OF TEST ==================*/
@ -133,7 +142,6 @@ static int test_has_determinant(const char* file_name, const back_end_t backend)
assert (rc == TREXIO_SUCCESS);
/*================= END OF TEST ==================*/
printf("has_determinant OK\n");
return 0;
}
@ -218,7 +226,7 @@ static int test_read_determinant (const char* file_name, const back_end_t backen
/*
printf("%s\n", trexio_string_of_error(rc));
for (int i=0; i<size_r; i++) {
printf("%lld %lld\n", det_list_read[6*i], det_list_read[6*i+5]);
printf("%ld %ld\n", det_list_read[6*i], det_list_read[6*i+5]);
}
*/
assert(rc == TREXIO_END);
@ -305,7 +313,6 @@ int main(){
assert (rc == 0);
// check the first write attempt (SIZE elements written in N_CHUNKS chunks)
printf("mo_num = %d\n", mo_nums[i]);
test_write_determinant (TREXIO_FILE, TEST_BACKEND, 0L, mo_nums[i]);
test_has_determinant (TREXIO_FILE, TEST_BACKEND);
test_read_determinant (TREXIO_FILE, TEST_BACKEND, 0L);

View File

@ -5,6 +5,7 @@ program test_trexio
integer :: rc
logical :: have_hdf5
character*(64) :: trexio_file1, trexio_file2
print'(a)' , "============================================"
print'(a,a)' , " TREXIO VERSION STRING : ", TREXIO_PACKAGE_VERSION
@ -14,20 +15,40 @@ program test_trexio
rc = trexio_info()
call system('rm -f -- test_write_f.dir/*.txt test_write_f.dir/*.txt.size test_write_f.dir/.lock ' &
// 'test_write_f2.dir/*.txt test_write_f2.dir/*.txt.size test_write_f2.dir/.lock && ' &
// 'rm -fd -- test_write_f.dir test_write_f2.dir')
print *, 'call test_write(''test_write_f.dir'', TREXIO_TEXT)'
call test_write('test_write_f.dir', TREXIO_TEXT)
rc = trexio_cp('test_write_f.dir', 'test_write_f2.dir')
call trexio_assert(rc, TREXIO_SUCCESS)
print *, 'call test_read(''test_write_f2.dir'', TREXIO_TEXT)'
call test_read('test_write_f2.dir', TREXIO_TEXT)
call system('rm -f -- test_write_f.dir/*.txt test_write_f.dir/*.txt.size test_write_f.dir/.lock ' &
// 'test_write_f2.dir/*.txt test_write_f2.dir/*.txt.size test_write_f2.dir/.lock && ' &
// 'rm -fd -- test_write_f.dir test_write_f2.dir')
trexio_file1 = 'test_write_f.dir'
trexio_file2 = 'test_write_f2.dir'
call test_read_void('test_write_f.dir', TREXIO_TEXT)
call system('rm -f -- '//trim(trexio_file1)//'/*.txt')
call system('rm -f -- '//trim(trexio_file1)//'/*.txt.size')
call system('rm -f -- '//trim(trexio_file1)//'/.lock ')
call system('rm -rf -- '//trim(trexio_file1))
call system('rm -f -- '//trim(trexio_file2)//'/*.txt')
call system('rm -f -- '//trim(trexio_file2)//'/*.txt.size')
call system('rm -f -- '//trim(trexio_file2)//'/.lock ')
call system('rm -rf -- '//trim(trexio_file2))
print *, 'call test_write'
call test_write('test_write_f.dir', TREXIO_TEXT)
rc = trexio_cp(trexio_file1, trexio_file2)
call trexio_assert(rc, TREXIO_SUCCESS)
print *, 'call test_read'
call test_read(trexio_file2, TREXIO_TEXT)
call system('rm -f -- '//trim(trexio_file1)//'/*.txt')
call system('rm -f -- '//trim(trexio_file1)//'/*.txt.size')
call system('rm -f -- '//trim(trexio_file1)//'/.lock ')
call system('rm -rf -- '//trim(trexio_file1))
call system('rm -f -- '//trim(trexio_file2)//'/*.txt')
call system('rm -f -- '//trim(trexio_file2)//'/*.txt.size')
call system('rm -f -- '//trim(trexio_file2)//'/.lock ')
call system('rm -rf -- '//trim(trexio_file2))
print *, 'call test_read_void'
call test_read_void(trexio_file1, TREXIO_TEXT)
! No way to conditionally check whether compilation was done with HDF5
! So temporarily disable the test for HDF5 back end at the moment
@ -69,16 +90,18 @@ subroutine test_write(file_name, back_end)
double precision :: charge(12)
double precision :: coord(3,12)
character(len=32), allocatable :: sym_str
character(len=32) :: sym_str
character(len=8), allocatable :: label(:)
double precision, allocatable :: energy(:)
integer , allocatable :: spin(:)
! sparse data
integer(4) :: index_sparse_ao_2e_int_eri(4,100)
double precision :: value_sparse_ao_2e_int_eri(100)
integer(4), allocatable :: index_sparse_ao_2e_int_eri(:,:)
double precision, allocatable :: value_sparse_ao_2e_int_eri(:)
! determinants
integer :: nup, ndn
integer :: det_occ(10,2)
integer*8 :: det_list(6, 50)
integer*8 :: det_num
integer :: int_num
@ -87,9 +110,12 @@ subroutine test_write(file_name, back_end)
integer(8) :: buf_size_sparse, buf_size_det, offset
integer :: state_id
buf_size_sparse = 100/n_buffers
buf_size_det = 50/n_buffers
allocate(index_sparse_ao_2e_int_eri(4,100), value_sparse_ao_2e_int_eri(100))
! fill sparse indices and values
do i = 1, 100
index_sparse_ao_2e_int_eri(1,i) = 4*i - 3
@ -100,10 +126,16 @@ subroutine test_write(file_name, back_end)
enddo
! fill determinant list
nup = 8
ndn = 6
det_occ = 0
det_occ(1:nup,1) = (/ 1, 2, 3, 4, 76, 128, 129, 143 /)
det_occ(1:ndn,2) = (/ 1, 3, 4, 80, 81, 139 /)
do i = 1, 50
do j = 1, 6
det_list(j,i) = 6*i+(j-1) - 5
enddo
rc = trexio_to_bitfield_list(det_occ(1:8,1), nup, det_list(1:3,i), 3)
call trexio_assert(rc, TREXIO_SUCCESS)
rc = trexio_to_bitfield_list(det_occ(1:6,2), ndn, det_list(4:6,i), 3)
call trexio_assert(rc, TREXIO_SUCCESS)
enddo
! parameters to be written
@ -161,6 +193,18 @@ subroutine test_write(file_name, back_end)
rc = trexio_has_nucleus_charge(trex_file)
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2')
rc = trexio_has_electron_up_num(trex_file)
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2.1')
rc = trexio_write_electron_up_num(trex_file, nup)
call trexio_assert(rc, TREXIO_SUCCESS)
rc = trexio_has_electron_dn_num(trex_file)
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2.2')
rc = trexio_write_electron_dn_num(trex_file, ndn)
call trexio_assert(rc, TREXIO_SUCCESS)
rc = trexio_has_ao_2e_int_eri(trex_file)
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 3')
@ -187,7 +231,6 @@ subroutine test_write(file_name, back_end)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE LABEL')
rc = trexio_write_nucleus_point_group(trex_file, sym_str, 32)
deallocate(sym_str)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE POINT GROUP')
rc = trexio_write_basis_shell_num(trex_file, basis_shell_num)
@ -244,6 +287,7 @@ subroutine test_write(file_name, back_end)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE DET LIST')
offset = offset + buf_size_det
enddo
deallocate(index_sparse_ao_2e_int_eri, value_sparse_ao_2e_int_eri)
rc = trexio_has_nucleus_num(trex_file)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 1')
@ -313,7 +357,7 @@ subroutine test_read(file_name, back_end)
! determinant data
integer*8 :: det_list(6,50)
integer*8 :: det_list_check(3)
integer*8 :: det_list_check(6)
integer*8 :: read_buf_det_size = 20
integer*8 :: offset_det_read = 10
integer*8 :: offset_det_data_read = 5
@ -477,17 +521,39 @@ subroutine test_read(file_name, back_end)
! read a chunk of determinants
rc = trexio_read_determinant_list(trex_file, offset_det_read, read_buf_det_size, &
det_list(1, offset_det_data_read + 1))
!do i = 1,50
! write(*,*) det_list(1,i)
!enddo
call trexio_assert(rc, TREXIO_SUCCESS)
if (det_list(1, 1) == 0 .and. &
det_list(1, offset_det_data_read + 1) == offset_det_read*6 + 1) then
write(*,*) 'SUCCESS READ DET LIST'
else
print *, 'FAILURE DET LIST CHECK'
call exit(-1)
endif
det_list_check = (/15_8, -9223372036854773760_8, 16385_8, 13_8, 98304_8, 1024_8 /)
do i = 1,offset_det_data_read
do j=1,6
if (det_list(j,i) /= 0_8) then
print *, det_list(j,i)
print *, 'FAILURE DET LIST CHECK 1'
call exit(-1)
endif
enddo
enddo
do i = offset_det_data_read+1, offset_det_data_read+read_buf_det_size
do j=1,6
if (det_list(j,i) /= det_list_check(j)) then
print *, det_list(j,i)
print *, 'FAILURE DET LIST CHECK 2'
call exit(-1)
endif
enddo
enddo
do i = offset_det_data_read+read_buf_det_size+1,50
do j=1,6
if (det_list(j,i) /= 0_8) then
print *, det_list(j,i)
print *, 'FAILURE DET LIST CHECK 3'
call exit(-1)
endif
enddo
enddo
write(*,*) 'SUCCESS READ DET LIST'
! read the total number of stored determinants
rc = trexio_read_determinant_num_64(trex_file, determinant_num)
@ -509,7 +575,7 @@ subroutine test_read(file_name, back_end)
! Print binary representation of the first integer bit field of a given determinant
!write(*,'(B64.64)') det_list(1, offset_det_data_read+1)
call trexio_assert(rc, TREXIO_SUCCESS)
if (occ_num_up == 16 .and. occ_num_dn == 5) then
if (occ_num_up == 8 .and. occ_num_dn == 6) then
write(*,*) 'SUCCESS CONVERT DET LIST'
else
print *, 'FAILURE DET CONVERT CHECK'