mirror of
https://github.com/TREX-CoE/trexio.git
synced 2024-12-23 04:43:57 +01:00
Merge pull request #91 from TREX-CoE/add-determinants
Add I/O for determinants
This commit is contained in:
commit
5ca632af2d
@ -112,6 +112,7 @@ TESTS_C = \
|
|||||||
tests/io_dset_float_text \
|
tests/io_dset_float_text \
|
||||||
tests/io_dset_int_text \
|
tests/io_dset_int_text \
|
||||||
tests/io_dset_sparse_text \
|
tests/io_dset_sparse_text \
|
||||||
|
tests/io_determinant_text \
|
||||||
tests/io_safe_dset_float_text \
|
tests/io_safe_dset_float_text \
|
||||||
tests/io_str_text \
|
tests/io_str_text \
|
||||||
tests/io_dset_str_text \
|
tests/io_dset_str_text \
|
||||||
@ -127,6 +128,7 @@ TESTS_C += \
|
|||||||
tests/io_dset_float_hdf5 \
|
tests/io_dset_float_hdf5 \
|
||||||
tests/io_dset_int_hdf5 \
|
tests/io_dset_int_hdf5 \
|
||||||
tests/io_dset_sparse_hdf5 \
|
tests/io_dset_sparse_hdf5 \
|
||||||
|
tests/io_determinant_hdf5 \
|
||||||
tests/io_safe_dset_float_hdf5 \
|
tests/io_safe_dset_float_hdf5 \
|
||||||
tests/io_str_hdf5 \
|
tests/io_str_hdf5 \
|
||||||
tests/io_dset_str_hdf5 \
|
tests/io_dset_str_hdf5 \
|
||||||
|
@ -9,7 +9,7 @@ from setuptools import setup, Extension
|
|||||||
|
|
||||||
def parse_setuppy_commands():
|
def parse_setuppy_commands():
|
||||||
"""Check the commands and respond appropriately.
|
"""Check the commands and respond appropriately.
|
||||||
At the moment it is adapted to ignore checks for numpy, plgconfig, HDF5 flags
|
At the moment it is adapted to ignore checks for numpy, pkgconfig, HDF5 flags
|
||||||
when building the distribution tarball with sdist option.
|
when building the distribution tarball with sdist option.
|
||||||
"""
|
"""
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
@ -93,7 +93,11 @@ pytrexio_module = Extension('pytrexio._pytrexio',
|
|||||||
sources = [os.path.join(srcpath, code) for code in c_files],
|
sources = [os.path.join(srcpath, code) for code in c_files],
|
||||||
include_dirs = [h5_cflags, srcpath, numpy_includedir],
|
include_dirs = [h5_cflags, srcpath, numpy_includedir],
|
||||||
libraries = ['hdf5', 'hdf5_hl'],
|
libraries = ['hdf5', 'hdf5_hl'],
|
||||||
extra_compile_args = ['-Wno-discarded-qualifiers'],
|
extra_compile_args = [
|
||||||
|
'-Wno-discarded-qualifiers',
|
||||||
|
'-Wno-unused-variable',
|
||||||
|
'-Wno-unused-but-set-variable'
|
||||||
|
],
|
||||||
extra_link_args = [h5_ldflags]
|
extra_link_args = [h5_ldflags]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -118,17 +118,40 @@ coords = [
|
|||||||
trexio.write_nucleus_coord(test_file, coords)
|
trexio.write_nucleus_coord(test_file, coords)
|
||||||
|
|
||||||
|
|
||||||
# write mo_num (needed later to write sparse mo_2e_int_eri integrals)
|
# write ao_num (needed later to write sparse ao_2e_int_eri integrals)
|
||||||
trexio.write_mo_num(test_file, 600)
|
trexio.write_ao_num(test_file, 600)
|
||||||
|
|
||||||
# write sparse data in the file
|
# write sparse data in the file
|
||||||
num_integrals = 100
|
num_integrals = 100
|
||||||
indices = [i for i in range(num_integrals*4)]
|
indices = [i for i in range(num_integrals*4)]
|
||||||
values = [(3.14 + float(i)) for i in range(num_integrals)]
|
values = [(3.14 + float(i)) for i in range(num_integrals)]
|
||||||
|
|
||||||
trexio.write_mo_2e_int_eri(test_file, 0, num_integrals, indices, values)
|
trexio.write_ao_2e_int_eri(test_file, 0, num_integrals, indices, values)
|
||||||
|
|
||||||
|
|
||||||
|
# write mo_num (needed later to write determinants)
|
||||||
|
mo_num = 150
|
||||||
|
trexio.write_mo_num(test_file, mo_num)
|
||||||
|
|
||||||
|
int_num = 2*int((mo_num-1)/64+1)
|
||||||
|
|
||||||
|
# write determinants in the file
|
||||||
|
num_dets = 50
|
||||||
|
offset = 0
|
||||||
|
dets = [i for i in range(num_dets*int_num)]
|
||||||
|
coeffs = [(3.14 + float(i)) for i in range(num_dets)]
|
||||||
|
coeffs_s2 = [(6.28 + float(i)) for i in range(num_dets)]
|
||||||
|
|
||||||
|
trexio.write_determinant_list(test_file, offset, num_dets, dets)
|
||||||
|
trexio.write_determinant_coefficient(test_file, offset, num_dets, coeffs)
|
||||||
|
|
||||||
|
test_file.set_state(2)
|
||||||
|
trexio.write_determinant_coefficient(test_file, offset, num_dets, coeffs_s2)
|
||||||
|
test_file.set_state(0)
|
||||||
|
|
||||||
|
# manually check the consistency between coefficient_size and number of determinants
|
||||||
|
assert trexio.read_determinant_coefficient_size(test_file) == trexio.read_determinant_num(test_file)
|
||||||
|
|
||||||
# write nucleus_point_group in the file
|
# write nucleus_point_group in the file
|
||||||
point_group = 'B3U'
|
point_group = 'B3U'
|
||||||
|
|
||||||
@ -210,7 +233,9 @@ assert trexio.has_nucleus_charge(test_file2)
|
|||||||
assert trexio.has_nucleus_coord(test_file2)
|
assert trexio.has_nucleus_coord(test_file2)
|
||||||
assert trexio.has_nucleus_label(test_file2)
|
assert trexio.has_nucleus_label(test_file2)
|
||||||
assert trexio.has_nucleus_point_group(test_file2)
|
assert trexio.has_nucleus_point_group(test_file2)
|
||||||
assert trexio.has_mo_2e_int_eri(test_file2)
|
assert trexio.has_ao_2e_int_eri(test_file2)
|
||||||
|
assert trexio.has_determinant_list(test_file2)
|
||||||
|
assert trexio.has_determinant_coefficient(test_file2)
|
||||||
|
|
||||||
# read nucleus_num from file
|
# read nucleus_num from file
|
||||||
rnum = trexio.read_nucleus_num(test_file2)
|
rnum = trexio.read_nucleus_num(test_file2)
|
||||||
@ -254,14 +279,14 @@ np.testing.assert_array_almost_equal(rcoords_np, np.array(coords).reshape(nucleu
|
|||||||
#rcoords_reshaped_2 = trexio.read_nucleus_coord(test_file2, doReshape=False)
|
#rcoords_reshaped_2 = trexio.read_nucleus_coord(test_file2, doReshape=False)
|
||||||
|
|
||||||
# read number of integrals already present in the file
|
# read number of integrals already present in the file
|
||||||
assert trexio.has_mo_2e_int_eri(test_file2)
|
assert trexio.has_ao_2e_int_eri(test_file2)
|
||||||
assert trexio.read_mo_2e_int_eri_size(test_file2)==num_integrals
|
assert trexio.read_ao_2e_int_eri_size(test_file2)==num_integrals
|
||||||
|
|
||||||
# read sparse arrays on mo_2e_int_eri integrals
|
# read sparse arrays on ao_2e_int_eri integrals
|
||||||
buf_size = 60
|
buf_size = 60
|
||||||
offset_file = 0
|
offset_file = 0
|
||||||
# read full buf_size (i.e. the one that does not reach EOF)
|
# read full buf_size (i.e. the one that does not reach EOF)
|
||||||
indices_sparse_np, value_sparse_np, read_buf_size, eof = trexio.read_mo_2e_int_eri(test_file2, offset_file, buf_size)
|
indices_sparse_np, value_sparse_np, read_buf_size, eof = trexio.read_ao_2e_int_eri(test_file2, offset_file, buf_size)
|
||||||
print(f'First complete sparse read size: {read_buf_size}')
|
print(f'First complete sparse read size: {read_buf_size}')
|
||||||
#print(indices_sparse_np)
|
#print(indices_sparse_np)
|
||||||
assert not eof
|
assert not eof
|
||||||
@ -271,7 +296,7 @@ assert indices_sparse_np[read_buf_size-1][3]==read_buf_size*4-1
|
|||||||
offset_file += buf_size
|
offset_file += buf_size
|
||||||
|
|
||||||
# read incomplete buf_size (i.e. the one that does reach EOF)
|
# read incomplete buf_size (i.e. the one that does reach EOF)
|
||||||
indices_sparse_np, value_sparse_np, read_buf_size, eof2 = trexio.read_mo_2e_int_eri(test_file2, offset_file, buf_size)
|
indices_sparse_np, value_sparse_np, read_buf_size, eof2 = trexio.read_ao_2e_int_eri(test_file2, offset_file, buf_size)
|
||||||
print(f'Second incomplete sparse read size: {read_buf_size}')
|
print(f'Second incomplete sparse read size: {read_buf_size}')
|
||||||
#print(indices_sparse_np)
|
#print(indices_sparse_np)
|
||||||
assert eof2
|
assert eof2
|
||||||
@ -279,6 +304,39 @@ assert read_buf_size==(num_integrals - buf_size)
|
|||||||
assert indices_sparse_np[0][0]==offset_file*4
|
assert indices_sparse_np[0][0]==offset_file*4
|
||||||
assert indices_sparse_np[read_buf_size-1][3]==(offset_file+read_buf_size)*4-1
|
assert indices_sparse_np[read_buf_size-1][3]==(offset_file+read_buf_size)*4-1
|
||||||
|
|
||||||
|
# read number of determinants already present in the file
|
||||||
|
assert trexio.has_determinant_list(test_file2)
|
||||||
|
assert trexio.read_determinant_num(test_file2)==num_dets
|
||||||
|
|
||||||
|
# read determinants (list of ints and float coefficients)
|
||||||
|
buf_size = 20
|
||||||
|
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(test_file2, offset_file, buf_size)
|
||||||
|
print(f'First complete read of determinant list: {read_buf_size}')
|
||||||
|
#print(indices_sparse_np)
|
||||||
|
assert not eof
|
||||||
|
assert read_buf_size==buf_size
|
||||||
|
assert dets_np[0][0]==0
|
||||||
|
assert dets_np[read_buf_size-1][int_num-1]==read_buf_size*int_num-1
|
||||||
|
|
||||||
|
coefficients_np, read_buf_size, eof = trexio.read_determinant_coefficient(test_file2, offset_file, buf_size)
|
||||||
|
print(f'First complete read of determinant coefficients: {read_buf_size}')
|
||||||
|
#print(indices_sparse_np)
|
||||||
|
assert not eof
|
||||||
|
assert read_buf_size==buf_size
|
||||||
|
|
||||||
|
# convert one determinant into a list of orbitals
|
||||||
|
|
||||||
|
dets_tmp = dets_np[read_buf_size-1][:]
|
||||||
|
#print(dets_tmp)
|
||||||
|
|
||||||
|
# divide by 2 because in this test int_num is the total number of integers (i.e. up-spin + down_spin)
|
||||||
|
orb_list_up, orb_list_dn = trexio.to_orbital_list_up_dn(int(int_num/2), dets_tmp)
|
||||||
|
assert(orb_list_up[0] == 2)
|
||||||
|
assert(orb_list_dn[0] == 1)
|
||||||
|
#print(orb_list_up)
|
||||||
|
#print(orb_list_dn)
|
||||||
|
|
||||||
# read array of nuclear labels
|
# read array of nuclear labels
|
||||||
rlabels_2d = trexio.read_nucleus_label(test_file2, dim=nucleus_num)
|
rlabels_2d = trexio.read_nucleus_label(test_file2, dim=nucleus_num)
|
||||||
|
@ -36,6 +36,10 @@
|
|||||||
/* Return num variables as part of the output tuple */
|
/* Return num variables as part of the output tuple */
|
||||||
%apply int *OUTPUT { int32_t* const num};
|
%apply int *OUTPUT { int32_t* const num};
|
||||||
%apply int *OUTPUT { int64_t* const num};
|
%apply int *OUTPUT { int64_t* const num};
|
||||||
|
%apply int *OUTPUT { int32_t* const num_up};
|
||||||
|
%apply int *OUTPUT { int32_t* const num_dn};
|
||||||
|
%apply int *OUTPUT { int64_t* const num_up};
|
||||||
|
%apply int *OUTPUT { int64_t* const num_dn};
|
||||||
%apply float *OUTPUT { float* const num};
|
%apply float *OUTPUT { float* const num};
|
||||||
%apply float *OUTPUT { double* const num};
|
%apply float *OUTPUT { double* const num};
|
||||||
/* Return TREXIO exit code from trexio_open as part of the output tuple */
|
/* Return TREXIO exit code from trexio_open as part of the output tuple */
|
||||||
@ -75,6 +79,7 @@ import_array();
|
|||||||
%numpy_typemaps(float, NPY_FLOAT, int64_t)
|
%numpy_typemaps(float, NPY_FLOAT, int64_t)
|
||||||
%numpy_typemaps(int32_t, NPY_INT32, int64_t)
|
%numpy_typemaps(int32_t, NPY_INT32, int64_t)
|
||||||
%numpy_typemaps(int64_t, NPY_INT64, int64_t)
|
%numpy_typemaps(int64_t, NPY_INT64, int64_t)
|
||||||
|
%numpy_typemaps(bitfield_t, NPY_INT64, int64_t)
|
||||||
/* Enable write|read_safe functions to convert numpy arrays from/to double arrays */
|
/* Enable write|read_safe functions to convert numpy arrays from/to double arrays */
|
||||||
%apply (double* ARGOUT_ARRAY1, int64_t DIM1) {(double* const dset_out, const int64_t dim_out)};
|
%apply (double* ARGOUT_ARRAY1, int64_t DIM1) {(double* const dset_out, const int64_t dim_out)};
|
||||||
%apply (double* IN_ARRAY1, int64_t DIM1) {(const double* dset_in, const int64_t dim_in)};
|
%apply (double* IN_ARRAY1, int64_t DIM1) {(const double* dset_in, const int64_t dim_in)};
|
||||||
@ -93,6 +98,12 @@ import_array();
|
|||||||
|
|
||||||
%apply (double* ARGOUT_ARRAY1, int64_t DIM1) {(double* const value_sparse_read, const int64_t size_value_read)};
|
%apply (double* ARGOUT_ARRAY1, int64_t DIM1) {(double* const value_sparse_read, const int64_t size_value_read)};
|
||||||
%apply (int32_t* ARGOUT_ARRAY1, int64_t DIM1) {(int32_t* const index_sparse_read, const int64_t size_index_read)};
|
%apply (int32_t* ARGOUT_ARRAY1, int64_t DIM1) {(int32_t* const index_sparse_read, const int64_t size_index_read)};
|
||||||
|
/* Enable write|read_safe functions to convert numpy arrays from orbital list arrays */
|
||||||
|
%apply (int32_t* ARGOUT_ARRAY1, int64_t DIM1) {(int32_t* const dset_up_out, const int64_t dim_up_out)};
|
||||||
|
%apply (int32_t* ARGOUT_ARRAY1, int64_t DIM1) {(int32_t* const dset_dn_out, const int64_t dim_dn_out)};
|
||||||
|
%apply (int64_t* ARGOUT_ARRAY1, int64_t DIM1) {(int64_t* const dset_up_out, const int64_t dim_up_out)};
|
||||||
|
%apply (int64_t* ARGOUT_ARRAY1, int64_t DIM1) {(int64_t* const dset_dn_out, const int64_t dim_dn_out)};
|
||||||
|
%apply (bitfield_t* IN_ARRAY1, int64_t DIM1) {(const bitfield_t* dset_in, const int64_t dim_in)};
|
||||||
|
|
||||||
/* This tells SWIG to treat char ** dset_in pattern as a special case
|
/* This tells SWIG to treat char ** dset_in pattern as a special case
|
||||||
Enables access to trexio_[...]_write_dset_str set of functions directly, i.e.
|
Enables access to trexio_[...]_write_dset_str set of functions directly, i.e.
|
||||||
|
@ -38,9 +38,14 @@ echo "" >> trexio_f.f90
|
|||||||
# c front end
|
# c front end
|
||||||
cat populated/pop_*.c >> trexio.c
|
cat populated/pop_*.c >> trexio.c
|
||||||
cat populated/pop_*.h >> trexio.h
|
cat populated/pop_*.h >> trexio.h
|
||||||
|
# add determinant part
|
||||||
|
cat hrw_determinant_front.h >> trexio.h
|
||||||
|
cat *_determinant_front.c >> trexio.c
|
||||||
|
|
||||||
# fortran front end
|
# fortran front end
|
||||||
cat populated/pop_*.f90 >> trexio_f.f90
|
cat populated/pop_*.f90 >> trexio_f.f90
|
||||||
|
# add determinant part
|
||||||
|
cat *_determinant_front_fortran.f90 >> trexio_f.f90
|
||||||
# add helper functions
|
# add helper functions
|
||||||
cat helper_fortran.f90 >> trexio_f.f90
|
cat helper_fortran.f90 >> trexio_f.f90
|
||||||
cat populated/pop_*.fh_90 >> trexio_f.f90
|
cat populated/pop_*.fh_90 >> trexio_f.f90
|
||||||
@ -48,6 +53,7 @@ cat populated/pop_*.fh_90 >> trexio_f.f90
|
|||||||
# python front end
|
# python front end
|
||||||
cat basic_python.py >> trexio.py
|
cat basic_python.py >> trexio.py
|
||||||
cat populated/pop_*.py >> trexio.py
|
cat populated/pop_*.py >> trexio.py
|
||||||
|
cat *_determinant_front.py >> trexio.py
|
||||||
|
|
||||||
# suffixes
|
# suffixes
|
||||||
cat suffix_s_front.h >> trexio_s.h
|
cat suffix_s_front.h >> trexio_s.h
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -14,5 +14,8 @@ cat populated/pop_delete_group_hdf5.c >> trexio_hdf5.c
|
|||||||
cat populated/pop_hrw_*.h >> trexio_hdf5.h
|
cat populated/pop_hrw_*.h >> trexio_hdf5.h
|
||||||
cat populated/pop_delete_group_hdf5.h >> trexio_hdf5.h
|
cat populated/pop_delete_group_hdf5.h >> trexio_hdf5.h
|
||||||
|
|
||||||
|
cat hrw_determinant_hdf5.h >> trexio_hdf5.h
|
||||||
|
cat *_determinant_hdf5.c >> trexio_hdf5.c
|
||||||
|
|
||||||
cat helpers_hdf5.c >> trexio_hdf5.c
|
cat helpers_hdf5.c >> trexio_hdf5.c
|
||||||
cat suffix_hdf5.h >> trexio_hdf5.h
|
cat suffix_hdf5.h >> trexio_hdf5.h
|
||||||
|
@ -265,6 +265,7 @@ trexio_hdf5_has_$group_num$ (trexio_t* const file)
|
|||||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||||
|
if (f->$group$_group == (hsize_t) 0) return TREXIO_HAS_NOT;
|
||||||
|
|
||||||
htri_t status = H5Aexists(f->$group$_group, $GROUP_NUM$_NAME);
|
htri_t status = H5Aexists(f->$group$_group, $GROUP_NUM$_NAME);
|
||||||
/* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */
|
/* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */
|
||||||
@ -399,6 +400,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
|
|||||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
if (f->$group$_group == (hsize_t) 0) return TREXIO_HAS_NOT;
|
||||||
|
|
||||||
herr_t status = H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME);
|
herr_t status = H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME);
|
||||||
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
||||||
@ -441,7 +443,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
|
|||||||
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
|
||||||
hid_t index_dtype;
|
hid_t index_dtype;
|
||||||
const void* index_p;
|
void* index_p = NULL;
|
||||||
uint64_t size_ranked = (uint64_t) size * $group_dset_rank$;
|
uint64_t size_ranked = (uint64_t) size * $group_dset_rank$;
|
||||||
/* Determine the optimal type for storing indices depending on the size_max (usually mo_num or ao_num) */
|
/* Determine the optimal type for storing indices depending on the size_max (usually mo_num or ao_num) */
|
||||||
if (size_max < UINT8_MAX) {
|
if (size_max < UINT8_MAX) {
|
||||||
@ -461,7 +463,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
|
|||||||
index_p = index;
|
index_p = index;
|
||||||
index_dtype = H5T_NATIVE_UINT16;
|
index_dtype = H5T_NATIVE_UINT16;
|
||||||
} else {
|
} else {
|
||||||
index_p = (const int32_t*) index_sparse;
|
index_p = (int32_t*) index_sparse;
|
||||||
index_dtype = H5T_NATIVE_INT32;
|
index_dtype = H5T_NATIVE_INT32;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,11 +548,11 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file,
|
|||||||
trexio_exit_code rc_read;
|
trexio_exit_code rc_read;
|
||||||
|
|
||||||
// attempt to read indices
|
// attempt to read indices
|
||||||
rc_read = trexio_hdf5_open_read_dset_sparse(f->$group$_group, dset_index_name, offset_i, count_i, NULL, is_index, index_read);
|
rc_read = trexio_hdf5_open_read_dset_sparse(f->$group$_group, dset_index_name, $group_dset_rank$, offset_i, count_i, NULL, is_index, index_read);
|
||||||
if (rc_read != TREXIO_SUCCESS && rc_read != TREXIO_END) return rc_read;
|
if (rc_read != TREXIO_SUCCESS && rc_read != TREXIO_END) return rc_read;
|
||||||
// attempt to read values
|
// attempt to read values
|
||||||
// when EOF is encountered - the count_v[0] is modified and contains the number of elements being read
|
// when EOF is encountered - the count_v[0] is modified and contains the number of elements being read
|
||||||
rc_read = trexio_hdf5_open_read_dset_sparse(f->$group$_group, dset_value_name, offset_v, count_v, eof_read_size, is_value, value_read);
|
rc_read = trexio_hdf5_open_read_dset_sparse(f->$group$_group, dset_value_name, 1, offset_v, count_v, eof_read_size, is_value, value_read);
|
||||||
if (rc_read != TREXIO_SUCCESS && rc_read != TREXIO_END) return rc_read;
|
if (rc_read != TREXIO_SUCCESS && rc_read != TREXIO_END) return rc_read;
|
||||||
|
|
||||||
return rc_read;
|
return rc_read;
|
||||||
@ -564,6 +566,7 @@ trexio_hdf5_read_$group_dset$_size (trexio_t* const file, int64_t* const size_ma
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (size_max == NULL) return TREXIO_INVALID_ARG_2;
|
||||||
|
|
||||||
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||||
|
|
||||||
@ -600,6 +603,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
|
|||||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
if (f->$group$_group == (hsize_t) 0) return TREXIO_HAS_NOT;
|
||||||
|
|
||||||
herr_t status = H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME "_values");
|
herr_t status = H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME "_values");
|
||||||
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
||||||
@ -798,6 +802,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
|
|||||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
if (f->$group$_group == (hsize_t) 0) return TREXIO_HAS_NOT;
|
||||||
|
|
||||||
herr_t status = H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME);
|
herr_t status = H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME);
|
||||||
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
||||||
@ -927,6 +932,7 @@ trexio_hdf5_has_$group_str$ (trexio_t* const file)
|
|||||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||||
|
if (f->$group$_group == (hsize_t) 0) return TREXIO_HAS_NOT;
|
||||||
|
|
||||||
htri_t status = H5Aexists(f->$group$_group, $GROUP_STR$_NAME);
|
htri_t status = H5Aexists(f->$group$_group, $GROUP_STR$_NAME);
|
||||||
/* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */
|
/* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */
|
||||||
@ -977,6 +983,262 @@ trexio_hdf5_delete_$group$ (trexio_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
* Source code for the determinant part
|
||||||
|
|
||||||
|
Each array is stored in a separate HDF5 dataset due to the fact that determinant I/O has to be decoupled.
|
||||||
|
Chunks are used to read/write the data to prevent memory overflow. Chunks have a given ~int64_t dims[0]*dims[1]~.
|
||||||
|
Size specifies the number of data items (e.g. determinants) to process.
|
||||||
|
|
||||||
|
#+begin_src c :tangle hrw_determinant_hdf5.h :exports none
|
||||||
|
trexio_exit_code trexio_hdf5_has_determinant_list(trexio_t* const file);
|
||||||
|
trexio_exit_code trexio_hdf5_read_determinant_list(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, int64_t* const eof_read_size, int64_t* const list);
|
||||||
|
trexio_exit_code trexio_hdf5_write_determinant_list(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, const int64_t* list);
|
||||||
|
trexio_exit_code trexio_hdf5_has_determinant_coefficient(trexio_t* const file);
|
||||||
|
trexio_exit_code trexio_hdf5_read_determinant_coefficient(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, int64_t* const eof_read_size, double* const coeff);
|
||||||
|
trexio_exit_code trexio_hdf5_write_determinant_coefficient(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, const double* coeff);
|
||||||
|
trexio_exit_code trexio_hdf5_read_determinant_coefficient_size(trexio_t* const file, int64_t* const size_max);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src c :tangle read_determinant_hdf5.c
|
||||||
|
trexio_exit_code trexio_hdf5_read_determinant_list(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
int64_t* const eof_read_size,
|
||||||
|
int64_t* const list)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
if (list == NULL) return TREXIO_INVALID_ARG_6;
|
||||||
|
|
||||||
|
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||||
|
|
||||||
|
char dset_det_name[256] = "determinant_list";
|
||||||
|
|
||||||
|
hsize_t offset[1] = {(hsize_t) offset_file * dims[1]};
|
||||||
|
hsize_t count[1] = {(hsize_t) dims[0] * dims[1]};
|
||||||
|
|
||||||
|
/* Attempt to read determinants (if EOF -> eof_read_size is modified with the number of elements read and return code is TREXIO_END)
|
||||||
|
0 argument below is requires to skip internal treatment specific to sparse indices (i.e. their de-compression).*/
|
||||||
|
return trexio_hdf5_open_read_dset_sparse(f->determinant_group, dset_det_name, (uint32_t) dims[1], offset, count, eof_read_size, 0, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code trexio_hdf5_read_determinant_coefficient(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
int64_t* const eof_read_size,
|
||||||
|
double* const coeff)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
if (coeff == NULL) return TREXIO_INVALID_ARG_6;
|
||||||
|
|
||||||
|
char dset_coeff_name[128];
|
||||||
|
memset(dset_coeff_name, 0, sizeof(dset_coeff_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(dset_coeff_name, "determinant_coefficient_state_%" PRId32, trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(dset_coeff_name, "determinant_coefficient", 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||||
|
|
||||||
|
hsize_t offset[1] = {(hsize_t) offset_file};
|
||||||
|
hsize_t count[1] = {(hsize_t) dims[0]};
|
||||||
|
|
||||||
|
/* Attempt to read determinants (if EOF -> eof_read_size is modified with the number of elements read and return code is TREXIO_END)
|
||||||
|
0 argument below is requires to skip internal treatment specific to sparse indices (i.e. their de-compression).*/
|
||||||
|
return trexio_hdf5_open_read_dset_sparse(f->determinant_group, dset_coeff_name, 1, offset, count, eof_read_size, 0, coeff);
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src c :tangle write_determinant_hdf5.c
|
||||||
|
trexio_exit_code trexio_hdf5_write_determinant_list(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
const int64_t* list)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (list == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
|
||||||
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
|
||||||
|
hid_t det_dtype = H5T_NATIVE_INT64;
|
||||||
|
uint64_t size_ranked = dims[1]*dims[0];
|
||||||
|
|
||||||
|
/* Arrays of chunk dims that will be used for chunking the dataset */
|
||||||
|
const hsize_t chunk_dims[1] = {size_ranked};
|
||||||
|
|
||||||
|
/* Indices and values are stored as 2 independent datasets in the HDF5 file */
|
||||||
|
char dset_det_name[256] = "determinant_list";
|
||||||
|
|
||||||
|
trexio_exit_code rc_write = TREXIO_FAILURE;
|
||||||
|
/* NOTE: chunk size is set upon creation of the HDF5 dataset and cannot be changed ! */
|
||||||
|
if ( H5LTfind_dataset(f->determinant_group, dset_det_name) != 1 ) {
|
||||||
|
/* If the file does not exist -> create it and write */
|
||||||
|
|
||||||
|
/* Create chunked dataset with det_dtype datatype and write indices into it */
|
||||||
|
rc_write = trexio_hdf5_create_write_dset_sparse(f->determinant_group, dset_det_name, det_dtype, chunk_dims, list);
|
||||||
|
if (rc_write != TREXIO_SUCCESS) return rc_write;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* If the file exists -> open it and write */
|
||||||
|
hsize_t offset_data[1] = {(hsize_t) offset_file * dims[1]};
|
||||||
|
|
||||||
|
/* Create chunked dataset with det_dtype datatype and write indices into it */
|
||||||
|
rc_write = trexio_hdf5_open_write_dset_sparse(f->determinant_group, dset_det_name, det_dtype, chunk_dims, offset_data, list);
|
||||||
|
if (rc_write != TREXIO_SUCCESS) return rc_write;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code trexio_hdf5_write_determinant_coefficient(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
const double* coeff)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (coeff == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
|
||||||
|
char dset_coeff_name[128];
|
||||||
|
memset(dset_coeff_name, 0, sizeof(dset_coeff_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(dset_coeff_name, "determinant_coefficient_state_%" PRId32, trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(dset_coeff_name, "determinant_coefficient", 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
|
||||||
|
hid_t det_dtype = H5T_NATIVE_DOUBLE;
|
||||||
|
|
||||||
|
/* Arrays of chunk dims that will be used for chunking the dataset */
|
||||||
|
const hsize_t chunk_dims[1] = {(hsize_t) dims[0]};
|
||||||
|
|
||||||
|
trexio_exit_code rc_write = TREXIO_FAILURE;
|
||||||
|
/* NOTE: chunk size is set upon creation of the HDF5 dataset and cannot be changed ! */
|
||||||
|
if ( H5LTfind_dataset(f->determinant_group, dset_coeff_name) != 1 ) {
|
||||||
|
/* If the file does not exist -> create it and write */
|
||||||
|
|
||||||
|
/* Create chunked dataset with det_dtype datatype and write indices into it */
|
||||||
|
rc_write = trexio_hdf5_create_write_dset_sparse(f->determinant_group, dset_coeff_name, det_dtype, chunk_dims, coeff);
|
||||||
|
if (rc_write != TREXIO_SUCCESS) return rc_write;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* If the file exists -> open it and write */
|
||||||
|
hsize_t offset_data[1] = {(hsize_t) offset_file};
|
||||||
|
|
||||||
|
/* Create chunked dataset with det_dtype datatype and write indices into it */
|
||||||
|
rc_write = trexio_hdf5_open_write_dset_sparse(f->determinant_group, dset_coeff_name, det_dtype, chunk_dims, offset_data, coeff);
|
||||||
|
if (rc_write != TREXIO_SUCCESS) return rc_write;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code
|
||||||
|
trexio_hdf5_read_determinant_coefficient_size (trexio_t* const file, int64_t* const size_max)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (size_max == NULL) return TREXIO_INVALID_ARG_2;
|
||||||
|
|
||||||
|
char dset_coeff_name[128];
|
||||||
|
memset(dset_coeff_name, 0, sizeof(dset_coeff_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(dset_coeff_name, "determinant_coefficient_state_%" PRId32, trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(dset_coeff_name, "determinant_coefficient", 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||||
|
|
||||||
|
hid_t dset_id = H5Dopen(f->determinant_group, dset_coeff_name, H5P_DEFAULT);
|
||||||
|
if (dset_id <= 0) return TREXIO_INVALID_ID;
|
||||||
|
|
||||||
|
hid_t fspace_id = H5Dget_space(dset_id);
|
||||||
|
if (fspace_id < 0) {
|
||||||
|
H5Dclose(dset_id);
|
||||||
|
return TREXIO_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate space for the dimensions to be read
|
||||||
|
hsize_t ddims[1] = {0};
|
||||||
|
|
||||||
|
// get the rank and dimensions of the dataset
|
||||||
|
H5Sget_simple_extent_dims(fspace_id, ddims, NULL);
|
||||||
|
|
||||||
|
H5Dclose(dset_id);
|
||||||
|
H5Sclose(fspace_id);
|
||||||
|
|
||||||
|
*size_max = (int64_t) ddims[0];
|
||||||
|
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src c :tangle has_determinant_hdf5.c
|
||||||
|
trexio_exit_code trexio_hdf5_has_determinant_list(trexio_t* const file)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
if (f->determinant_group == (hsize_t) 0) return TREXIO_HAS_NOT;
|
||||||
|
|
||||||
|
herr_t status = H5LTfind_dataset(f->determinant_group, "determinant_list");
|
||||||
|
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
||||||
|
if (status == 1){
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
} else if (status == 0) {
|
||||||
|
return TREXIO_HAS_NOT;
|
||||||
|
} else {
|
||||||
|
return TREXIO_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code trexio_hdf5_has_determinant_coefficient(trexio_t* const file)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
|
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||||
|
if (f->determinant_group == (hsize_t) 0) return TREXIO_HAS_NOT;
|
||||||
|
|
||||||
|
char dset_coeff_name[128];
|
||||||
|
memset(dset_coeff_name, 0, sizeof(dset_coeff_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(dset_coeff_name, "determinant_coefficient_state_%" PRId32, trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(dset_coeff_name, "determinant_coefficient", 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
herr_t status = H5LTfind_dataset(f->determinant_group, dset_coeff_name);
|
||||||
|
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
||||||
|
if (status == 1){
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
} else if (status == 0) {
|
||||||
|
return TREXIO_HAS_NOT;
|
||||||
|
} else {
|
||||||
|
return TREXIO_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
* Helper functions
|
* Helper functions
|
||||||
|
|
||||||
#+begin_src c :tangle helpers_hdf5.c
|
#+begin_src c :tangle helpers_hdf5.c
|
||||||
@ -1113,6 +1375,7 @@ trexio_hdf5_open_write_dset_sparse (const hid_t group_id,
|
|||||||
trexio_exit_code
|
trexio_exit_code
|
||||||
trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
|
trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
|
||||||
const char* dset_name,
|
const char* dset_name,
|
||||||
|
const uint32_t dset_rank,
|
||||||
const hsize_t* offset_file,
|
const hsize_t* offset_file,
|
||||||
hsize_t* const size_read,
|
hsize_t* const size_read,
|
||||||
int64_t* const eof_read_size,
|
int64_t* const eof_read_size,
|
||||||
@ -1121,6 +1384,7 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
const int h5_rank = 1;
|
const int h5_rank = 1;
|
||||||
|
if (dset_rank == 0) return TREXIO_INVALID_ARG_3;
|
||||||
|
|
||||||
// get the dataset handle
|
// get the dataset handle
|
||||||
hid_t dset_id = H5Dopen(group_id, dset_name, H5P_DEFAULT);
|
hid_t dset_id = H5Dopen(group_id, dset_name, H5P_DEFAULT);
|
||||||
@ -1151,9 +1415,9 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
|
|||||||
if (max_offset > ddims[0]) {
|
if (max_offset > ddims[0]) {
|
||||||
is_EOF = 1;
|
is_EOF = 1;
|
||||||
// lower the value of count to reduce the number of elements which will be read
|
// lower the value of count to reduce the number of elements which will be read
|
||||||
size_read[0] -= max_offset - ddims[0];
|
size_read[0] -= (max_offset - ddims[0]);
|
||||||
// modified the value of eof_read_size passed by address
|
// modified the value of eof_read_size passed by address
|
||||||
if (eof_read_size != NULL) *eof_read_size = size_read[0];
|
if (eof_read_size != NULL) *eof_read_size = size_read[0]/dset_rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case when reading int indices
|
// special case when reading int indices
|
||||||
@ -1238,7 +1502,7 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
|
|||||||
#+begin_src c :tangle suffix_hdf5.h
|
#+begin_src c :tangle suffix_hdf5.h
|
||||||
trexio_exit_code trexio_hdf5_create_write_dset_sparse (const hid_t group_id, const char* dset_name, const hid_t dtype_id, const hsize_t* chunk_dims, const void* data_sparse);
|
trexio_exit_code trexio_hdf5_create_write_dset_sparse (const hid_t group_id, const char* dset_name, const hid_t dtype_id, const hsize_t* chunk_dims, const void* data_sparse);
|
||||||
trexio_exit_code trexio_hdf5_open_write_dset_sparse (const hid_t group_id, const char* dset_name, const hid_t dtype_id, const hsize_t* chunk_dims, const hsize_t* offset_file, const void* data_sparse);
|
trexio_exit_code trexio_hdf5_open_write_dset_sparse (const hid_t group_id, const char* dset_name, const hid_t dtype_id, const hsize_t* chunk_dims, const hsize_t* offset_file, const void* data_sparse);
|
||||||
trexio_exit_code trexio_hdf5_open_read_dset_sparse (const hid_t group_id, const char* dset_name, const hsize_t* offset_file, hsize_t* const size_read, int64_t* const eof_read_size, const int is_index, void* const data_sparse);
|
trexio_exit_code trexio_hdf5_open_read_dset_sparse (const hid_t group_id, const char* dset_name, const uint32_t dset_rank, const hsize_t* offset_file, hsize_t* const size_read, int64_t* const eof_read_size, const int is_index, void* const data_sparse);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#+end_src
|
#+end_src
|
||||||
|
@ -10,6 +10,9 @@ cat populated/pop_struct_text_group_dset.h >> trexio_text.h
|
|||||||
cat populated/pop_struct_text_group.h >> trexio_text.h
|
cat populated/pop_struct_text_group.h >> trexio_text.h
|
||||||
cat basic_text.h >> trexio_text.h
|
cat basic_text.h >> trexio_text.h
|
||||||
|
|
||||||
|
cat hrw_determinant_text.h >> trexio_text.h
|
||||||
|
cat *_determinant_text.c >> trexio_text.c
|
||||||
|
|
||||||
cat populated/pop_free_group_text.c >> trexio_text.c
|
cat populated/pop_free_group_text.c >> trexio_text.c
|
||||||
cat populated/pop_read_group_text.c >> trexio_text.c
|
cat populated/pop_read_group_text.c >> trexio_text.c
|
||||||
cat populated/pop_flush_group_text.c >> trexio_text.c
|
cat populated/pop_flush_group_text.c >> trexio_text.c
|
||||||
|
@ -3,6 +3,18 @@
|
|||||||
#+SETUPFILE: ../../docs/theme.setup
|
#+SETUPFILE: ../../docs/theme.setup
|
||||||
# -*- mode: org -*-
|
# -*- mode: org -*-
|
||||||
|
|
||||||
|
The "file" produced by the text back end is a directory with one
|
||||||
|
file per group.
|
||||||
|
|
||||||
|
When the file is open, it is locked by the current process. No other
|
||||||
|
process can read/write the same file. This guarantees that the
|
||||||
|
representation in memory is consistent with the file and avoid
|
||||||
|
re-reading the file before writing.
|
||||||
|
To lock the file, we lock the =.lock= file which is present in the
|
||||||
|
directory.
|
||||||
|
|
||||||
|
The file is written when closed, or when the flush function is called.
|
||||||
|
|
||||||
* Constant file prefixes (not used by the generator) :noexport:
|
* Constant file prefixes (not used by the generator) :noexport:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
@ -61,21 +73,7 @@
|
|||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* TEXT back end
|
* Template for group-related structures in text back end
|
||||||
|
|
||||||
The "file" produced by the text back end is a directory with one
|
|
||||||
file per group.
|
|
||||||
|
|
||||||
When the file is open, it is locked by the current process. No other
|
|
||||||
process can read/write the same file. This guarantees that the
|
|
||||||
representation in memory is consistent with the file and avoid
|
|
||||||
re-reading the file before writing.
|
|
||||||
To lock the file, we lock the =.lock= file which is present in the
|
|
||||||
directory.
|
|
||||||
|
|
||||||
The file is written when closed, or when the flush function is called.
|
|
||||||
|
|
||||||
** Template for group-related structures in text back end
|
|
||||||
|
|
||||||
#+begin_src c :tangle struct_text_group_dset.h
|
#+begin_src c :tangle struct_text_group_dset.h
|
||||||
typedef struct $group$_s {
|
typedef struct $group$_s {
|
||||||
@ -91,7 +89,7 @@ typedef struct $group$_s {
|
|||||||
} $group$_t;
|
} $group$_t;
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Template for general structure in text back end
|
* Template for general structure in text back end
|
||||||
|
|
||||||
#+begin_src c :tangle struct_text_group.h
|
#+begin_src c :tangle struct_text_group.h
|
||||||
typedef struct trexio_text_s {
|
typedef struct trexio_text_s {
|
||||||
@ -101,7 +99,7 @@ typedef struct trexio_text_s {
|
|||||||
} trexio_text_t;
|
} trexio_text_t;
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Initialize function (constant part)
|
* Initialize function (constant part)
|
||||||
|
|
||||||
#+begin_src c :tangle basic_text.h :exports none
|
#+begin_src c :tangle basic_text.h :exports none
|
||||||
trexio_exit_code trexio_text_init(trexio_t* const file);
|
trexio_exit_code trexio_text_init(trexio_t* const file);
|
||||||
@ -246,7 +244,7 @@ trexio_text_unlock (trexio_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Deinitialize function (templated part)
|
* Deinitialize function (templated part)
|
||||||
|
|
||||||
#+begin_src c :tangle basic_text_group.c
|
#+begin_src c :tangle basic_text_group.c
|
||||||
trexio_exit_code
|
trexio_exit_code
|
||||||
@ -265,7 +263,7 @@ trexio_text_deinit (trexio_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Template for text read a group
|
* Template for text read a group
|
||||||
|
|
||||||
#+begin_src c :tangle read_group_text.h :exports none
|
#+begin_src c :tangle read_group_text.h :exports none
|
||||||
$group$_t* trexio_text_read_$group$(trexio_text_t* const file);
|
$group$_t* trexio_text_read_$group$(trexio_text_t* const file);
|
||||||
@ -567,7 +565,7 @@ trexio_text_read_$group$ (trexio_text_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Template for text flush a group
|
* Template for text flush a group
|
||||||
|
|
||||||
#+begin_src c :tangle flush_group_text.h :exports none
|
#+begin_src c :tangle flush_group_text.h :exports none
|
||||||
trexio_exit_code trexio_text_flush_$group$(trexio_text_t* const file);
|
trexio_exit_code trexio_text_flush_$group$(trexio_text_t* const file);
|
||||||
@ -632,7 +630,7 @@ trexio_text_flush_$group$ (trexio_text_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Template for text free memory
|
* Template for text free memory
|
||||||
|
|
||||||
Memory is allocated when reading. The following function frees memory.
|
Memory is allocated when reading. The following function frees memory.
|
||||||
|
|
||||||
@ -678,7 +676,7 @@ trexio_text_free_$group$ (trexio_text_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Template for has/read/write a numerical attribute
|
* Template for has/read/write a numerical attribute
|
||||||
|
|
||||||
#+begin_src c :tangle hrw_attr_num_text.h :exports none
|
#+begin_src c :tangle hrw_attr_num_text.h :exports none
|
||||||
trexio_exit_code trexio_text_has_$group_num$ (trexio_t* const file);
|
trexio_exit_code trexio_text_has_$group_num$ (trexio_t* const file);
|
||||||
@ -742,7 +740,7 @@ trexio_text_has_$group_num$ (trexio_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Template for has/read/write a dataset of numerical data
|
* Template for has/read/write a dataset of numerical data
|
||||||
|
|
||||||
The ~group_dset~ array is assumed allocated with the appropriate size.
|
The ~group_dset~ array is assumed allocated with the appropriate size.
|
||||||
|
|
||||||
@ -837,7 +835,7 @@ trexio_text_has_$group_dset$ (trexio_t* const file)
|
|||||||
|
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
** Template for has/read/write a dataset of strings
|
* Template for has/read/write a dataset of strings
|
||||||
|
|
||||||
The ~group_dset~ array is assumed allocated with the appropriate size.
|
The ~group_dset~ array is assumed allocated with the appropriate size.
|
||||||
|
|
||||||
@ -937,7 +935,7 @@ trexio_text_has_$group_dset$ (trexio_t* const file)
|
|||||||
|
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
** Template for has/read/write a string attribute
|
* Template for has/read/write a string attribute
|
||||||
|
|
||||||
#+begin_src c :tangle hrw_attr_str_text.h :exports none
|
#+begin_src c :tangle hrw_attr_str_text.h :exports none
|
||||||
trexio_exit_code trexio_text_has_$group_str$ (trexio_t* const file);
|
trexio_exit_code trexio_text_has_$group_str$ (trexio_t* const file);
|
||||||
@ -1012,7 +1010,7 @@ trexio_text_has_$group_str$ (trexio_t* const file)
|
|||||||
|
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
** Template for has/read/write the dataset of sparse data
|
* Template for has/read/write the dataset of sparse data
|
||||||
|
|
||||||
Each sparse array is stored in a separate =.txt= file due to the fact that sparse I/O has to be decoupled
|
Each sparse array is stored in a separate =.txt= file due to the fact that sparse I/O has to be decoupled
|
||||||
from conventional write/read/flush behaviour of the TEXT back end. Chunks are used to read/write sparse data
|
from conventional write/read/flush behaviour of the TEXT back end. Chunks are used to read/write sparse data
|
||||||
@ -1284,7 +1282,7 @@ trexio_exit_code trexio_text_has_$group_dset$(trexio_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Template for text delete a group (UNSAFE mode)
|
* Template for text delete a group (UNSAFE mode)
|
||||||
|
|
||||||
#+begin_src c :tangle delete_group_text.h :exports none
|
#+begin_src c :tangle delete_group_text.h :exports none
|
||||||
trexio_exit_code trexio_text_delete_$group$ (trexio_t* const file);
|
trexio_exit_code trexio_text_delete_$group$ (trexio_t* const file);
|
||||||
@ -1313,6 +1311,411 @@ trexio_text_delete_$group$ (trexio_t* const file)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
* Source code for the determinant part
|
||||||
|
|
||||||
|
Each array is stored in a separate =.txt= file due to the fact that determinant I/O has to be decoupled
|
||||||
|
from conventional write/read/flush behaviour of the TEXT back end. Chunks are used to read/write the data
|
||||||
|
to prevent memory overflow. Chunks have a given ~int64_t size~.
|
||||||
|
Size specifies the number of data items, e.g. determinants.
|
||||||
|
|
||||||
|
|
||||||
|
#+begin_src c :tangle hrw_determinant_text.h :exports none
|
||||||
|
trexio_exit_code trexio_text_has_determinant_list(trexio_t* const file);
|
||||||
|
trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, int64_t* const eof_read_size, int64_t* const list);
|
||||||
|
trexio_exit_code trexio_text_write_determinant_list(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, const int64_t* list);
|
||||||
|
trexio_exit_code trexio_text_has_determinant_coefficient(trexio_t* const file);
|
||||||
|
trexio_exit_code trexio_text_read_determinant_coefficient(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, int64_t* const eof_read_size, double* const coeff);
|
||||||
|
trexio_exit_code trexio_text_write_determinant_coefficient(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, const double* coeff);
|
||||||
|
trexio_exit_code trexio_text_read_determinant_coefficient_size(trexio_t* const file, int64_t* const size_max);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src c :tangle read_determinant_text.c
|
||||||
|
trexio_exit_code trexio_text_read_determinant_list(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
int64_t* const eof_read_size,
|
||||||
|
int64_t* const list)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
if (list == NULL) return TREXIO_INVALID_ARG_6;
|
||||||
|
|
||||||
|
const char determinant_list_file_name[256] = "/determinant_list.txt";
|
||||||
|
/* The full path to the destination TXT file with sparse data. This will include TREXIO directory name. */
|
||||||
|
char file_full_path[TREXIO_MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
/* Copy directory name in file_full_path */
|
||||||
|
strncpy (file_full_path, file->file_name, TREXIO_MAX_FILENAME_LENGTH);
|
||||||
|
/* Append name of the file with sparse data */
|
||||||
|
strncat (file_full_path, determinant_list_file_name,
|
||||||
|
TREXIO_MAX_FILENAME_LENGTH-strlen(determinant_list_file_name));
|
||||||
|
|
||||||
|
/* Open the file in "r" (read) mode to guarantee that no truncation happens upon consecutive reads */
|
||||||
|
FILE* f = fopen(file_full_path, "r");
|
||||||
|
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,
|
||||||
|
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
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Read the data from the file and check the return code of fprintf to verify that > 0 bytes have been read or reached EOF */
|
||||||
|
int rc;
|
||||||
|
/* Declare fixed buffer which will be used to read the determinant string <a1 a2 ... a/\ b1 b2 ... b\/> */
|
||||||
|
char buffer[1024];
|
||||||
|
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;
|
||||||
|
/* Counter for number of elements beind processed */
|
||||||
|
uint64_t count = 0UL;
|
||||||
|
for (uint64_t i=0UL; i < dims[0]; ++i) {
|
||||||
|
|
||||||
|
accum = 0UL;
|
||||||
|
memset(buffer, 0, buf_size);
|
||||||
|
|
||||||
|
if(fgets(buffer, buf_size-1, f) == NULL){
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
,*eof_read_size = count;
|
||||||
|
return TREXIO_END;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* The format string is not anymore static but rather dynamic (the number of ints depend on the mo_num)
|
||||||
|
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);
|
||||||
|
if(rc <= 0) {
|
||||||
|
fclose(f);
|
||||||
|
return TREXIO_FAILURE;
|
||||||
|
}
|
||||||
|
accum += shift_int64;
|
||||||
|
}
|
||||||
|
count += 1UL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the TXT file */
|
||||||
|
rc = fclose(f);
|
||||||
|
if(rc != 0) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code trexio_text_read_determinant_coefficient(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
int64_t* const eof_read_size,
|
||||||
|
double* const coeff)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
if (coeff == NULL) return TREXIO_INVALID_ARG_6;
|
||||||
|
|
||||||
|
char coeff_file_name[256];
|
||||||
|
memset(coeff_file_name, 0, sizeof(coeff_file_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(coeff_file_name, "/determinant_coefficient_state_%" PRId32 ".txt", trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(coeff_file_name, "/determinant_coefficient.txt", 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The full path to the destination TXT file with sparse data. This will include TREXIO directory name. */
|
||||||
|
char file_full_path[TREXIO_MAX_FILENAME_LENGTH];
|
||||||
|
/* Copy directory name in file_full_path */
|
||||||
|
strncpy (file_full_path, file->file_name, TREXIO_MAX_FILENAME_LENGTH);
|
||||||
|
/* Append name of the file with sparse data */
|
||||||
|
strncat (file_full_path, coeff_file_name,
|
||||||
|
TREXIO_MAX_FILENAME_LENGTH-strlen(coeff_file_name));
|
||||||
|
|
||||||
|
/* Open the file in "r" (read) mode to guarantee that no truncation happens upon consecutive reads */
|
||||||
|
FILE* f = fopen(file_full_path, "r");
|
||||||
|
if(f == NULL) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Specify the line length in order to offset properly.
|
||||||
|
Each double value 24 elements + one newline char.
|
||||||
|
,*/
|
||||||
|
uint64_t line_length = 25UL;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Read the data from the file and check the return code of fprintf to verify that > 0 bytes have been read or reached EOF */
|
||||||
|
int rc;
|
||||||
|
/* Declare fixed buffer which will be used to read the determinant string <a1 a2 ... a/\ b1 b2 ... b\/> */
|
||||||
|
char buffer[64];
|
||||||
|
uint32_t buf_size = sizeof(buffer);
|
||||||
|
/* Counter for number of elements beind processed */
|
||||||
|
uint64_t count = 0UL;
|
||||||
|
|
||||||
|
for (uint64_t i=0UL; i < dims[0]; ++i) {
|
||||||
|
|
||||||
|
memset(buffer, 0, buf_size);
|
||||||
|
if(fgets(buffer, buf_size-1, f) == NULL){
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
,*eof_read_size = count;
|
||||||
|
return TREXIO_END;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
rc = sscanf(buffer, "%lf", coeff + i);
|
||||||
|
if(rc <= 0) {
|
||||||
|
fclose(f);
|
||||||
|
return TREXIO_FAILURE;
|
||||||
|
}
|
||||||
|
count += 1UL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the TXT file */
|
||||||
|
rc = fclose(f);
|
||||||
|
if(rc != 0) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code
|
||||||
|
trexio_text_read_determinant_coefficient_size(trexio_t* const file, int64_t* const size_max)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (size_max == NULL) return TREXIO_INVALID_ARG_2;
|
||||||
|
|
||||||
|
char coeff_file_name[256];
|
||||||
|
memset(coeff_file_name, 0, sizeof(coeff_file_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(coeff_file_name, "/determinant_coefficient_state_%" PRId32 ".txt.size", trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(coeff_file_name, "/determinant_coefficient.txt.size", 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The full path to the destination TXT file with sparse data. This will include TREXIO directory name. */
|
||||||
|
char file_full_path[TREXIO_MAX_FILENAME_LENGTH];
|
||||||
|
/* Copy directory name in file_full_path */
|
||||||
|
strncpy (file_full_path, file->file_name, TREXIO_MAX_FILENAME_LENGTH);
|
||||||
|
/* Append name of the file with sparse data */
|
||||||
|
strncat (file_full_path, coeff_file_name,
|
||||||
|
TREXIO_MAX_FILENAME_LENGTH-strlen(coeff_file_name));
|
||||||
|
|
||||||
|
/* Open the file in "r" (read) mode to guarantee that no truncation happens upon consecutive reads */
|
||||||
|
FILE* f = fopen(file_full_path, "r");
|
||||||
|
if(f == NULL) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Read the data from the file and check the return code of fprintf to verify that > 0 bytes have been read or reached EOF */
|
||||||
|
int rc;
|
||||||
|
int64_t size_item, size_accum=0L;
|
||||||
|
|
||||||
|
/* Read the values from the file. BEWARE OF POSSIBLE MAX_INT64 OVERFLOW ! */
|
||||||
|
while(fscanf(f, "%" SCNd64, &size_item) != EOF) {
|
||||||
|
/* Check that summation will not overflow the int64_t value */
|
||||||
|
if (INT64_MAX - size_accum > size_item) {
|
||||||
|
size_accum += size_item;
|
||||||
|
} else {
|
||||||
|
fclose(f);
|
||||||
|
,*size_max = -1L;
|
||||||
|
return TREXIO_INT_SIZE_OVERFLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the TXT file */
|
||||||
|
rc = fclose(f);
|
||||||
|
if(rc != 0) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Overwrite the value at the input address and return TREXIO_SUCCESS */
|
||||||
|
,*size_max = size_accum;
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src c :tangle write_determinant_text.c
|
||||||
|
trexio_exit_code trexio_text_write_determinant_list(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
const int64_t* list)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (list == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
|
||||||
|
const char determinant_list_file_name[256] = "/determinant_list.txt";
|
||||||
|
/* The full path to the destination TXT file with sparse data. This will include TREXIO directory name. */
|
||||||
|
char file_full_path[TREXIO_MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
/* Copy directory name in file_full_path */
|
||||||
|
strncpy (file_full_path, file->file_name, TREXIO_MAX_FILENAME_LENGTH);
|
||||||
|
/* Append name of the file with sparse data */
|
||||||
|
strncat (file_full_path, determinant_list_file_name,
|
||||||
|
TREXIO_MAX_FILENAME_LENGTH-strlen(determinant_list_file_name));
|
||||||
|
|
||||||
|
/* Open the file in "a" (append) mode to guarantee that no truncation happens upon consecutive writes */
|
||||||
|
FILE* f = fopen(file_full_path, "a");
|
||||||
|
if(f == NULL) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Write the data in the file and check the return code of fprintf to verify that > 0 bytes have been written */
|
||||||
|
int rc;
|
||||||
|
for (uint64_t i=0UL; i < dims[0]; ++i) {
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
if(rc <= 0) {
|
||||||
|
fclose(f);
|
||||||
|
return TREXIO_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(f, "%s", "\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the TXT file */
|
||||||
|
rc = fclose(f);
|
||||||
|
if (rc != 0) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Exit upon success */
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code trexio_text_write_determinant_coefficient(trexio_t* const file,
|
||||||
|
const int64_t offset_file,
|
||||||
|
const uint32_t rank,
|
||||||
|
const uint64_t* dims,
|
||||||
|
const double* coeff)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
if (coeff == NULL) return TREXIO_INVALID_ARG_5;
|
||||||
|
|
||||||
|
char coeff_file_name[256];
|
||||||
|
memset(coeff_file_name, 0, sizeof(coeff_file_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(coeff_file_name, "/determinant_coefficient_state_%" PRId32 ".txt", trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(coeff_file_name, "/determinant_coefficient.txt", 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The full path to the destination TXT file with sparse data. This will include TREXIO directory name. */
|
||||||
|
char file_full_path[TREXIO_MAX_FILENAME_LENGTH];
|
||||||
|
/* Copy directory name in file_full_path */
|
||||||
|
strncpy (file_full_path, file->file_name, TREXIO_MAX_FILENAME_LENGTH);
|
||||||
|
/* Append name of the file with sparse data */
|
||||||
|
strncat (file_full_path, coeff_file_name,
|
||||||
|
TREXIO_MAX_FILENAME_LENGTH-strlen(coeff_file_name));
|
||||||
|
|
||||||
|
/* Open the file in "a" (append) mode to guarantee that no truncation happens upon consecutive writes */
|
||||||
|
FILE* f = fopen(file_full_path, "a");
|
||||||
|
if(f == NULL) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Write the data in the file and check the return code of fprintf to verify that > 0 bytes have been written */
|
||||||
|
int rc;
|
||||||
|
for (uint64_t i=0UL; i < dims[0]; ++i) {
|
||||||
|
|
||||||
|
rc = fprintf(f, "%24.16e\n", *(coeff + i));
|
||||||
|
if(rc <= 0) {
|
||||||
|
fclose(f);
|
||||||
|
return TREXIO_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the TXT file */
|
||||||
|
rc = fclose(f);
|
||||||
|
if (rc != 0) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Append .size to the file_full_path in order to write additional info about the written buffer of data */
|
||||||
|
strncat(file_full_path, ".size", 6);
|
||||||
|
|
||||||
|
/* Open the new file in "a" (append) mode to append info about the buffer that has been just written */
|
||||||
|
FILE *f_wSize = fopen(file_full_path, "a");
|
||||||
|
if (f_wSize == NULL) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Write the buffer_size */
|
||||||
|
rc = fprintf(f_wSize, "%" PRIu64 "\n", dims[0]);
|
||||||
|
if (rc <= 0) {
|
||||||
|
fclose(f_wSize);
|
||||||
|
return TREXIO_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the TXT file */
|
||||||
|
rc = fclose(f_wSize);
|
||||||
|
if (rc != 0) return TREXIO_FILE_ERROR;
|
||||||
|
|
||||||
|
/* Exit upon success */
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src c :tangle has_determinant_text.c
|
||||||
|
trexio_exit_code trexio_text_has_determinant_list(trexio_t* const file)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
|
const char determinant_list_file_name[256] = "/determinant_list.txt";
|
||||||
|
/* The full path to the destination TXT file with sparse data. This will include TREXIO directory name. */
|
||||||
|
char file_full_path[TREXIO_MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
/* Copy directory name in file_full_path */
|
||||||
|
strncpy (file_full_path, file->file_name, TREXIO_MAX_FILENAME_LENGTH);
|
||||||
|
/* Append name of the file with sparse data */
|
||||||
|
strncat (file_full_path, determinant_list_file_name,
|
||||||
|
TREXIO_MAX_FILENAME_LENGTH-strlen(determinant_list_file_name));
|
||||||
|
|
||||||
|
/* Check the return code of access function to determine whether the file with data exists or not */
|
||||||
|
if (access(file_full_path, F_OK) == 0){
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return TREXIO_HAS_NOT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trexio_exit_code trexio_text_has_determinant_coefficient(trexio_t* const file)
|
||||||
|
{
|
||||||
|
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||||
|
|
||||||
|
char coeff_file_name[256];
|
||||||
|
memset(coeff_file_name, 0, sizeof(coeff_file_name));
|
||||||
|
const int32_t trexio_state = file->state;
|
||||||
|
|
||||||
|
if (trexio_state != 0) {
|
||||||
|
sprintf(coeff_file_name, "/determinant_coefficient_state_%" PRId32 ".txt", trexio_state);
|
||||||
|
} else {
|
||||||
|
strncpy(coeff_file_name, "/determinant_coefficient.txt", 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The full path to the destination TXT file with sparse data. This will include TREXIO directory name. */
|
||||||
|
char file_full_path[TREXIO_MAX_FILENAME_LENGTH];
|
||||||
|
/* Copy directory name in file_full_path */
|
||||||
|
strncpy (file_full_path, file->file_name, TREXIO_MAX_FILENAME_LENGTH);
|
||||||
|
/* Append name of the file with sparse data */
|
||||||
|
strncat (file_full_path, coeff_file_name,
|
||||||
|
TREXIO_MAX_FILENAME_LENGTH-strlen(coeff_file_name));
|
||||||
|
|
||||||
|
/* Check the return code of access function to determine whether the file with data exists or not */
|
||||||
|
if (access(file_full_path, F_OK) == 0){
|
||||||
|
return TREXIO_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return TREXIO_HAS_NOT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
* Constant file suffixes (not used by the generator) :noexport:
|
* Constant file suffixes (not used by the generator) :noexport:
|
||||||
|
|
||||||
#+begin_src c :tangle suffix_text.h
|
#+begin_src c :tangle suffix_text.h
|
||||||
|
@ -7,6 +7,7 @@ set(Tests_text
|
|||||||
io_dset_float_text
|
io_dset_float_text
|
||||||
io_dset_str_text
|
io_dset_str_text
|
||||||
io_dset_sparse_text
|
io_dset_sparse_text
|
||||||
|
io_determinant_text
|
||||||
io_safe_dset_float_text
|
io_safe_dset_float_text
|
||||||
io_dset_int_text
|
io_dset_int_text
|
||||||
io_num_text
|
io_num_text
|
||||||
@ -23,6 +24,7 @@ if(ENABLE_HDF5)
|
|||||||
io_dset_float_hdf5
|
io_dset_float_hdf5
|
||||||
io_dset_str_hdf5
|
io_dset_str_hdf5
|
||||||
io_dset_sparse_hdf5
|
io_dset_sparse_hdf5
|
||||||
|
io_determinant_hdf5
|
||||||
io_safe_dset_float_hdf5
|
io_safe_dset_float_hdf5
|
||||||
io_dset_int_hdf5
|
io_dset_int_hdf5
|
||||||
io_num_hdf5
|
io_num_hdf5
|
||||||
|
340
tests/io_determinant_hdf5.c
Normal file
340
tests/io_determinant_hdf5.c
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
#include "trexio.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define TEST_BACKEND TREXIO_HDF5
|
||||||
|
#define TREXIO_FILE "test_determinant.h5"
|
||||||
|
#define RM_COMMAND "rm -f " TREXIO_FILE
|
||||||
|
#define SIZE 100
|
||||||
|
#define N_CHUNKS 5
|
||||||
|
#define STATE_TEST 2
|
||||||
|
#define MO_NUM 150
|
||||||
|
|
||||||
|
static int test_write_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
|
||||||
|
|
||||||
|
/* Try to write an array of sparse data into the TREXIO file */
|
||||||
|
|
||||||
|
trexio_t* file = NULL;
|
||||||
|
trexio_exit_code rc;
|
||||||
|
|
||||||
|
/*================= START OF TEST ==================*/
|
||||||
|
|
||||||
|
// open file in 'write' mode
|
||||||
|
file = trexio_open(file_name, 'w', backend, &rc);
|
||||||
|
assert (file != NULL);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// parameters to be written
|
||||||
|
int64_t* det_list;
|
||||||
|
double* det_coef;
|
||||||
|
|
||||||
|
int mo_num = MO_NUM;
|
||||||
|
|
||||||
|
det_list = (int64_t*) calloc(2*3*SIZE, sizeof(int64_t));
|
||||||
|
det_coef = (double*) calloc(SIZE, sizeof(double));
|
||||||
|
|
||||||
|
for(int i=0; i<SIZE; i++){
|
||||||
|
det_list[6*i] = 6*i;
|
||||||
|
det_list[6*i+1] = 6*i+1;
|
||||||
|
det_list[6*i+2] = 6*i+2;
|
||||||
|
det_list[6*i+3] = 6*i+3;
|
||||||
|
det_list[6*i+4] = 6*i+4;
|
||||||
|
det_list[6*i+5] = 6*i+5;
|
||||||
|
det_coef[i] = 3.14 + (double) i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write mo_num which will be used to determine the optimal size of int indices
|
||||||
|
if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
|
||||||
|
rc = trexio_write_mo_num(file, mo_num);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write dataset chunks of sparse data in the file (including FAKE statements)
|
||||||
|
uint64_t chunk_size = (uint64_t) SIZE/N_CHUNKS;
|
||||||
|
uint64_t offset_f = 0UL;
|
||||||
|
uint64_t offset_d = 0UL;
|
||||||
|
if (offset != 0L) offset_f += offset;
|
||||||
|
|
||||||
|
// write n_chunks times using write_sparse
|
||||||
|
for(int i=0; i<N_CHUNKS; ++i){
|
||||||
|
|
||||||
|
rc = trexio_write_determinant_list(file, offset_f, chunk_size, &det_list[6*offset_d]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// The block below will write the coefficients for STATE_TEST
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// set state back to the default 0 (ground state)
|
||||||
|
rc = trexio_set_state(file, 0);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
// =================================================
|
||||||
|
|
||||||
|
offset_d += chunk_size;
|
||||||
|
offset_f += chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// manually check the consistency of the determinant_num and coefficient_size after writing
|
||||||
|
int64_t coeff_size = 0L;
|
||||||
|
int64_t determinant_num = 0L;
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_num_64(file, &determinant_num);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient_size(file, &coeff_size);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(determinant_num == coeff_size);
|
||||||
|
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient_size(file, &coeff_size);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(determinant_num == coeff_size);
|
||||||
|
|
||||||
|
// close current session
|
||||||
|
rc = trexio_close(file);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// free the allocated memeory
|
||||||
|
free(det_list);
|
||||||
|
free(det_coef);
|
||||||
|
|
||||||
|
/*================= END OF TEST ==================*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_has_determinant(const char* file_name, const back_end_t backend) {
|
||||||
|
|
||||||
|
/* Try to check the existence of a dataset of sparse data in the TREXIO file */
|
||||||
|
|
||||||
|
trexio_t* file = NULL;
|
||||||
|
trexio_exit_code rc;
|
||||||
|
|
||||||
|
/*================= START OF TEST ==================*/
|
||||||
|
|
||||||
|
// open file
|
||||||
|
file = trexio_open(file_name, 'r', backend, &rc);
|
||||||
|
assert (file != NULL);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// now check that previously written determinant_list exists
|
||||||
|
rc = trexio_has_determinant_list(file);
|
||||||
|
assert(rc==TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// now check that previously written determinant_coefficient exists
|
||||||
|
rc = trexio_has_determinant_coefficient(file);
|
||||||
|
assert(rc==TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// also check for STATE_TEST
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_has_determinant_coefficient(file);
|
||||||
|
assert(rc==TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_set_state(file, 0);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// close current session
|
||||||
|
rc = trexio_close(file);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
/*================= END OF TEST ==================*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_read_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
|
||||||
|
|
||||||
|
/* Try to read one chunk of dataset of sparse data in the TREXIO file */
|
||||||
|
|
||||||
|
trexio_t* file = NULL;
|
||||||
|
trexio_exit_code rc;
|
||||||
|
|
||||||
|
/*================= START OF TEST ==================*/
|
||||||
|
|
||||||
|
// open file
|
||||||
|
file = trexio_open(file_name, 'r', backend, &rc);
|
||||||
|
assert (file != NULL);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// compute how many integer bit fields is needed per determinant (for a given spin)
|
||||||
|
int64_t mo_num;
|
||||||
|
rc = trexio_read_mo_num_64(file, &mo_num);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
assert (mo_num == MO_NUM);
|
||||||
|
|
||||||
|
int int_num = (mo_num - 1)/64 + 1;
|
||||||
|
assert (int_num == 3);
|
||||||
|
|
||||||
|
// define arrays to read into
|
||||||
|
int64_t* det_list_read;
|
||||||
|
double* det_coef_read;
|
||||||
|
double* det_coef_s2_read;
|
||||||
|
double check_diff;
|
||||||
|
uint64_t size_r = 40L;
|
||||||
|
|
||||||
|
det_list_read = (int64_t*) calloc(2*int_num*size_r,sizeof(int64_t));
|
||||||
|
det_coef_read = (double*) calloc(size_r,sizeof(double));
|
||||||
|
det_coef_s2_read = (double*) calloc(size_r,sizeof(double));
|
||||||
|
|
||||||
|
// specify the read parameters, here:
|
||||||
|
// 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
|
||||||
|
int64_t chunk_read = 10L;
|
||||||
|
int64_t offset_file_read = 40L;
|
||||||
|
int offset_data_read = 5;
|
||||||
|
int64_t read_size_check;
|
||||||
|
read_size_check = chunk_read;
|
||||||
|
|
||||||
|
if (offset != 0L) offset_file_read += offset;
|
||||||
|
|
||||||
|
// read one chunk using the aforementioned parameters
|
||||||
|
rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(chunk_read == read_size_check);
|
||||||
|
assert(det_list_read[0] == 0);
|
||||||
|
assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(chunk_read == read_size_check);
|
||||||
|
|
||||||
|
check_diff = det_coef_read[0] - 0.;
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
check_diff = det_coef_read[offset_data_read] - (3.14 + (double) (offset_file_read-offset));
|
||||||
|
//printf("%lf %lf\n", check_diff, det_coef_read[offset_data_read]);
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
// read one chuk of coefficients for a different state
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_s2_read[offset_data_read]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(chunk_read == read_size_check);
|
||||||
|
|
||||||
|
check_diff = det_coef_s2_read[0] - 0.;
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
rc = trexio_set_state(file, 0);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
|
||||||
|
offset_file_read = 97L;
|
||||||
|
offset_data_read = 1;
|
||||||
|
int64_t eof_read_size_check = SIZE - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
|
||||||
|
|
||||||
|
if (offset != 0L) offset_file_read += offset;
|
||||||
|
|
||||||
|
chunk_read = read_size_check;
|
||||||
|
// read one chunk that will reach EOF and return TREXIO_END code
|
||||||
|
rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
|
||||||
|
/*
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
assert(rc == TREXIO_END);
|
||||||
|
assert(chunk_read == eof_read_size_check);
|
||||||
|
assert(det_list_read[2*int_num*size_r-1] == 0);
|
||||||
|
assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
|
||||||
|
|
||||||
|
chunk_read = read_size_check;
|
||||||
|
rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
|
||||||
|
/*
|
||||||
|
printf("%s\n", trexio_string_of_error(rc));
|
||||||
|
for (int i=0; i<size_r; i++) {
|
||||||
|
printf("%lf\n", det_coef_read[i]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
assert(rc == TREXIO_END);
|
||||||
|
assert(chunk_read == eof_read_size_check);
|
||||||
|
|
||||||
|
check_diff= det_coef_read[size_r-1] - 0.;
|
||||||
|
//printf("%lf %lf\n", check_diff, det_coef_read[size_r-1]);
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
// check the value of determinant_num
|
||||||
|
int32_t det_num = 0;
|
||||||
|
int32_t size_check = SIZE;
|
||||||
|
if (offset != 0L) size_check += offset;
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_num(file, &det_num);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(det_num == size_check);
|
||||||
|
|
||||||
|
|
||||||
|
// check conversion of determinants into orbital lists
|
||||||
|
int64_t size_list = NORB_PER_INT * int_num;
|
||||||
|
int32_t* orb_list_up = (int32_t*) calloc(size_list, sizeof(int32_t));
|
||||||
|
int32_t* orb_list_dn = (int32_t*) calloc(size_list, sizeof(int32_t));
|
||||||
|
int32_t occ_num_up, occ_num_dn;
|
||||||
|
|
||||||
|
rc = trexio_to_orbital_list_up_dn (int_num, &det_list_read[2*int_num*5], orb_list_up, orb_list_dn, &occ_num_up, &occ_num_dn);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
assert (occ_num_up == 14);
|
||||||
|
assert (occ_num_dn == 17);
|
||||||
|
/* // DEBUG printing
|
||||||
|
printf("occ_num_up : %d ; occ_num_dn : %d \n", occ_num_up, occ_num_dn);
|
||||||
|
for (int i=0; i<occ_num_up; i++) {
|
||||||
|
printf("%d ", orb_list_up[i]);
|
||||||
|
}
|
||||||
|
printf("| ");
|
||||||
|
for (int i=0; i<occ_num_dn; i++) {
|
||||||
|
printf("%d ", orb_list_dn[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// close current session
|
||||||
|
rc = trexio_close(file);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// free the memory
|
||||||
|
free(det_list_read);
|
||||||
|
free(det_coef_read);
|
||||||
|
free(det_coef_s2_read);
|
||||||
|
free(orb_list_up);
|
||||||
|
free(orb_list_dn);
|
||||||
|
|
||||||
|
/*================= END OF TEST ==================*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
|
||||||
|
/*============== Test launcher ================*/
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
rc = system(RM_COMMAND);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// check the first write attempt (SIZE elements written in N_CHUNKS chunks)
|
||||||
|
test_write_determinant (TREXIO_FILE, TEST_BACKEND, 0);
|
||||||
|
test_has_determinant (TREXIO_FILE, TEST_BACKEND);
|
||||||
|
test_read_determinant (TREXIO_FILE, TEST_BACKEND, 0);
|
||||||
|
|
||||||
|
// check the second write attempt (SIZE elements written in N_CHUNKS chunks)
|
||||||
|
test_write_determinant (TREXIO_FILE, TEST_BACKEND, SIZE);
|
||||||
|
test_read_determinant (TREXIO_FILE, TEST_BACKEND, SIZE);
|
||||||
|
|
||||||
|
rc = system(RM_COMMAND);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
340
tests/io_determinant_text.c
Normal file
340
tests/io_determinant_text.c
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
#include "trexio.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define TEST_BACKEND TREXIO_TEXT
|
||||||
|
#define TREXIO_FILE "test_determinant.dir"
|
||||||
|
#define RM_COMMAND "rm -rf " TREXIO_FILE
|
||||||
|
#define SIZE 100
|
||||||
|
#define N_CHUNKS 5
|
||||||
|
#define STATE_TEST 2
|
||||||
|
#define MO_NUM 150
|
||||||
|
|
||||||
|
static int test_write_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
|
||||||
|
|
||||||
|
/* Try to write an array of sparse data into the TREXIO file */
|
||||||
|
|
||||||
|
trexio_t* file = NULL;
|
||||||
|
trexio_exit_code rc;
|
||||||
|
|
||||||
|
/*================= START OF TEST ==================*/
|
||||||
|
|
||||||
|
// open file in 'write' mode
|
||||||
|
file = trexio_open(file_name, 'w', backend, &rc);
|
||||||
|
assert (file != NULL);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// parameters to be written
|
||||||
|
int64_t* det_list;
|
||||||
|
double* det_coef;
|
||||||
|
|
||||||
|
int mo_num = MO_NUM;
|
||||||
|
|
||||||
|
det_list = (int64_t*) calloc(2*3*SIZE, sizeof(int64_t));
|
||||||
|
det_coef = (double*) calloc(SIZE, sizeof(double));
|
||||||
|
|
||||||
|
for(int i=0; i<SIZE; i++){
|
||||||
|
det_list[6*i] = 6*i;
|
||||||
|
det_list[6*i+1] = 6*i+1;
|
||||||
|
det_list[6*i+2] = 6*i+2;
|
||||||
|
det_list[6*i+3] = 6*i+3;
|
||||||
|
det_list[6*i+4] = 6*i+4;
|
||||||
|
det_list[6*i+5] = 6*i+5;
|
||||||
|
det_coef[i] = 3.14 + (double) i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write mo_num which will be used to determine the optimal size of int indices
|
||||||
|
if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
|
||||||
|
rc = trexio_write_mo_num(file, mo_num);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write dataset chunks of sparse data in the file (including FAKE statements)
|
||||||
|
uint64_t chunk_size = (uint64_t) SIZE/N_CHUNKS;
|
||||||
|
uint64_t offset_f = 0UL;
|
||||||
|
uint64_t offset_d = 0UL;
|
||||||
|
if (offset != 0L) offset_f += offset;
|
||||||
|
|
||||||
|
// write n_chunks times using write_sparse
|
||||||
|
for(int i=0; i<N_CHUNKS; ++i){
|
||||||
|
|
||||||
|
rc = trexio_write_determinant_list(file, offset_f, chunk_size, &det_list[6*offset_d]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// The block below will write the coefficients for STATE_TEST
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// set state back to the default 0 (ground state)
|
||||||
|
rc = trexio_set_state(file, 0);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
// =================================================
|
||||||
|
|
||||||
|
offset_d += chunk_size;
|
||||||
|
offset_f += chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// manually check the consistency of the determinant_num and coefficient_size after writing
|
||||||
|
int64_t coeff_size = 0L;
|
||||||
|
int64_t determinant_num = 0L;
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_num_64(file, &determinant_num);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient_size(file, &coeff_size);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(determinant_num == coeff_size);
|
||||||
|
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient_size(file, &coeff_size);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(determinant_num == coeff_size);
|
||||||
|
|
||||||
|
// close current session
|
||||||
|
rc = trexio_close(file);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// free the allocated memeory
|
||||||
|
free(det_list);
|
||||||
|
free(det_coef);
|
||||||
|
|
||||||
|
/*================= END OF TEST ==================*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_has_determinant(const char* file_name, const back_end_t backend) {
|
||||||
|
|
||||||
|
/* Try to check the existence of a dataset of sparse data in the TREXIO file */
|
||||||
|
|
||||||
|
trexio_t* file = NULL;
|
||||||
|
trexio_exit_code rc;
|
||||||
|
|
||||||
|
/*================= START OF TEST ==================*/
|
||||||
|
|
||||||
|
// open file
|
||||||
|
file = trexio_open(file_name, 'r', backend, &rc);
|
||||||
|
assert (file != NULL);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// now check that previously written determinant_list exists
|
||||||
|
rc = trexio_has_determinant_list(file);
|
||||||
|
assert(rc==TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// now check that previously written determinant_coefficient exists
|
||||||
|
rc = trexio_has_determinant_coefficient(file);
|
||||||
|
assert(rc==TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// also check for STATE_TEST
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_has_determinant_coefficient(file);
|
||||||
|
assert(rc==TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_set_state(file, 0);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// close current session
|
||||||
|
rc = trexio_close(file);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
/*================= END OF TEST ==================*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_read_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
|
||||||
|
|
||||||
|
/* Try to read one chunk of dataset of sparse data in the TREXIO file */
|
||||||
|
|
||||||
|
trexio_t* file = NULL;
|
||||||
|
trexio_exit_code rc;
|
||||||
|
|
||||||
|
/*================= START OF TEST ==================*/
|
||||||
|
|
||||||
|
// open file
|
||||||
|
file = trexio_open(file_name, 'r', backend, &rc);
|
||||||
|
assert (file != NULL);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// compute how many integer bit fields is needed per determinant (for a given spin)
|
||||||
|
int64_t mo_num;
|
||||||
|
rc = trexio_read_mo_num_64(file, &mo_num);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
assert (mo_num == MO_NUM);
|
||||||
|
|
||||||
|
int int_num = (mo_num - 1)/64 + 1;
|
||||||
|
assert (int_num == 3);
|
||||||
|
|
||||||
|
// define arrays to read into
|
||||||
|
int64_t* det_list_read;
|
||||||
|
double* det_coef_read;
|
||||||
|
double* det_coef_s2_read;
|
||||||
|
double check_diff;
|
||||||
|
uint64_t size_r = 40L;
|
||||||
|
|
||||||
|
det_list_read = (int64_t*) calloc(2*int_num*size_r,sizeof(int64_t));
|
||||||
|
det_coef_read = (double*) calloc(size_r,sizeof(double));
|
||||||
|
det_coef_s2_read = (double*) calloc(size_r,sizeof(double));
|
||||||
|
|
||||||
|
// specify the read parameters, here:
|
||||||
|
// 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
|
||||||
|
int64_t chunk_read = 10L;
|
||||||
|
int64_t offset_file_read = 40L;
|
||||||
|
int offset_data_read = 5;
|
||||||
|
int64_t read_size_check;
|
||||||
|
read_size_check = chunk_read;
|
||||||
|
|
||||||
|
if (offset != 0L) offset_file_read += offset;
|
||||||
|
|
||||||
|
// read one chunk using the aforementioned parameters
|
||||||
|
rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(chunk_read == read_size_check);
|
||||||
|
assert(det_list_read[0] == 0);
|
||||||
|
assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(chunk_read == read_size_check);
|
||||||
|
|
||||||
|
check_diff = det_coef_read[0] - 0.;
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
check_diff = det_coef_read[offset_data_read] - (3.14 + (double) (offset_file_read-offset));
|
||||||
|
//printf("%lf %lf\n", check_diff, det_coef_read[offset_data_read]);
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
// read one chuk of coefficients for a different state
|
||||||
|
rc = trexio_set_state(file, STATE_TEST);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_s2_read[offset_data_read]);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(chunk_read == read_size_check);
|
||||||
|
|
||||||
|
check_diff = det_coef_s2_read[0] - 0.;
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
rc = trexio_set_state(file, 0);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
|
||||||
|
offset_file_read = 97L;
|
||||||
|
offset_data_read = 1;
|
||||||
|
int64_t eof_read_size_check = SIZE - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
|
||||||
|
|
||||||
|
if (offset != 0L) offset_file_read += offset;
|
||||||
|
|
||||||
|
chunk_read = read_size_check;
|
||||||
|
// read one chunk that will reach EOF and return TREXIO_END code
|
||||||
|
rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
|
||||||
|
/*
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
assert(rc == TREXIO_END);
|
||||||
|
assert(chunk_read == eof_read_size_check);
|
||||||
|
assert(det_list_read[2*int_num*size_r-1] == 0);
|
||||||
|
assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
|
||||||
|
|
||||||
|
chunk_read = read_size_check;
|
||||||
|
rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
|
||||||
|
/*
|
||||||
|
printf("%s\n", trexio_string_of_error(rc));
|
||||||
|
for (int i=0; i<size_r; i++) {
|
||||||
|
printf("%lf\n", det_coef_read[i]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
assert(rc == TREXIO_END);
|
||||||
|
assert(chunk_read == eof_read_size_check);
|
||||||
|
|
||||||
|
check_diff= det_coef_read[size_r-1] - 0.;
|
||||||
|
//printf("%lf %lf\n", check_diff, det_coef_read[size_r-1]);
|
||||||
|
assert(check_diff*check_diff < 1e-14);
|
||||||
|
|
||||||
|
// check the value of determinant_num
|
||||||
|
int32_t det_num = 0;
|
||||||
|
int32_t size_check = SIZE;
|
||||||
|
if (offset != 0L) size_check += offset;
|
||||||
|
|
||||||
|
rc = trexio_read_determinant_num(file, &det_num);
|
||||||
|
assert(rc == TREXIO_SUCCESS);
|
||||||
|
assert(det_num == size_check);
|
||||||
|
|
||||||
|
|
||||||
|
// check conversion of determinants into orbital lists
|
||||||
|
int64_t size_list = NORB_PER_INT * int_num;
|
||||||
|
int32_t* orb_list_up = (int32_t*) calloc(size_list, sizeof(int32_t));
|
||||||
|
int32_t* orb_list_dn = (int32_t*) calloc(size_list, sizeof(int32_t));
|
||||||
|
int32_t occ_num_up, occ_num_dn;
|
||||||
|
|
||||||
|
rc = trexio_to_orbital_list_up_dn (int_num, &det_list_read[2*int_num*5], orb_list_up, orb_list_dn, &occ_num_up, &occ_num_dn);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
assert (occ_num_up == 14);
|
||||||
|
assert (occ_num_dn == 17);
|
||||||
|
/* // DEBUG printing
|
||||||
|
printf("occ_num_up : %d ; occ_num_dn : %d \n", occ_num_up, occ_num_dn);
|
||||||
|
for (int i=0; i<occ_num_up; i++) {
|
||||||
|
printf("%d ", orb_list_up[i]);
|
||||||
|
}
|
||||||
|
printf("| ");
|
||||||
|
for (int i=0; i<occ_num_dn; i++) {
|
||||||
|
printf("%d ", orb_list_dn[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// close current session
|
||||||
|
rc = trexio_close(file);
|
||||||
|
assert (rc == TREXIO_SUCCESS);
|
||||||
|
|
||||||
|
// free the memory
|
||||||
|
free(det_list_read);
|
||||||
|
free(det_coef_read);
|
||||||
|
free(det_coef_s2_read);
|
||||||
|
free(orb_list_up);
|
||||||
|
free(orb_list_dn);
|
||||||
|
|
||||||
|
/*================= END OF TEST ==================*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
|
||||||
|
/*============== Test launcher ================*/
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
rc = system(RM_COMMAND);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// check the first write attempt (SIZE elements written in N_CHUNKS chunks)
|
||||||
|
test_write_determinant (TREXIO_FILE, TEST_BACKEND, 0);
|
||||||
|
test_has_determinant (TREXIO_FILE, TEST_BACKEND);
|
||||||
|
test_read_determinant (TREXIO_FILE, TEST_BACKEND, 0);
|
||||||
|
|
||||||
|
// check the second write attempt (SIZE elements written in N_CHUNKS chunks)
|
||||||
|
test_write_determinant (TREXIO_FILE, TEST_BACKEND, SIZE);
|
||||||
|
test_read_determinant (TREXIO_FILE, TEST_BACKEND, SIZE);
|
||||||
|
|
||||||
|
rc = system(RM_COMMAND);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
173
tests/test_f.f90
173
tests/test_f.f90
@ -55,7 +55,7 @@ subroutine test_write(file_name, back_end)
|
|||||||
|
|
||||||
integer(trexio_exit_code) :: rc = 1
|
integer(trexio_exit_code) :: rc = 1
|
||||||
|
|
||||||
integer :: num, basis_shell_num
|
integer :: nucleus_num, mo_num, ao_num, basis_shell_num
|
||||||
|
|
||||||
integer :: basis_nucleus_index(24)
|
integer :: basis_nucleus_index(24)
|
||||||
double precision :: charge(12)
|
double precision :: charge(12)
|
||||||
@ -65,23 +65,37 @@ subroutine test_write(file_name, back_end)
|
|||||||
character(len=:), allocatable :: label(:)
|
character(len=:), allocatable :: label(:)
|
||||||
|
|
||||||
! sparse data
|
! sparse data
|
||||||
integer(4) :: index_sparse_mo_2e_int_eri(4,100)
|
integer(4) :: index_sparse_ao_2e_int_eri(4,100)
|
||||||
double precision :: value_sparse_mo_2e_int_eri(100)
|
double precision :: value_sparse_ao_2e_int_eri(100)
|
||||||
|
|
||||||
integer :: i, n_buffers = 5
|
! determinants
|
||||||
integer(8) :: buf_size, offset
|
integer*8 :: det_list(6, 50)
|
||||||
buf_size = 100/n_buffers
|
integer*8 :: det_num
|
||||||
|
|
||||||
|
integer :: i, j, n_buffers = 5
|
||||||
|
integer(8) :: buf_size_sparse, buf_size_det, offset
|
||||||
|
|
||||||
|
buf_size_sparse = 100/n_buffers
|
||||||
|
buf_size_det = 50/n_buffers
|
||||||
|
|
||||||
|
! fill sparse indices and values
|
||||||
do i = 1, 100
|
do i = 1, 100
|
||||||
index_sparse_mo_2e_int_eri(1,i) = 4*i - 3
|
index_sparse_ao_2e_int_eri(1,i) = 4*i - 3
|
||||||
index_sparse_mo_2e_int_eri(2,i) = 4*i+1 - 3
|
index_sparse_ao_2e_int_eri(2,i) = 4*i+1 - 3
|
||||||
index_sparse_mo_2e_int_eri(3,i) = 4*i+2 - 3
|
index_sparse_ao_2e_int_eri(3,i) = 4*i+2 - 3
|
||||||
index_sparse_mo_2e_int_eri(4,i) = 4*i+3 - 3
|
index_sparse_ao_2e_int_eri(4,i) = 4*i+3 - 3
|
||||||
value_sparse_mo_2e_int_eri(i) = 3.14 + float(i)
|
value_sparse_ao_2e_int_eri(i) = 3.14 + float(i)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! fill determinant list
|
||||||
|
do i = 1, 50
|
||||||
|
do j = 1, 6
|
||||||
|
det_list(j,i) = 6*i+(j-1) - 5
|
||||||
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
! parameters to be written
|
! parameters to be written
|
||||||
num = 12
|
nucleus_num = 12
|
||||||
charge = (/ 6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1. /)
|
charge = (/ 6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1. /)
|
||||||
coord = reshape( (/ 0.00000000d0, 1.39250319d0 , 0.00000000d0 , &
|
coord = reshape( (/ 0.00000000d0, 1.39250319d0 , 0.00000000d0 , &
|
||||||
-1.20594314d0, 0.69625160d0 , 0.00000000d0 , &
|
-1.20594314d0, 0.69625160d0 , 0.00000000d0 , &
|
||||||
@ -97,6 +111,10 @@ subroutine test_write(file_name, back_end)
|
|||||||
0.00000000d0, 2.47304151d0 , 0.00000000d0 /), &
|
0.00000000d0, 2.47304151d0 , 0.00000000d0 /), &
|
||||||
shape(coord) )
|
shape(coord) )
|
||||||
|
|
||||||
|
! the first dimension of det_list (6) corresponds to mo_num=150; adapt the former if the latter is changed
|
||||||
|
mo_num = 150
|
||||||
|
ao_num = 1000
|
||||||
|
|
||||||
basis_shell_num = 24
|
basis_shell_num = 24
|
||||||
basis_nucleus_index = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 /)
|
basis_nucleus_index = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 /)
|
||||||
|
|
||||||
@ -118,10 +136,13 @@ subroutine test_write(file_name, back_end)
|
|||||||
rc = trexio_has_nucleus_charge(trex_file)
|
rc = trexio_has_nucleus_charge(trex_file)
|
||||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2')
|
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2')
|
||||||
|
|
||||||
rc = trexio_has_mo_2e_int_eri(trex_file)
|
rc = trexio_has_ao_2e_int_eri(trex_file)
|
||||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 3')
|
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 3')
|
||||||
|
|
||||||
rc = trexio_write_nucleus_num(trex_file, num)
|
rc = trexio_has_determinant_list(trex_file)
|
||||||
|
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 4')
|
||||||
|
|
||||||
|
rc = trexio_write_nucleus_num(trex_file, nucleus_num)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE NUM')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE NUM')
|
||||||
|
|
||||||
rc = trexio_write_nucleus_charge(trex_file, charge)
|
rc = trexio_write_nucleus_charge(trex_file, charge)
|
||||||
@ -144,19 +165,33 @@ subroutine test_write(file_name, back_end)
|
|||||||
rc = trexio_write_basis_nucleus_index(trex_file, basis_nucleus_index)
|
rc = trexio_write_basis_nucleus_index(trex_file, basis_nucleus_index)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE INDEX')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE INDEX')
|
||||||
|
|
||||||
! write mo_num which will be used to determine the optimal size of int indices
|
! write ao_num which will be used to determine the optimal size of int indices
|
||||||
|
if (trexio_has_ao_num(trex_file) == TREXIO_HAS_NOT) then
|
||||||
|
rc = trexio_write_ao_num(trex_file, ao_num)
|
||||||
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE AO NUM')
|
||||||
|
endif
|
||||||
|
! write mo_num which will be used to determine the optimal size of the determinants bit fields
|
||||||
if (trexio_has_mo_num(trex_file) == TREXIO_HAS_NOT) then
|
if (trexio_has_mo_num(trex_file) == TREXIO_HAS_NOT) then
|
||||||
rc = trexio_write_mo_num(trex_file, 1000)
|
rc = trexio_write_mo_num(trex_file, mo_num)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE MO NUM')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE MO NUM')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
do i = 1,n_buffers
|
do i = 1,n_buffers
|
||||||
rc = trexio_write_mo_2e_int_eri(trex_file, offset, buf_size, &
|
rc = trexio_write_ao_2e_int_eri(trex_file, offset, buf_size_sparse, &
|
||||||
index_sparse_mo_2e_int_eri(1,offset+1), &
|
index_sparse_ao_2e_int_eri(1,offset+1), &
|
||||||
value_sparse_mo_2e_int_eri(offset+1))
|
value_sparse_ao_2e_int_eri(offset+1))
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE SPARSE')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE SPARSE')
|
||||||
offset = offset + buf_size
|
offset = offset + buf_size_sparse
|
||||||
|
enddo
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
do i = 1,n_buffers
|
||||||
|
rc = trexio_write_determinant_list(trex_file, offset, buf_size_det, &
|
||||||
|
det_list(1,offset+1))
|
||||||
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE DET LIST')
|
||||||
|
offset = offset + buf_size_det
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
rc = trexio_has_nucleus_num(trex_file)
|
rc = trexio_has_nucleus_num(trex_file)
|
||||||
@ -165,9 +200,12 @@ subroutine test_write(file_name, back_end)
|
|||||||
rc = trexio_has_nucleus_coord(trex_file)
|
rc = trexio_has_nucleus_coord(trex_file)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 2')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 2')
|
||||||
|
|
||||||
rc = trexio_has_mo_2e_int_eri(trex_file)
|
rc = trexio_has_ao_2e_int_eri(trex_file)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 3')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 3')
|
||||||
|
|
||||||
|
rc = trexio_has_determinant_list(trex_file)
|
||||||
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 4')
|
||||||
|
|
||||||
rc = trexio_close(trex_file)
|
rc = trexio_close(trex_file)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS CLOSE')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS CLOSE')
|
||||||
|
|
||||||
@ -203,8 +241,8 @@ subroutine test_read(file_name, back_end)
|
|||||||
character(len=32) :: sym_str
|
character(len=32) :: sym_str
|
||||||
|
|
||||||
! sparse data
|
! sparse data
|
||||||
integer(4) :: index_sparse_mo_2e_int_eri(4,20)
|
integer(4) :: index_sparse_ao_2e_int_eri(4,20)
|
||||||
double precision :: value_sparse_mo_2e_int_eri(20)
|
double precision :: value_sparse_ao_2e_int_eri(20)
|
||||||
integer(8) :: read_buf_size = 10
|
integer(8) :: read_buf_size = 10
|
||||||
integer(8) :: read_buf_size_save = 10
|
integer(8) :: read_buf_size_save = 10
|
||||||
integer(8) :: offset_read = 40
|
integer(8) :: offset_read = 40
|
||||||
@ -213,13 +251,29 @@ subroutine test_read(file_name, back_end)
|
|||||||
integer(8) :: offset_data_eof = 1
|
integer(8) :: offset_data_eof = 1
|
||||||
integer(8) :: size_toread = 0
|
integer(8) :: size_toread = 0
|
||||||
|
|
||||||
|
! determinant data
|
||||||
|
integer*8 :: det_list(6,50)
|
||||||
|
integer*8 :: read_buf_det_size = 20
|
||||||
|
integer*8 :: offset_det_read = 10
|
||||||
|
integer*8 :: offset_det_data_read = 5
|
||||||
|
integer*8 :: determinant_num
|
||||||
|
|
||||||
|
! orbital lists
|
||||||
|
integer*4 :: orb_list_up(150)
|
||||||
|
integer*4 :: orb_list_dn(150)
|
||||||
|
integer*4 :: occ_num_up, occ_num_dn
|
||||||
|
|
||||||
character*(128) :: str
|
character*(128) :: str
|
||||||
|
|
||||||
num = 12
|
num = 12
|
||||||
basis_shell_num = 24
|
basis_shell_num = 24
|
||||||
|
|
||||||
index_sparse_mo_2e_int_eri = 0
|
index_sparse_ao_2e_int_eri = 0
|
||||||
value_sparse_mo_2e_int_eri = 0.0d0
|
value_sparse_ao_2e_int_eri = 0.0d0
|
||||||
|
|
||||||
|
det_list = 0_8
|
||||||
|
orb_list_up = 0
|
||||||
|
orb_list_dn = 0
|
||||||
|
|
||||||
! ================= START OF TEST ===================== !
|
! ================= START OF TEST ===================== !
|
||||||
|
|
||||||
@ -289,15 +343,15 @@ subroutine test_read(file_name, back_end)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
rc = trexio_read_mo_2e_int_eri(trex_file, offset_read, read_buf_size, &
|
rc = trexio_read_ao_2e_int_eri(trex_file, offset_read, read_buf_size, &
|
||||||
index_sparse_mo_2e_int_eri(1, offset_data_read + 1), &
|
index_sparse_ao_2e_int_eri(1, offset_data_read + 1), &
|
||||||
value_sparse_mo_2e_int_eri(offset_data_read + 1))
|
value_sparse_ao_2e_int_eri(offset_data_read + 1))
|
||||||
!do i = 1,20
|
!do i = 1,20
|
||||||
! write(*,*) index_sparse_mo_2e_int_eri(1,i)
|
! write(*,*) index_sparse_ao_2e_int_eri(1,i)
|
||||||
!enddo
|
!enddo
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||||
if (index_sparse_mo_2e_int_eri(1, 1) == 0 .and. &
|
if (index_sparse_ao_2e_int_eri(1, 1) == 0 .and. &
|
||||||
index_sparse_mo_2e_int_eri(1, offset_data_read + 1) == offset_read*4 + 1) then
|
index_sparse_ao_2e_int_eri(1, offset_data_read + 1) == offset_read*4 + 1) then
|
||||||
write(*,*) 'SUCCESS READ SPARSE DATA'
|
write(*,*) 'SUCCESS READ SPARSE DATA'
|
||||||
else
|
else
|
||||||
print *, 'FAILURE SPARSE DATA CHECK'
|
print *, 'FAILURE SPARSE DATA CHECK'
|
||||||
@ -307,17 +361,17 @@ subroutine test_read(file_name, back_end)
|
|||||||
|
|
||||||
! attempt to read reaching EOF: should return TREXIO_END and
|
! attempt to read reaching EOF: should return TREXIO_END and
|
||||||
! NOT increment the existing values in the buffer (only upd with what has been read)
|
! NOT increment the existing values in the buffer (only upd with what has been read)
|
||||||
rc = trexio_read_mo_2e_int_eri(trex_file, offset_eof, read_buf_size, &
|
rc = trexio_read_ao_2e_int_eri(trex_file, offset_eof, read_buf_size, &
|
||||||
index_sparse_mo_2e_int_eri(1, offset_data_eof + 1), &
|
index_sparse_ao_2e_int_eri(1, offset_data_eof + 1), &
|
||||||
value_sparse_mo_2e_int_eri(offset_data_eof + 1))
|
value_sparse_ao_2e_int_eri(offset_data_eof + 1))
|
||||||
!do i = 1,20
|
!do i = 1,20
|
||||||
! write(*,*) index_sparse_mo_2e_int_eri(1,i)
|
! write(*,*) index_sparse_ao_2e_int_eri(1,i)
|
||||||
!enddo
|
!enddo
|
||||||
call trexio_assert(rc, TREXIO_END)
|
call trexio_assert(rc, TREXIO_END)
|
||||||
if (read_buf_size == 3 .and. &
|
if (read_buf_size == 3 .and. &
|
||||||
index_sparse_mo_2e_int_eri(1, 1) == 0 .and. &
|
index_sparse_ao_2e_int_eri(1, 1) == 0 .and. &
|
||||||
index_sparse_mo_2e_int_eri(1, offset_data_read + 1) == offset_read*4 + 1 .and. &
|
index_sparse_ao_2e_int_eri(1, offset_data_read + 1) == offset_read*4 + 1 .and. &
|
||||||
index_sparse_mo_2e_int_eri(1, offset_data_eof + 1) == offset_eof*4 + 1) then
|
index_sparse_ao_2e_int_eri(1, offset_data_eof + 1) == offset_eof*4 + 1) then
|
||||||
write(*,*) 'SUCCESS READ SPARSE DATA EOF'
|
write(*,*) 'SUCCESS READ SPARSE DATA EOF'
|
||||||
read_buf_size = read_buf_size_save
|
read_buf_size = read_buf_size_save
|
||||||
else
|
else
|
||||||
@ -325,7 +379,8 @@ subroutine test_read(file_name, back_end)
|
|||||||
call exit(-1)
|
call exit(-1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
rc = trexio_read_mo_2e_int_eri_size(trex_file, size_toread)
|
! read the size (number of integrals) of the sparse dataset
|
||||||
|
rc = trexio_read_ao_2e_int_eri_size(trex_file, size_toread)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||||
if (size_toread == 100) then
|
if (size_toread == 100) then
|
||||||
write(*,*) 'SUCCESS READ SPARSE SIZE'
|
write(*,*) 'SUCCESS READ SPARSE SIZE'
|
||||||
@ -334,7 +389,45 @@ subroutine test_read(file_name, back_end)
|
|||||||
call exit(-1)
|
call exit(-1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
! 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
|
||||||
|
|
||||||
|
! read the total number of stored determinants
|
||||||
|
rc = trexio_read_determinant_num_64(trex_file, determinant_num)
|
||||||
|
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||||
|
if (determinant_num == 50_8) then
|
||||||
|
write(*,*) 'SUCCESS READ DET NUM'
|
||||||
|
else
|
||||||
|
print *, 'FAILURE DET NUM CHECK'
|
||||||
|
call exit(-1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
! convert one given determinant into lists of orbitals
|
||||||
|
rc = trexio_to_orbital_list_up_dn(3, det_list(:, offset_det_data_read+1), orb_list_up, orb_list_dn, occ_num_up, occ_num_dn)
|
||||||
|
!write(*,*) occ_num_up, occ_num_dn
|
||||||
|
!write(*,*) orb_list_up(1:occ_num_up)
|
||||||
|
!write(*,*) det_list(:, offset_det_data_read+1)
|
||||||
|
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||||
|
if (occ_num_up == 16 .and. occ_num_dn == 5) then
|
||||||
|
write(*,*) 'SUCCESS CONVERT DET LIST'
|
||||||
|
else
|
||||||
|
print *, 'FAILURE DET CONVERT CHECK'
|
||||||
|
call exit(-1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
! close the file
|
||||||
rc = trexio_close(trex_file)
|
rc = trexio_close(trex_file)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||||
|
|
||||||
@ -365,7 +458,7 @@ subroutine test_read_void(file_name, back_end)
|
|||||||
call trexio_assert(rc, TREXIO_OPEN_ERROR)
|
call trexio_assert(rc, TREXIO_OPEN_ERROR)
|
||||||
|
|
||||||
call trexio_string_of_error(rc, str)
|
call trexio_string_of_error(rc, str)
|
||||||
print *, trim(str)
|
print *, 'Test error message: ', trim(str)
|
||||||
|
|
||||||
! ================= END OF TEST ===================== !
|
! ================= END OF TEST ===================== !
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ def get_dtype_dict (dtype: str, target: str, rank = None, int_len_printf = None)
|
|||||||
group_dset_format_printf_16 = '"'
|
group_dset_format_printf_16 = '"'
|
||||||
group_dset_format_printf_32 = '"'
|
group_dset_format_printf_32 = '"'
|
||||||
group_dset_format_scanf = ''
|
group_dset_format_scanf = ''
|
||||||
for i in range(rank):
|
for _ in range(rank):
|
||||||
group_dset_format_printf_8 += item_printf_8
|
group_dset_format_printf_8 += item_printf_8
|
||||||
group_dset_format_printf_16 += item_printf_16
|
group_dset_format_printf_16 += item_printf_16
|
||||||
group_dset_format_printf_32 += item_printf_32
|
group_dset_format_printf_32 += item_printf_32
|
||||||
@ -644,11 +644,16 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
|
|||||||
dset_string_dict = {}
|
dset_string_dict = {}
|
||||||
dset_sparse_dict = {}
|
dset_sparse_dict = {}
|
||||||
for k,v in datasets.items():
|
for k,v in datasets.items():
|
||||||
|
|
||||||
# create a temp dictionary
|
# create a temp dictionary
|
||||||
tmp_dict = {}
|
tmp_dict = {}
|
||||||
rank = len(v[1])
|
rank = len(v[1])
|
||||||
datatype = v[0]
|
datatype = v[0]
|
||||||
|
|
||||||
|
# skip the data which has 'special' datatype (e.g. determinants for which the code is not templated)
|
||||||
|
if 'special' in datatype:
|
||||||
|
continue
|
||||||
|
|
||||||
# define whether the dset is sparse
|
# define whether the dset is sparse
|
||||||
is_sparse = False
|
is_sparse = False
|
||||||
int_len_printf = {}
|
int_len_printf = {}
|
||||||
|
69
trex.org
69
trex.org
@ -635,7 +635,74 @@ prim_factor =
|
|||||||
#+end_src
|
#+end_src
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
* TODO Slater determinants
|
* Slater determinants (determinant group)
|
||||||
|
|
||||||
|
The configuration interaction (CI) wave function $\Psi$
|
||||||
|
can be expanded in the basis of Slater determinants $D_I$ as follows
|
||||||
|
|
||||||
|
\[
|
||||||
|
| \Psi> = \sum_I C_I | D_I> |
|
||||||
|
\]
|
||||||
|
|
||||||
|
For relatively small expansions, a given determinant can be represented as a list of ~mo.num~ occupation numbers.
|
||||||
|
However, this requires a lot of extra memory and would be technically impossible for larger expansions
|
||||||
|
(~millions of determinants). This is why the determinants are stored as bit fields in the TREXIO file
|
||||||
|
(see ~int bitfield~ type in the table below). By default, the chemist notation is used, namely
|
||||||
|
|
||||||
|
\[
|
||||||
|
| D_I > = | \alpha_1 \alpha_2 \ldots \alpha_{n\uparrow} \beta_1 \beta_2 \ldots \beta_{n\downarrow} > |
|
||||||
|
\]
|
||||||
|
|
||||||
|
where $\alpha$ and $\beta$ denote $\uparrow$-spin and $\downarrow$-spin electrons, respectively,
|
||||||
|
$n\uparrow$ and $n\downarrow$ correspond to ~electron.up_num~ and ~electron.dn_num~, respectively.
|
||||||
|
Internally, bit fields for $\alpha$ and $\beta$ electrons are stored separately,
|
||||||
|
which is why the ~determinant.list~ attribute has a second dimension.
|
||||||
|
|
||||||
|
#+NAME: determinant
|
||||||
|
| Variable | Type | Dimensions | Description |
|
||||||
|
|---------------+-----------------+-------------------------------+--------------------------------------------------------|
|
||||||
|
| ~num~ | ~dim~ | | Number of determinants |
|
||||||
|
| ~list~ | ~int special~ | ~(determinant.num)~ | List of determinants as integer bit fields |
|
||||||
|
| ~coefficient~ | ~float special~ | ~(state.num,determinant.num)~ | Coefficients of the determinants from the CI expansion |
|
||||||
|
|
||||||
|
#+CALL: json(data=determinant, title="determinant")
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
:RESULTS:
|
||||||
|
#+begin_src python :tangle trex.json
|
||||||
|
"determinant": {
|
||||||
|
"num" : [ "dim" , [] ]
|
||||||
|
, "list" : [ "int special" , [ "determinant.num" ] ]
|
||||||
|
, "coefficient" : [ "float special", [ "determinant.num", "state.num" ] ]
|
||||||
|
} ,
|
||||||
|
#+end_src
|
||||||
|
:END:
|
||||||
|
|
||||||
|
* Excited states (state group)
|
||||||
|
|
||||||
|
By default, the ~determinant~ group corresponds to the ground state.
|
||||||
|
However, it should be also possible to store the coefficients that
|
||||||
|
correspond to excited state wave functions for the same set of
|
||||||
|
determinants. This is the goal of the present group
|
||||||
|
|
||||||
|
#+NAME: state
|
||||||
|
| Variable | Type | Dimensions | Description |
|
||||||
|
|----------+-------+---------------+------------------------------------------------|
|
||||||
|
| ~num~ | ~dim~ | | Number of states (including the ground state) |
|
||||||
|
| ~label~ | ~str~ | ~(state.num)~ | Label of a given state (e.g. 'S' for singlets) |
|
||||||
|
|
||||||
|
#+CALL: json(data=state, title="state")
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
:RESULTS:
|
||||||
|
#+begin_src python :tangle trex.json
|
||||||
|
"state": {
|
||||||
|
"num" : [ "dim", [] ]
|
||||||
|
, "label" : [ "str", [ "state.num" ] ]
|
||||||
|
} ,
|
||||||
|
#+end_src
|
||||||
|
:END:
|
||||||
|
|
||||||
* Reduced density matrices (rdm group)
|
* Reduced density matrices (rdm group)
|
||||||
|
|
||||||
The reduced density matrices are defined in the basis of molecular
|
The reduced density matrices are defined in the basis of molecular
|
||||||
|
Loading…
Reference in New Issue
Block a user