diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org index 1d4b36e..e0cb18b 100644 --- a/src/templates_front/templator_front.org +++ b/src/templates_front/templator_front.org @@ -4238,14 +4238,15 @@ def delete_$group$(trexio_file) -> None: This section concerns API calls related to Slater determinants. - | Function name | Description | - |----------------------------------------+----------------------------------------| - | ~trexio_has_determinant_coefficient~ | Check if an attribute exists in a file | - | ~trexio_has_determinant_list~ | Check if an attribute exists in a file | - | ~trexio_write_determinant_coefficient~ | Write an attribute | - | ~trexio_write_determinant_list~ | Write an attribute | - | ~trexio_read_determinant_coefficient~ | Read an attribute | - | ~trexio_read_determinant_list~ | Read an attribute | + | Function name | Description | + |--------------------------------------------+----------------------------------------| + | ~trexio_has_determinant_coefficient~ | Check if an attribute exists in a file | + | ~trexio_has_determinant_list~ | Check if an attribute exists in a file | + | ~trexio_write_determinant_coefficient~ | Write an attribute | + | ~trexio_write_determinant_list~ | Write an attribute | + | ~trexio_read_determinant_coefficient~ | Read an attribute | + | ~trexio_read_determinant_list~ | Read an attribute | + | ~trexio_read_determinant_coefficient_size~ | Get the number of the coefficients | *** C source code @@ -4260,6 +4261,7 @@ trexio_exit_code trexio_write_determinant_list(trexio_t* const file, const int64 trexio_exit_code trexio_write_safe_determinant_list(trexio_t* const file, const int64_t offset_file, const int64_t buffer_size, const int64_t* dset_in, const int64_t dim_in); trexio_exit_code trexio_write_determinant_coefficient(trexio_t* const file, const int64_t offset_file, const int64_t buffer_size, const double* dset); trexio_exit_code trexio_write_safe_determinant_coefficient(trexio_t* const file, const int64_t offset_file, const int64_t buffer_size, const double* dset_in, const int64_t dim_in); +trexio_exit_code trexio_read_determinant_coefficient_size(trexio_t* const file, int64_t* const size_max); #+end_src #+begin_src c :tangle read_determinant_front.c @@ -4370,7 +4372,37 @@ trexio_read_determinant_coefficient (trexio_t* const file, const int64_t offset_ return rc; +} + +trexio_exit_code +trexio_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; + if (trexio_has_determinant_coefficient(file) != TREXIO_SUCCESS) return TREXIO_DSET_MISSING; + + switch (file->back_end) { + + case TREXIO_TEXT: + return trexio_text_read_determinant_coefficient_size(file, size_max); + break; + + case TREXIO_HDF5: +#ifdef HAVE_HDF5 + return trexio_hdf5_read_determinant_coefficient_size(file, size_max); + break; +#else + return TREXIO_BACK_END_MISSING; +#endif +/* + case TREXIO_JSON: + return trexio_json_read_ + break; +,*/ + default: + return TREXIO_FAILURE; /* Impossible case */ + } } trexio_exit_code @@ -4490,6 +4522,8 @@ trexio_write_determinant_coefficient (trexio_t* const file, const int64_t offset break; ,*/ } + + return TREXIO_FAILURE; } trexio_exit_code @@ -4596,6 +4630,32 @@ interface integer(c_int64_t), intent(in), value :: list_size end function trexio_write_safe_determinant_list end interface + +interface + integer(trexio_exit_code) function trexio_write_determinant_coefficient(trex_file, & + offset_file, buffer_size, coefficient) bind(C) + use, intrinsic :: iso_c_binding + import + integer(c_int64_t), intent(in), value :: trex_file + integer(c_int64_t), intent(in), value :: offset_file + integer(c_int64_t), intent(in), value :: buffer_size + real(c_double), intent(in) :: coefficient(*) + end function trexio_write_determinant_coefficient +end interface + +interface + integer(trexio_exit_code) function trexio_write_safe_determinant_coefficient (trex_file, & + offset_file, buffer_size, & + coefficient, coefficient_size) bind(C) + use, intrinsic :: iso_c_binding + import + integer(c_int64_t), intent(in), value :: trex_file + integer(c_int64_t), intent(in), value :: offset_file + integer(c_int64_t), intent(in), value :: buffer_size + real(c_double), intent(in) :: coefficient(*) + integer(c_int64_t), intent(in), value :: coefficient_size + end function trexio_write_safe_determinant_coefficient +end interface #+end_src #+begin_src f90 :tangle read_determinant_front_fortran.f90 @@ -4624,6 +4684,42 @@ interface integer(c_int64_t), intent(in), value :: list_size end function trexio_read_safe_determinant_list end interface + +interface + integer(trexio_exit_code) function trexio_read_safe_determinant_coefficient (trex_file, & + offset_file, buffer_size, & + coefficient, coefficient_size) bind(C) + use, intrinsic :: iso_c_binding + import + integer(c_int64_t), intent(in), value :: trex_file + integer(c_int64_t), intent(in), value :: offset_file + integer(c_int64_t), intent(inout) :: buffer_size + real(c_double), intent(out) :: coefficient(*) + integer(c_int64_t), intent(in), value :: coefficient_size + end function trexio_read_safe_determinant_coefficient +end interface + +interface + integer(trexio_exit_code) function trexio_read_determinant_coefficient(trex_file, & + offset_file, buffer_size, coefficient) bind(C) + use, intrinsic :: iso_c_binding + import + integer(c_int64_t), intent(in), value :: trex_file + integer(c_int64_t), intent(in), value :: offset_file + integer(c_int64_t), intent(inout) :: buffer_size + real(c_double), intent(out) :: coefficient(*) + end function trexio_read_determinant_coefficient +end interface + +interface + integer(trexio_exit_code) function trexio_read_determinant_coefficient_size (trex_file, & + size_max) bind(C) + use, intrinsic :: iso_c_binding + import + integer(c_int64_t), intent(in), value :: trex_file + integer(c_int64_t), intent(out) :: size_max + end function trexio_read_determinant_coefficient_size +end interface #+end_src #+begin_src f90 :tangle has_determinant_front_fortran.f90 @@ -4634,6 +4730,14 @@ interface integer(c_int64_t), intent(in), value :: trex_file end function trexio_has_determinant_list end interface + +interface + integer(trexio_exit_code) function trexio_has_determinant_coefficient (trex_file) bind(C) + use, intrinsic :: iso_c_binding + import + integer(c_int64_t), intent(in), value :: trex_file + end function trexio_has_determinant_coefficient +end interface #+end_src *** Python interface @@ -4706,6 +4810,50 @@ def write_determinant_list(trexio_file: File, offset_file: int, buffer_size: int if rc != TREXIO_SUCCESS: raise Error(rc) + +def write_determinant_coefficient(trexio_file: File, offset_file: int, buffer_size: int, coefficients: list) -> None: + """Write the determinant coefficients in the TREXIO file. + + Parameters: + + trexio_file: + TREXIO File object. + + offset_file: int + The number of coefficients to be skipped in the file when writing. + + buffer_size: int + The number of coefficients to write in the file. + + coefficients: list OR numpy.ndarray + Array of determinant_coefficient to be written. If array data type does not correspond to int64, the conversion is performed. + + Raises: + - trexio.Error if TREXIO return code ~rc~ is different from TREXIO_SUCCESS and prints the error message. + - Exception from some other error (e.g. RuntimeError). + """ + + try: + import numpy as np + except ImportError: + raise Exception("NumPy cannot be imported.") + + if not isinstance(offset_file, int): + raise TypeError("offset_file argument has to be an integer.") + if not isinstance(buffer_size, int): + raise TypeError("buffer_size argument has to be an integer.") + if not isinstance(coefficients, (list, tuple, np.ndarray)): + raise TypeError("coefficients argument has to be an array (list, tuple or NumPy ndarray).") + + if isinstance(coefficients, np.ndarray) and not coefficients.dtype==np.float64: + # convert to float64 if input is in a different precision + coefficients_64 = np.float64(coefficients) + rc = pytr.trexio_write_safe_determinant_coefficient(trexio_file.pytrexio_s, offset_file, buffer_size, coefficients_64) + else: + rc = pytr.trexio_write_safe_determinant_coefficient(trexio_file.pytrexio_s, offset_file, buffer_size, coefficients) + + if rc != TREXIO_SUCCESS: + raise Error(rc) #+end_src #+begin_src python :tangle read_determinant_front.py @@ -4718,10 +4866,10 @@ def read_determinant_list(trexio_file: File, offset_file: int, buffer_size: int) TREXIO File object. offset_file: int - The number of integrals to be skipped in the file when reading. + The number of determinants to be skipped in the file when reading. buffer_size: int - The number of integrals to read from the file. + The number of determinants to read from the file. Returns: (determinants, n_int_read, eof_flag) tuple where @@ -4749,7 +4897,7 @@ def read_determinant_list(trexio_file: File, offset_file: int, buffer_size: int) # read the number of determinants already in the file det_num = read_determinant_num(trexio_file) - # TODO: calculate the rank (number of int bit fields per determinant) + # calculate the int_num (number of int bit fields per determinant) mo_num = read_mo_num(trexio_file) int_num = 2*int((mo_num-1)/64+1) @@ -4779,6 +4927,94 @@ def read_determinant_list(trexio_file: File, offset_file: int, buffer_size: int) dets_reshaped = np.reshape(determinants, (verified_size, int_num), order='C') return (dets_reshaped, n_int_read, eof_flag) + +def read_determinant_coefficient(trexio_file: File, offset_file: int, buffer_size: int) -> tuple: + """Read determinant_coefficient from the TREXIO file. + + Parameters: + + trexio_file: + TREXIO File object. + + offset_file: int + The number of coefficient to be skipped in the file when reading. + + buffer_size: int + The number of coefficients to read from the file. + + Returns: + (coefficients, n_int_read, eof_flag) tuple where + - coefficients are NumPy arrays [numpy.ndarray] with the default int64 precision; + - n_int_read [int] is the number of coefficients read from the trexio_file + (either strictly equal to buffer_size or less than buffer_size if EOF has been reached); + - eof_flag [bool] is True when EOF has been reached (i.e. when call to low-level pytrexio API returns TREXIO_END) + False otherwise. + + Raises: + - trexio.Error if TREXIO return code ~rc~ is different from TREXIO_SUCCESS and prints the error message. + - Exception from some other error (e.g. RuntimeError). + """ + + try: + import numpy as np + except ImportError: + raise Exception("NumPy cannot be imported.") + + if not isinstance(offset_file, int): + raise TypeError("offset_file argument has to be an integer.") + if not isinstance(buffer_size, int): + raise TypeError("buffer_size argument has to be an integer.") + + + # read the number of determinants already in the file + det_num = read_determinant_coefficient_size(trexio_file) + + # additional modification needed to avoid allocating more memory than needed if EOF will be reached during read + overflow = offset_file + buffer_size - det_num + eof_flag = False + if overflow > 0: + verified_size = buffer_size - overflow + eof_flag = True + else: + verified_size = buffer_size + + # main call to the low-level (SWIG-wrapped) trexio_read function, which also requires the sizes of the output to be provided + # read_buf_size contains the number of elements being read from the file, useful when EOF has been reached + rc, n_int_read, coefficients = pytr.trexio_read_safe_determinant_coefficient(trexio_file.pytrexio_s, + offset_file, + verified_size, + verified_size) + if rc != TREXIO_SUCCESS: + raise Error(rc) + if n_int_read == 0: + raise ValueError("No integrals have been read from the file.") + if coefficients is None: + raise ValueError("Returned NULL array from the low-level pytrexio API.") + + return (coefficients, n_int_read, eof_flag) + + +def read_determinant_coefficient_size(trexio_file) -> int: + """Read the number of determinant coefficients stored in the TREXIO file. + + Parameter is a ~TREXIO File~ object that has been created by a call to ~open~ function. + + Returns: + ~num~: int + Integer value of corresponding to the size of the determinant_coefficient array from ~trexio_file~. + + Raises: + - Exception from AssertionError if TREXIO return code ~rc~ is different from TREXIO_SUCCESS and prints the error message using trexio_string_of_error. + - Exception from some other error (e.g. RuntimeError). + """ + + rc, num = pytr.trexio_read_determinant_coefficient_size(trexio_file.pytrexio_s) + if rc != TREXIO_SUCCESS: + raise Error(rc) + + return num + #+end_src + #+end_src #+begin_src python :tangle has_determinant_front.py @@ -4800,6 +5036,25 @@ def has_determinant_list(trexio_file) -> bool: raise Error(rc) return rc == TREXIO_SUCCESS + +def has_determinant_coefficient(trexio_file) -> bool: + """Check that determinant_coefficient exists in the TREXIO file. + + Parameter is a ~TREXIO File~ object that has been created by a call to ~open~ function. + + Returns: + True if the variable exists, False otherwise + + Raises: + - trexio.Error if TREXIO return code ~rc~ is TREXIO_FAILURE and prints the error message using string_of_error. + - Exception from some other error (e.g. RuntimeError). + """ + + rc = pytr.trexio_has_determinant_coefficient(trexio_file.pytrexio_s) + if rc == TREXIO_FAILURE: + raise Error(rc) + + return rc == TREXIO_SUCCESS #+end_src * TODO General helper functions diff --git a/src/templates_hdf5/templator_hdf5.org b/src/templates_hdf5/templator_hdf5.org index da2900d..f7108bb 100644 --- a/src/templates_hdf5/templator_hdf5.org +++ b/src/templates_hdf5/templator_hdf5.org @@ -562,6 +562,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 (size_max == NULL) return TREXIO_INVALID_ARG_2; const trexio_hdf5_t* f = (const trexio_hdf5_t*) file; @@ -988,6 +989,7 @@ trexio_exit_code trexio_hdf5_write_determinant_list(trexio_t* const file, const 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 @@ -1138,6 +1140,48 @@ trexio_exit_code trexio_hdf5_write_determinant_coefficient(trexio_t* const file, 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 diff --git a/src/templates_text/templator_text.org b/src/templates_text/templator_text.org index c1097c2..0c04249 100644 --- a/src/templates_text/templator_text.org +++ b/src/templates_text/templator_text.org @@ -1326,6 +1326,7 @@ trexio_exit_code trexio_text_write_determinant_list(trexio_t* const file, const 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 @@ -1429,7 +1430,7 @@ trexio_exit_code trexio_text_read_determinant_coefficient(trexio_t* const file, if (trexio_state != 0) { sprintf(coeff_file_name, "/determinant_coefficient_state_%" PRId32 ".txt", trexio_state); } else { - strncpy(coeff_file_name, "/determinant_coefficient.txt", 28); + 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. */ @@ -1487,6 +1488,59 @@ trexio_exit_code trexio_text_read_determinant_coefficient(trexio_t* const file, 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 @@ -1553,7 +1607,7 @@ trexio_exit_code trexio_text_write_determinant_coefficient(trexio_t* const file, if (trexio_state != 0) { sprintf(coeff_file_name, "/determinant_coefficient_state_%" PRId32 ".txt", trexio_state); } else { - strncpy(coeff_file_name, "/determinant_coefficient.txt", 28); + 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. */ @@ -1584,6 +1638,24 @@ trexio_exit_code trexio_text_write_determinant_coefficient(trexio_t* const 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; } @@ -1624,7 +1696,7 @@ trexio_exit_code trexio_text_has_determinant_coefficient(trexio_t* const file) if (trexio_state != 0) { sprintf(coeff_file_name, "/determinant_coefficient_state_%" PRId32 ".txt", trexio_state); } else { - strncpy(coeff_file_name, "/determinant_coefficient.txt", 28); + 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. */