1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2024-12-22 20:35:44 +01:00

Merge branch 'master' of github.com:TREX-CoE/trexio

This commit is contained in:
Anthony Scemama 2022-12-13 17:08:05 +01:00
commit 158f99bde9
80 changed files with 6353 additions and 1220 deletions

0
.devel Normal file
View File

View File

@ -15,7 +15,7 @@ jobs:
get_commit_message:
name: Get commit message
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
outputs:
message: ${{ steps.commit_message.outputs.message }}
steps:
@ -34,8 +34,8 @@ jobs:
trexio_ubuntu:
runs-on: ubuntu-latest
name: x86 Ubuntu latest
runs-on: ubuntu-20.04
name: x86 Ubuntu 20.04
needs: get_commit_message
steps:
@ -52,10 +52,10 @@ jobs:
./configure --enable-silent-rules
- name: compile TREXIO
run: make -j 2
run: make -j2
- name: check TREXIO
run: make check
run: make -j2 check
- name: create virtual environment
run: |
@ -82,13 +82,27 @@ jobs:
name: pytrexio-source
path: ./trexio-*.tar.gz
- name: clean
run: make clean
- name: maintainer clean
run: make maintainer-clean
- name: reconfigure with clang and AddressSanitizer
run: |
./autogen.sh
./configure CC=clang-11 CFLAGS="-O2 -fsanitize=address -fno-omit-frame-pointer" LDFLAGS="-fsanitize=address" --enable-silent-rules
- name: recompile TREXIO
run: make -j2
- name: recheck TREXIO for memory leaks
run: make -j2 check
- name: maintainer clean
run: make maintainer-clean
trexio_macos:
runs-on: macos-latest
name: x86 MacOS latest
runs-on: macos-11
name: x86 MacOS 11
steps:
- uses: actions/checkout@v2

View File

@ -16,7 +16,7 @@ jobs:
get_commit_message:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
name: Get commit message
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
outputs:
message: ${{ steps.commit_message.outputs.message }}
steps:
@ -39,7 +39,7 @@ jobs:
if: >-
contains(needs.get_commit_message.outputs.message, '[wheel build]') ||
(github.repository == 'TREX-CoE/trexio' && startsWith(github.ref, 'refs/tags/v'))
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
strategy:
matrix:
manylinux_tag: [2010_x86_64, 2014_x86_64, 2_24_x86_64]
@ -152,7 +152,7 @@ jobs:
working-directory: python
- name: Install Python dependencies
run: pip install --upgrade pip setuptools build delocate
run: pip install --upgrade pip setuptools build delocate pytest
- name: Build wheel for a given version of CPython
run: |
@ -169,7 +169,7 @@ jobs:
working-directory: python
- name: Test the wheel
run: python test_api.py
run: pytest -v test_api.py
working-directory: python/test
- name: Upload produced wheels as artifacts
@ -182,7 +182,7 @@ jobs:
publish_wheels:
name: Publish all wheels on PyPI
needs: [build_linux_wheels, build_macos_wheels]
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: Checkout the branch
@ -222,7 +222,7 @@ jobs:
#- name: Publish distribution 📦 to Test PyPI
# uses: pypa/gh-action-pypi-publish@master
# with:
# with:
# password: ${{ secrets.TEST_PYPI_API_TOKEN }}
# repository_url: https://test.pypi.org/legacy/
#verbose: true

View File

@ -20,7 +20,7 @@ jobs:
run: sudo apt-get update
- name: install dependencies
run: sudo apt-get install emacs26
run: sudo apt-get install emacs
# this step is needed to pull the git submodule org-html-themes
#- name: initialize submodules

3
.gitignore vendored
View File

@ -41,6 +41,3 @@ trex.json
*~
.*.swp
/build*
# output of debian build (debuild)
libtrexio-*
libtrexio_*

4
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "python/examples"]
path = python/examples
url = git@github.com:TREX-CoE/trexio-tutorials.git
url = https://github.com/TREX-CoE/trexio-tutorials.git
[submodule "docs/org-html-themes"]
path = docs/org-html-themes
url = git@github.com:fniessen/org-html-themes.git
url = https://github.com/fniessen/org-html-themes.git

10
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,10 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files

View File

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
# Initialize the CMake project.
project(Trexio
VERSION 2.2.0
VERSION 2.3.0
DESCRIPTION "TREX I/O library"
LANGUAGES C Fortran
)
@ -16,7 +16,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
# Optional configure for developer mode to generate source code from org-mode files.
option(TREXIO_DEVEL "TREXIO developer mode (for code generation)." OFF)
if(EXISTS "${CMAKE_SOURCE_DIR}/.git/config")
if(EXISTS "${CMAKE_SOURCE_DIR}/.devel")
set(TREXIO_DEVEL ON)
find_package(Python3 REQUIRED)
if(Python3_FOUND)

View File

@ -1,9 +1,35 @@
CHANGES
=======
2.3
---
- Fixed Fortran interface on 32-bit (e.g. i386) architectures
- Changed the structure of the state group
- Sparse data type is patched to work with different dimensions
- Safer cleaning of the output files in TREXIO_TEXT tests
- The global `state` switch is replaced with `state_id` attribute
- Added `float buffered` type for vectors like CI/CSF coefficients
- .git folder is no longer needed to activate TREXIO_DEVEL mode
- Renamed debian folder into helpers-debian
- Added trexio_to_bitfield_list functionality
- Added `trexio_has_group` functionality
- Added OCaml binding
- Added spin and energy in MOs
- Added CSF group
- Added Cholesky-decomposed two-electron integrals
- Added Cholesky-decomposed RDMs for Gammcor
- Added `trexio_flush` functionality
- Optional compilation `--without-fortran`
2.2
---
- Added `dim_readonly` data type for read-only dimensions
- Added I/O for the CI determinants (lists and coefficients) in #91
- Merged local and non-local components of pseudopotential integrals in #89
- Added QMC components to the format in #89
- Added debian packaging in #84
- Added support for Python-ic `with` statements
- Merged local and non-local pseudopotential integrals in #86
- Fixed backwards incompatibility of the `TREXIO_TEXT` back end in #82

View File

@ -34,7 +34,11 @@
ACLOCAL_AMFLAGS = -I m4
CLEANFILES = trexio.mod
if HAVE_FORTRAN
BUILT_SOURCES = trexio.mod
else
BUILT_SOURCES =
endif
EXTRA_DIST = .git_hash
PACKAGE_VERSION = @PACKAGE_VERSION@
@ -45,10 +49,13 @@ pkgconfig_DATA = pkgconfig/trexio.pc
# =============== BUILD =============== #
trexio_h = $(srcdir)/include/trexio.h
trexio_f = $(srcdir)/include/trexio_f.f90
trexio_h = include/trexio.h
include_HEADERS = $(trexio_h)
include_HEADERS = $(trexio_h) $(trexio_f)
if HAVE_FORTRAN
trexio_f = include/trexio_f.f90
include_HEADERS += $(trexio_f)
endif
AM_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/include
@ -56,7 +63,6 @@ lib_LTLIBRARIES = src/libtrexio.la
SOURCES = \
$(trexio_h) \
src/trexio.c \
src/trexio_private.h \
src/trexio_s.h \
@ -75,7 +81,7 @@ ORG_FILES = \
trex.org
src_libtrexio_la_SOURCES = $(SOURCES)
src_libtrexio_la_SOURCES = $(trexio_h) $(SOURCES)
# Include CMake-related files in the distribution.
EXTRA_DIST += CMakeLists.txt \
@ -85,25 +91,6 @@ EXTRA_DIST += CMakeLists.txt \
cmake/FindTREXIO.cmake
# Include files needed to produce the debian package.
DEB_FILES = \
debian/changelog \
debian/compat \
debian/control \
debian/copyright \
debian/patches \
debian/README.Debian \
debian/README.md \
debian/rules \
debian/source \
debian/watch
EXTRA_DIST += $(DEB_FILES)
debian_from_dist: $(DEB_FILES) $(SOURCES) $(trexio_h)
cp ../trexio-$(PACKAGE_VERSION).tar.gz ../libtrexio_$(PACKAGE_VERSION).orig.tar.gz
debuild
# =============== TESTS =============== #
TESTS_C = \
@ -112,6 +99,7 @@ TESTS_C = \
tests/io_dset_float_text \
tests/io_dset_int_text \
tests/io_dset_sparse_text \
tests/io_determinant_text \
tests/io_safe_dset_float_text \
tests/io_str_text \
tests/io_dset_str_text \
@ -127,6 +115,7 @@ TESTS_C += \
tests/io_dset_float_hdf5 \
tests/io_dset_int_hdf5 \
tests/io_dset_sparse_hdf5 \
tests/io_determinant_hdf5 \
tests/io_safe_dset_float_hdf5 \
tests/io_str_hdf5 \
tests/io_dset_str_hdf5 \
@ -134,17 +123,20 @@ TESTS_C += \
tests/overwrite_all_hdf5
endif
TESTS_F = \
tests/test_f
TESTS = $(TESTS_C)
if HAVE_FORTRAN
TESTS_F = tests/test_f
TESTS += $(TESTS_F)
endif
TESTS = $(TESTS_C) $(TESTS_F)
check_PROGRAMS = $(TESTS)
# specify common LDADD options for all tests
LDADD = src/libtrexio.la
test_trexio_f = $(srcdir)/tests/trexio_f.f90
CLEANFILES += $(test_trexio_f)
if HAVE_FORTRAN
test_trexio_f = tests/trexio_f.f90
$(test_trexio_f): $(trexio_f)
cp $(trexio_f) $(test_trexio_f)
@ -152,10 +144,16 @@ $(test_trexio_f): $(trexio_f)
trexio.mod: tests/trexio_f.o
tests_test_f_SOURCES = $(test_trexio_f) tests/test_f.f90
endif
clean-local:
-rm -rf -- *.dir/ *.h5 __pycache__/
# =============== GUIX MANIFEST =============== #
trexio_scm = $(srcdir)/tools/trexio.scm
EXTRA_DIST += $(trexio_scm)
# =============== DOCUMENTATION =============== #
HTML_TANGLED = docs/index.html \
@ -193,9 +191,15 @@ HDF5_CPPFLAGS = @HDF5_CPPFLAGS@
if TREXIO_DEVEL
CLEANFILES += $(SOURCES) $(trexio_f) $(trexio_h) $(HTML_TANGLED) $(htmlizer) .git_hash
CLEANFILES += $(SOURCES) $(trexio_h) $(HTML_TANGLED) $(htmlizer) .git_hash
BUILT_SOURCES += $(SOURCES) $(trexio_f) $(test_trexio_f)
BUILT_SOURCES += $(SOURCES) $(trexio_h)
if HAVE_FORTRAN
CLEANFILES += $(trexio_f)
BUILT_SOURCES += $(trexio_f) $(test_trexio_f)
$(trexio_f): $(trexio_h)
endif
.git_hash: FORCE
git log | head -1 | cut -d ' ' -f 2 > .git_hash
@ -205,10 +209,10 @@ all: .git_hash
GENERATOR_FILES = $(srcdir)/tools/generator.py \
$(srcdir)/tools/generator_tools.py
$(SOURCES): $(trexio_f)
$(SOURCES): $(trexio_h)
src/trexio.c: $(trexio_h)
$(trexio_f): $(ORG_FILES) $(GENERATOR_FILES)
$(trexio_h): $(ORG_FILES) $(GENERATOR_FILES)
cd $(srcdir)/tools && ./build_trexio.sh
$(htmlizer): $(ORG_FILES) $(srcdir)/src/README.org
@ -225,6 +229,22 @@ cppcheck.out: $(trexio_h)
--language=c --std=c99 -rp --platform=unix64 \
-I../include *.c *.h 2>../$@
#################
# OCaml binding #
#################
ocaml/trexio/_build/default/lib/trexio.cma:
$(MAKE) -C ocaml/trexio
ocaml: ocaml/trexio/_build/default/lib/trexio.cma
ocaml-install: ocaml/trexio/_build/default/lib/trexio.cma
opam install ocaml/trexio
##################
# Python binding #
##################
setup_py = $(srcdir)/python/setup.py
setup_cfg = $(srcdir)/python/setup.cfg
pytrexio_py = $(srcdir)/python/pytrexio/pytrexio.py
@ -236,8 +256,9 @@ numpy_i = $(srcdir)/src/numpy.i
python-test: $(TEST_PY)
python3 $(TEST_PY)
python3 -m pytest -v $(TEST_PY)
$(RM) -r -- __pycache__
$(RM) -f -- test_file_py.h5 unsafe_test_file_py.h5
python-install: $(pytrexio_py) $(setup_py) $(setup_cfg)
cd python && \
@ -269,12 +290,30 @@ $(numpy_i):
check-numpy:
cd tools && ./check_numpy_i.sh
# Include files needed to produce the debian package.
DEB_FILES = \
helpers-debian/changelog \
helpers-debian/compat \
helpers-debian/control \
helpers-debian/copyright \
helpers-debian/rules \
helpers-debian/source \
helpers-debian/libtrexio0.install \
helpers-debian/libtrexio-dev.install \
helpers-debian/source \
helpers-debian/README.source
debian_from_dist: $(DEB_FILES) $(SOURCES) $(trexio_h)
cp ../trexio-$(PACKAGE_VERSION).tar.gz ../libtrexio_$(PACKAGE_VERSION).orig.tar.gz
debuild
CLEANFILES += $(pytrexio_c) \
$(pytrexio_py) \
$(trexio_py) \
python/src/*.c \
python/src/*.h
.PHONY: cppcheck python-test python-install python-sdist check-numpy FORCE
.PHONY: cppcheck python-test python-install python-sdist check-numpy FORCE ocaml
endif

View File

@ -1,5 +1,6 @@
# TREXIO
<img src="https://trex-coe.eu/sites/default/files/styles/responsive_no_crop/public/2022-01/TREXIO%20Code.png" width=200>
[![build](https://github.com/TREX-CoE/trexio/actions/workflows/actions.yml/badge.svg)](https://github.com/TREX-CoE/trexio/actions/workflows/actions.yml)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/TREX-CoE/trexio)
@ -9,10 +10,10 @@ TREX library for efficient I/O.
## Minimal requirements (for users):
- Autotools (autoconf >= 2.69, automake >= 1.11, libtool >= 2.2) or CMake (>= 3.16)
- Autotools (autoconf >= 2.69, automake >= 1.11, libtool >= 2.2) or CMake (>= 3.16)
- C compiler (gcc/icc/clang)
- Fortran compiler (gfortran/ifort)
- HDF5 library (>= 1.8) [optional, recommended for high performance]
- HDF5 library (>= 1.8) [optional, recommended for high performance]
## Installation procedure from the tarball (for users):
@ -34,7 +35,7 @@ TREX library for efficient I/O.
- python3 (>= 3.6)
- Emacs (>= 26.0)
- SWIG (>= 4.0)
- SWIG (>= 4.0) [required for the Python API]
## Installation procedure from the GitHub repo clone (for developers):
@ -61,6 +62,48 @@ The aforementioned instructions rely on [Autotools](https://www.gnu.org/software
**Note: when linking against an MPI-enabled HDF5 library one usually has to specify the MPI wrapper for the C compiler by adding, e.g., `-DCMAKE_C_COMPILER=mpicc` to the `cmake` command.**
## Installation procedure for conda users
[![Anaconda-Server Badge](https://anaconda.org/conda-forge/trexio/badges/version.svg)](https://anaconda.org/conda-forge/trexio)
[![Anaconda-Server Badge](https://anaconda.org/conda-forge/trexio/badges/platforms.svg)](https://anaconda.org/conda-forge/trexio)
The official releases of TREXIO `>2.0.0` are also available via the `conda-forge` channel.
The pre-compiled stable binaries of `trexio` can be installed as follows:
```
conda install trexio -c conda-forge
```
More details can be found in the corresponding [trexio-feedstock](https://github.com/conda-forge/trexio-feedstock).
Note that both parallel (see `mpi_openmpi` prefix) and serial (`nompi`) variants are provided.
## Installation procedure for Guix users
The official releases of TREXIO `>=2.0.0` can be installed using the
[GNU Guix](https://guix.gnu.org) functional package manager.
The [trexio.scm](https://github.com/TREX-CoE/trexio/blob/master/tools/trexio.scm)
Schema file contains the manifest specification for the `trexio` package.
It can be installed within the selected `$GUIX_PROFILE` as follows:
```
guix package \
--profile=$GUIX_PROFILE \
--cores=<n_cores> \
--install-from-file=trexio.scm
```
## Installation procedure for Spack users
The official releases `>=2.0.0` and the development version of TREXIO can be installed using the
[Spack](https://spack.io/) package manager.
The [trexio/package.py](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/trexio/package.py)
file contains the Spack specifications required to build different variants of `trexio` library.
It can be installed as follows
```
spack install --jobs <n_cores> trexio
```
## Compilation without the HDF5 library
By default, the configuration step proceeds to search for the [HDF5 library](https://portal.hdfgroup.org/display/HDF5/HDF5).
@ -120,6 +163,24 @@ These quantities can be accessed using the corresponding `trexio_[has|read|write
For more details regarding the installation and usage of the TREXIO Python API,
see [this page](python/README.md).
The aforementioned instructions are adapted for users installing from the source code distribution (periodically updated).
In order to install the Python API with the latest changes, follow the developer installation guide and run the following command in the end
```
make python-install
```
**Note: this implies that both HDF5 and SWIG are installed and available.
At the moment, it is not possible to configure the Python API without HDF5 library.**
We rely on the `pytest` package for unit testing. It can be installed via `pip install pytest`. To test the installation, run
```
make python-test
```
We highly recommend to use virtual environments to avoid compatibility issues and to improve reproducibility.
## Tutorial

View File

@ -6,7 +6,7 @@
# TREXIO_INCLUDE_DIRS - The TREXIO include directories;
# TREXIO_LIBRARIES - The libraries needed to use TREXIO;
# If TREXIO has been installed in a non-standard location, one can set an
# If TREXIO has been installed in a non-standard location, one can set an
# environment variable $TREXIO_DIR in the current shell:
# $ export TREXIO_DIR=<custom_path>
# to indicate the prefix used during the TREXIO installation
@ -45,13 +45,13 @@ set(TREXIO_SEARCH_PATHS
/opt
)
find_path(TREXIO_INCLUDE_DIR
NAMES trexio.h
find_path(TREXIO_INCLUDE_DIR
NAMES trexio.h
HINTS $ENV{TREXIO_DIR}
PATH_SUFFIXES include/trexio include
PATHS ${TREXIO_SEARCH_PATHS}
)
# No need to specify platform-specific prefix (e.g. libtrexio on Unix) or
# suffix (e.g. .so on Unix or .dylib on MacOS) in NAMES. CMake takes care of that.
@ -70,8 +70,8 @@ INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(TREXIO DEFAULT_MSG TREXIO_LIBRARY TREXIO_INCLUDE_DIR )
MARK_AS_ADVANCED(TREXIO_INCLUDE_DIR TREXIO_LIBRARY)
# Mot setting _INCLUDE_DIR and _LIBRARIES is considered a bug,
# Mot setting _INCLUDE_DIR and _LIBRARIES is considered a bug,
# see https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/How-To-Find-Libraries
set(TREXIO_LIBRARIES ${TREXIO_LIBRARY})
set(TREXIO_INCLUDE_DIRS ${TREXIO_INCLUDE_DIR})
set(TREXIO_INCLUDE_DIRS ${TREXIO_INCLUDE_DIR})

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([trexio],[2.2.0],[https://github.com/TREX-CoE/trexio/issues])
AC_INIT([trexio],[2.3.0],[https://github.com/TREX-CoE/trexio/issues])
AC_CONFIG_SRCDIR([Makefile.in])
AC_CONFIG_HEADERS([include/config.h])
@ -16,11 +16,11 @@ AM_PROG_AR
LT_PREREQ([2.2])
LT_INIT
# Activate developer mode when the source is the git repository.
# Activate developer mode if a dummy file is present (true when cloning the git repository).
# Otherwise, it is the source distribution and the developer mode should not be activated.
TEST_IFEXISTS=".git"
AC_CHECK_FILE([$TEST_IFEXISTS],
[enable_maintainer_mode="yes"],
TEST_IFEXISTS=".devel"
AS_IF([test -f $TEST_IFEXISTS],
[enable_maintainer_mode="yes"]
)
VERSION_MAJOR=`echo ${PACKAGE_VERSION} | cut -d. -f1`
@ -50,12 +50,18 @@ AS_IF([test "$ac_cv_prog_cc_c99" = "no"],
[AC_MSG_ERROR([The compiler does not support C99])])
AC_PROG_CC_C_O
# Fortran
AC_PROG_FC
AC_FC_FREEFORM
AC_FC_SRCEXT([f90])
AC_PROG_FC_C_O
AC_FC_LIBRARY_LDFLAGS
# Fortran API [default: --with-fortran], do not disable in the dev mode
AC_ARG_WITH(fortran, [AS_HELP_STRING([--without-fortran],[do not test and install the Fortran API])], ok=$withval, ok=yes)
if test "$ok" = "yes"; then
AC_PROG_FC
AC_FC_FREEFORM
AC_FC_SRCEXT([f90])
AC_PROG_FC_C_O
AC_FC_LIBRARY_LDFLAGS
fi
AM_CONDITIONAL([HAVE_FORTRAN],[test "$ok" = "yes"])
# pkg-config
PKG_PROG_PKG_CONFIG()
@ -66,6 +72,31 @@ AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_GREP
# Specific options required with some compilers
case $FC in
*gfortran*)
FCFLAGS="$FCFLAGS -fPIC"
;;
*flang*)
FCFLAGS="$FCFLAGS -fPIC"
;;
*ifort*)
FCFLAGS="$FCFLAGS -fPIC"
;;
esac
case $CC in
*gcc*)
CFLAGS="$CFLAGS -fPIC"
;;
*clang*)
CFLAGS="$CFLAGS -fPIC"
;;
*icc*)
CFLAGS="$CFLAGS -fPIC"
;;
esac
## ---------
## Libraries
@ -144,7 +175,7 @@ AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
# Checks for library functions.
AC_FUNC_MALLOC
# AC_FUNC_MALLOC
AC_CHECK_FUNCS([memset mkdir strerror])
if test "x$enable_maintainer_mode" == "xyes"; then
@ -153,6 +184,27 @@ else
TREXIO_DEVEL=""
fi
AC_ARG_WITH(efence, [AS_HELP_STRING([--with-efence],[use ElectricFence library])], ok=$withval, ok=no)
if test "$ok" = "yes"; then
AC_CHECK_LIB([efence], [malloc])
ARGS="${ARGS} efence"
fi
AC_ARG_ENABLE(malloc-trace, [AS_HELP_STRING([--enable-malloc-trace],[use debug malloc/free])], ok=$enableval, ok=no)
if test "$ok" = "yes"; then
AC_DEFINE(MALLOC_TRACE,"malloc_trace.dat",[Define to use debugging malloc/free])
ARGS="${ARGS} malloc-trace"
fi
AC_ARG_ENABLE(prof, [AS_HELP_STRING([--enable-prof],[compile for profiling])], ok=$enableval, ok=no)
if test "$ok" = "yes"; then
CFLAGS="${CFLAGS} -pg"
AC_DEFINE(ENABLE_PROF,1,[Define when using the profiler tool])
ARGS="${ARGS} prof"
fi
AM_CONDITIONAL([TREXIO_DEVEL],[test "x$TREXIO_DEVEL" != x])
if test "x${TREXIO_DEVEL}" != "x"; then

5
debian/changelog vendored
View File

@ -1,5 +0,0 @@
libtrexio (2.1.0-1) UNRELEASED; urgency=low
* Initial release.
-- Evgeny Posenitskiy <posenitskiy@irsamc.ups-tlse.fr> Wed, 16 Feb 2022 15:07:02 +0100

15
debian/control vendored
View File

@ -1,15 +0,0 @@
Source: libtrexio
Section: science
Priority: optional
Maintainer: Evgeny Posenitskiy <posenitskiy@irsamc.ups-tlse.fr>
Build-Depends: gfortran, pkg-config, libhdf5-dev, debhelper (>=11~), dh-autoreconf
Standards-Version: 4.1.4
Homepage: https://trex-coe.github.io/trexio/
Package: libtrexio
Architecture: any
Multi-Arch: foreign
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: I/O library for quantum chemistry.
This Debian binary package was auto-generated by the
debmake(1) command provided by the debmake package.

9
debian/rules vendored
View File

@ -1,9 +0,0 @@
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
#export DH_VERBOSE = 1
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh $@ --with autoreconf

View File

@ -3,7 +3,8 @@
#+SETUPFILE: docs/theme.setup
* Accessing sparse quantities
* Accessing sparse quantities (integrals)
** Fortran
:PROPERTIES:
:header-args: :tangle print_energy.f90
@ -270,3 +271,83 @@ program print_energy
end program
#+end_src
* Reading determinants
** Fortran
:PROPERTIES:
:header-args: :tangle print_dets.f90
:END:
#+begin_src f90
program test
use trexio
implicit none
character*(128) :: filename ! Name of the input file
integer(trexio_exit_code) :: rc ! Return code for error checking
integer(trexio_t) :: trex_determinant_file ! TREXIO file handle
character*(128) :: err_msg ! Error message
integer*8, allocatable :: buffer(:,:,:)
integer(8) :: offset, icount, BUFSIZE
integer :: ndet, int64_num, m
integer :: occ_num_up, occ_num_dn
integer, allocatable :: orb_list_up(:), orb_list_dn(:)
call getarg(1, filename)
trex_determinant_file = trexio_open(filename, 'r', TREXIO_AUTO, rc)
if (rc /= TREXIO_SUCCESS) then
call trexio_string_of_error(rc, err_msg)
print *, 'Error opening TREXIO file: '//trim(err_msg)
stop
end if
rc = trexio_read_determinant_num(trex_determinant_file, ndet)
if (rc /= TREXIO_SUCCESS) then
call trexio_string_of_error(rc, err_msg)
print *, 'Error reading determinant_num: '//trim(err_msg)
stop
end if
print *, 'ndet', ndet
rc = trexio_get_int64_num(trex_determinant_file, int64_num)
if (rc /= TREXIO_SUCCESS) then
call trexio_string_of_error(rc, err_msg)
print *, 'Error reading int64_num: '//trim(err_msg)
stop
end if
print *, 'int64_num', int64_num
BUFSIZE = 1000_8
allocate(buffer(int64_num, 2, BUFSIZE))
allocate(orb_list_up(int64_num*64), orb_list_dn(int64_num*64))
offset = 0_8
icount = BUFSIZE
do while (icount == BUFSIZE)
if (offset < ndet) then
rc = trexio_read_determinant_list(trex_determinant_file, offset, icount, buffer)
offset = offset + icount
else
icount = 0
end if
print *, '---'
do m=1,icount
rc = trexio_to_orbital_list_up_dn(int64_num, buffer(1,1,m), &
orb_list_up, orb_list_dn, occ_num_up, occ_num_dn)
print '(100(I3,X))', (orb_list_up(1:occ_num_up)), (orb_list_dn(1:occ_num_dn))
print *, ''
end do
end do
deallocate(buffer, orb_list_dn, orb_list_up)
end
#+end_src

View File

@ -0,0 +1,15 @@
libtrexio for Debian
-------------------
TREXIO distribution tarballs contain the source code required to build the C
library and the Fortran module based on the ISO_C_BINDING.
The build system is Autotools and follows the common installation path, i.e.
./autogeh.sh && ./configure && make && make install
For details about the development version (i.e. compiling from the GitHub
repository clone) contact the upstream maintainers.
-- Evgeny <posenitskiy@irsamc.ups-tlse.fr> Tue, 27 Sep 2022 10:34:39 +0200

5
helpers-debian/changelog Normal file
View File

@ -0,0 +1,5 @@
libtrexio (2.2.1-1) UNRELEASED; urgency=medium
* Initial release (Closes: #1020772)
-- Evgeny <posenitskiy@irsamc.ups-tlse.fr> Tue, 27 Sep 2022 10:34:39 +0200

30
helpers-debian/control Normal file
View File

@ -0,0 +1,30 @@
Source: libtrexio
Section: science
Priority: optional
Maintainer: Evgeny <posenitskiy@irsamc.ups-tlse.fr>
Build-Depends: debhelper-compat (= 12),
gfortran,
pkg-config,
libhdf5-dev
Standards-Version: 4.4.1
Homepage: https://github.com/TREX-CoE/trexio
#Vcs-Browser: https://salsa.debian.org/debian/libtrexio
#Vcs-Git: https://salsa.debian.org/debian/libtrexio.git
Package: libtrexio-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libtrexio0 (= ${binary:Version}), ${misc:Depends}
Description: TREX I/O library for efficient data I/O in quantum chemistry.
.
This package contains the static C library, C headers
and the Fortran modules necessary for developers.
Package: libtrexio0
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: TREX I/O library for efficient data I/O in quantum chemistry.
.
This package contains the shared C library.

View File

@ -1,11 +1,30 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: libtrexio
Source: <url://github.com/TREX-CoE/trexio>
#
# Please double check copyright with the licensecheck(1) command.
Upstream-Contact: Evgeny <posenitskiy@irsamc.ups-tlse.fr>
Source: <https://github.com/TREX-CoE/trexio>
Files: debian/*
Copyright: 2022 Evgeny <posenitskiy@irsamc.ups-tlse.fr>
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
Files: .git_hash
AUTHORS
ChangeLog
Makefile.am
CMakeLists.txt
NEWS
@ -35,6 +54,8 @@ Files: .git_hash
tests/io_dset_int_text.c
tests/io_dset_sparse_hdf5.c
tests/io_dset_sparse_text.c
tests/io_determinant_hdf5.c
tests/io_determinant_text.c
tests/io_dset_str_hdf5.c
tests/io_dset_str_text.c
tests/io_num_hdf5.c
@ -47,6 +68,9 @@ Files: .git_hash
tests/open_text.c
tests/overwrite_all_hdf5.c
tests/overwrite_all_text.c
tests/delete_group_hdf5.c
tests/delete_group_text.c
tests/pre_close.c
tests/test_f.f90
tests/trexio_f.f90
Copyright: 2020 TREX Center of Excellence
@ -75,9 +99,6 @@ License: BSD-3-Clause
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.
On Debian systems, the complete text of the BSD 3-clause "New" or "Revised"
License can be found in `/usr/share/common-licenses/BSD'.
Files: Makefile.in
aclocal.m4
@ -277,9 +298,6 @@ License: GPL-3.0+ with autoconf exception
the same distribution terms that you use for the rest of that
program. This Exception is an additional permission under section 7
of the GNU General Public License, version 3 ("GPLv3").
.
On Debian systems, the complete text of the GNU General Public License
Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
Files: m4/ax_pkg_swig.m4
Copyright: 2008 Alan W. Irwin
@ -331,14 +349,11 @@ License: GPL-2.0+ with unknown exception *** check multiple exceptions ***
#----------------------------------------------------------------------------
# Files marked as NO_LICENSE_TEXT_FOUND may be covered by the following
# license/copyright files.
#----------------------------------------------------------------------------
# License file: COPYING
BSD 3-Clause License
.
Copyright (c) 2021, TREX Center of Excellence
All rights reserved.
Copyright 2020 TREX Center of Excellence
License BSD-3-Clause
.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@ -364,3 +379,4 @@ License: GPL-2.0+ with unknown exception *** check multiple exceptions ***
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,4 @@
usr/include/*
usr/lib/*/lib*.so
usr/lib/*/lib*.a
usr/lib/*/pkgconfig/*

View File

@ -0,0 +1 @@
usr/lib/*/lib*.so.*

21
helpers-debian/rules Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/make -f
# output every command that modifies files on the build system.
#export DH_VERBOSE = 1
# see FEATURE AREAS in dpkg-buildflags(1)
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh $@

View File

@ -257,7 +257,7 @@ HDF5 support is being disabled (equivalent to --with-hdf5=no).
AC_MSG_WARN([Unable to compile HDF5 test program])
fi
dnl Look for HDF5's high level library
AC_HAVE_LIBRARY([hdf5_hl], [HDF5_LIBS="-lhdf5_hl $HDF5_LIBS"], [], [])
AC_CHECK_LIB([hdf5_hl], [main],[HDF5_LIBS="-lhdf5_hl $HDF5_LIBS"], [], [])
CC=$ax_lib_hdf5_save_CC
CPPFLAGS=$ax_lib_hdf5_save_CPPFLAGS

3
ocaml/trexio/.ocamlinit Normal file
View File

@ -0,0 +1,3 @@
#use "topfind";;
open Printf;;

9
ocaml/trexio/Makefile Normal file
View File

@ -0,0 +1,9 @@
default: sources
dune build
lib/trexio.ml: ../../trex.json read_json.py src/trexio.ml src/trexio.mli src/trexio_stubs.c
./read_json.py
sources: lib/trexio.ml
.PHONY: sources default

9
ocaml/trexio/README.md Normal file
View File

@ -0,0 +1,9 @@
# TREXIO OCaml interface
## Building the source code
The hand-written source files are located in the `src` directory. These files contain
the pieces of code that can't be generated automatically. The source code distributed
in the OPAM package is generated by the `read_json.py` script, and is written in files
located in the `lib` directory.

36
ocaml/trexio/dune-project Normal file
View File

@ -0,0 +1,36 @@
(lang dune 3.1)
(name trexio)
(version 2.3.0)
(generate_opam_files true)
(source
(github trex-coe/trexio_ocaml))
(authors
"Anthony Scemama <scemama@irsamc.ups-tlse.fr>"
"Evgeny Posenitskiy <posenitskiy@irsamc.ups-tlse.fr>"
)
(maintainers
"Anthony Scemama <scemama@irsamc.ups-tlse.fr>"
)
(license "BSD-3-Clause")
(documentation "https://trex-coe.github.io/trexio/")
(package
(name trexio)
(synopsis "Binding for the TREXIO Input/Output library")
(description "TREXIO is a file format and library for storing wave functions and integrals for quantum chemistry.")
(depends
dune
(dune-configurator :build)
(conf-pkg-config :build))
(tags
("Quantum chemistry" "Library"))
)
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project

View File

@ -0,0 +1,22 @@
module C = Configurator.V1
let () =
C.main ~name:"trexio" (fun c ->
let default : C.Pkg_config.package_conf =
{ libs = ["-ltrexio"]
; cflags = ["-fPIC"]
}
in
let conf =
match C.Pkg_config.get c with
| None -> default
| Some pc ->
match (C.Pkg_config.query pc ~package:"trexio") with
| None -> default
| Some deps -> deps
in
C.Flags.write_sexp "c_flags.sexp" conf.cflags;
C.Flags.write_sexp "c_library_flags.sexp" conf.libs)

View File

@ -0,0 +1,3 @@
(executable
(name discover)
(libraries dune-configurator))

19
ocaml/trexio/lib/dune Normal file
View File

@ -0,0 +1,19 @@
(library
(name trexio)
(public_name trexio)
(foreign_stubs
(language c)
(names trexio_stubs)
(flags (:include c_flags.sexp) "-fPIC"))
(c_library_flags (:include c_library_flags.sexp))
)
(rule
(targets c_flags.sexp c_library_flags.sexp)
(action (run ./config/discover.exe)))
(env
(dev
(flags ))
(release
(ocamlopt_flags )))

659
ocaml/trexio/read_json.py Executable file
View File

@ -0,0 +1,659 @@
#!/usr/bin/env python
import json
json_file = "../../trex.json"
stubs_file= "trexio_stubs.c"
ml_file = "trexio.ml"
mli_file = ml_file+"i"
def write_stubs(data):
with open("src/"+stubs_file,'r') as f:
content = f.readlines()
index = -1
for i, line in enumerate(content):
if line.startswith("/**** ****/"):
index = i
break
content_pre = ''.join(content[:index])
content_post = ''.join(content[index:])
with open("lib/"+stubs_file,'w') as f:
f.write(content_pre)
for group in data:
t = """
CAMLprim value caml_delete_{group}(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_delete_{group}( File_val(file) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_has_{group}(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_has_{group}( File_val(file) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_bool(true) );
} else {
CAMLreturn ( Val_bool(false) );
}
}
"""
f.write( t.replace("{group}",group) )
for element in data[group]:
t = """
CAMLprim value caml_has_{group}_{element}(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_has_{group}_{element}( File_val(file) );
CAMLreturn ( Val_bool(rc == TREXIO_SUCCESS) );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element) )
# Scalar elements
if data[group][element][1] == []:
if data[group][element][0] in [ "int", "dim", "index" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file)
{
CAMLparam1(file);
int64_t result;
trexio_exit_code rc = trexio_read_{group}_{element}_64( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_int(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_write_{group}_{element}(value file, value data)
{
CAMLparam2(file, data);
trexio_exit_code rc = trexio_write_{group}_{element}_64( File_val(file), (int64_t) Int_val(data) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "float" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file)
{
CAMLparam1(file);
double result;
trexio_exit_code rc = trexio_read_{group}_{element}_64( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( caml_copy_double(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_write_{group}_{element}(value file, value data)
{
CAMLparam2(file, data);
trexio_exit_code rc = trexio_write_{group}_{element}_64( File_val(file), (double) Double_val(data) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file, value max_str_len_in)
{
CAMLparam2(file, max_str_len_in);
int32_t max_str_len = Int_val(max_str_len_in);
char result[max_str_len];
trexio_exit_code rc = trexio_read_{group}_{element}( File_val(file), result, max_str_len);
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( caml_copy_string(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_write_{group}_{element}(value file, value data)
{
CAMLparam2(file, data);
const char* val = String_val(data);
trexio_exit_code rc = trexio_write_{group}_{element}( File_val(file), val, (int32_t) strlen(val));
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
if data[group][element][0] in [ "dim readonly" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file)
{
CAMLparam1(file);
int64_t result;
trexio_exit_code rc = trexio_read_{group}_{element}_64( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_int(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0].split()[0]) )
# Array elements
else:
if data[group][element][0] in [ "float" ]:
t = """
CAMLprim value caml_read_safe_{group}_{element}(value file_in, value size_max_in)
{
CAMLparam2 ( file_in, size_max_in );
CAMLlocal1 ( result );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
double* read_data = (double*) malloc (size_max * sizeof(double));
trexio_exit_code rc = trexio_read_safe_{group}_{element}_64(file, read_data, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(size_max * Double_wosize, Double_array_tag);
for (size_t i=0 ; i<size_max ; ++i) {
Store_double_field( result, i, read_data[i] );
}
free(read_data);
CAMLreturn (result);
}
CAMLprim value caml_write_safe_{group}_{element}(value file_in, value size_max_in, value array)
{
CAMLparam3 ( file_in, size_max_in, array );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
double* c_array = (double*) malloc (size_max * sizeof(double));
for (size_t i=0 ; i<size_max ; ++i) {
c_array[i] = Double_field(array, i);
}
trexio_exit_code rc = trexio_write_safe_{group}_{element}_64(file, c_array, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(c_array);
CAMLreturn ( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "int", "index", "dim" ]:
t = """
CAMLprim value caml_read_safe_{group}_{element}(value file_in, value size_max_in)
{
CAMLparam2 ( file_in, size_max_in );
CAMLlocal1 ( result );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int64_t* read_data = (int64_t*) malloc (size_max * sizeof(int64_t));
trexio_exit_code rc = trexio_read_safe_{group}_{element}_64(file, read_data, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(size_max, 0);
for (size_t i=0 ; i<size_max ; ++i) {
Store_field( result, i, Val_int(read_data[i]) );
}
free(read_data);
CAMLreturn (result);
}
CAMLprim value caml_write_safe_{group}_{element}(value file_in, value size_max_in, value array)
{
CAMLparam3 ( file_in, size_max_in, array );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int64_t* c_array = (int64_t*) malloc (size_max * sizeof(int64_t));
for (size_t i=0 ; i<size_max ; ++i) {
c_array[i] = Int_val( Field(array, i) );
}
trexio_exit_code rc = trexio_write_safe_{group}_{element}_64(file, c_array, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(c_array);
CAMLreturn ( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = """
CAMLprim value caml_read_safe_{group}_{element}(value file_in, value size_max_in, value max_str_len_in)
{
CAMLparam3 ( file_in, size_max_in, max_str_len_in );
CAMLlocal1 ( result );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int32_t max_str_len = Int_val(max_str_len_in);
char** read_data = (char**) malloc (size_max * sizeof(char*));
read_data[0] = (char*) malloc (size_max * (int64_t) (max_str_len+1) * sizeof(char));
for (size_t i=1 ; i<size_max ; ++i) {
read_data[i] = read_data[i-1] + max_str_len+1;
}
trexio_exit_code rc = trexio_read_{group}_{element}(file, read_data, max_str_len);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(size_max, 0);
for (size_t i=0 ; i<size_max ; ++i) {
Store_field( result, i, caml_copy_string(read_data[i]) );
}
free(read_data[0]);
free(read_data);
CAMLreturn (result);
}
CAMLprim value caml_write_safe_{group}_{element}(value file_in, value size_max_in, value max_str_len_in, value array)
{
CAMLparam4 ( file_in, size_max_in, max_str_len_in, array );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int32_t max_str_len = Int_val(max_str_len_in);
char** c_array = (char**) malloc (size_max * sizeof(char*));
c_array[0] = (char*) malloc (size_max * (max_str_len+1) * sizeof(char*));
for (size_t i=1 ; i<size_max ; ++i) {
c_array[i] = c_array[i-1] + max_str_len+1;
}
for (size_t i=0 ; i<size_max ; ++i) {
strcpy(c_array[i], String_val( Field(array, i) ));
}
printf("%d\\n", max_str_len);
fprintf(stderr,"%d\\n", max_str_len);
trexio_exit_code rc = trexio_write_{group}_{element}(file, (const char**) c_array, max_str_len);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(c_array[0]);
free(c_array);
CAMLreturn ( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
if data[group][element][0] in [ "float sparse" ]:
size = len(data[group][element][1])
t = """
CAMLprim value caml_read_{group}_{element}(value file_in, value offset_in, value buffer_size_in)
{
CAMLparam3 ( file_in, offset_in, buffer_size_in );
CAMLlocal2 ( result, data );
trexio_t* file = File_val( file_in );
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Int_val( buffer_size_in );
int64_t size_max = buffer_size;
int32_t* index_sparse_read = (int32_t*) malloc ({size}*size_max*sizeof(int32_t));
double* value_sparse_read = (double*) malloc (size_max*sizeof(double));
trexio_exit_code rc = trexio_read_safe_{group}_{element}(file, offset, &buffer_size,
index_sparse_read, size_max,
value_sparse_read, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(buffer_size, 0);
for (size_t i=0 ; i<buffer_size ; ++i) {
data = caml_alloc_tuple({size}+1);
for (int j=0 ; j<{size} ; ++j) {
Store_field(data, j, Val_int( index_sparse_read[{size}*i+j] ));
}
Store_field(data, {size}, caml_copy_double( value_sparse_read[i] ));
Store_field(result, i, data);
}
free(index_sparse_read);
free(value_sparse_read);
CAMLreturn(result);
}
CAMLprim value caml_write_{group}_{element}(value file_in, value offset_in, value buffer_in)
{
CAMLparam3 ( file_in, offset_in, buffer_in );
CAMLlocal1 ( data );
trexio_t* file = File_val( file_in );
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Wosize_val( buffer_in );
const int64_t size_max = buffer_size;
int32_t* index_sparse_write = (int32_t*) malloc ({size}*size_max*sizeof(int32_t));
double* value_sparse_write = (double*) malloc (size_max*sizeof(double));
for (size_t i=0 ; i<buffer_size ; ++i) {
data = Field(buffer_in, i);
for (int j=0 ; j<{size} ; ++j) {
index_sparse_write[{size}*i+j] = Int_val( Field(data, j) );
}
value_sparse_write[i] = Double_val( Field(data, {size}) );
}
trexio_exit_code rc = trexio_write_safe_{group}_{element}(file, offset, buffer_size,
index_sparse_write, size_max,
value_sparse_write, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(index_sparse_write);
free(value_sparse_write);
CAMLreturn( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{size}", str(size))
.replace("{type}", data[group][element][0]) )
f.write(content_post)
def write_mli(data):
with open("src/"+mli_file,'r') as f:
content = f.readlines()
index = -1
for i, line in enumerate(content):
if line.startswith("(**** ****)"):
index = i
break
content_pre = ''.join(content[:index])
content_post = ''.join(content[index:])
with open("lib/"+mli_file,'w') as f:
f.write(content_pre)
for group in data:
t = "val delete_{group}: trexio_file -> unit\n"
t += "val has_{group}: trexio_file -> bool\n"
f.write( t.replace("{group}",group) )
for element in data[group]:
t = "val has_{group}_{element}: trexio_file -> bool\n"
f.write( t.replace("{group}", group)
.replace("{element}", element) )
# Scalar elements
if data[group][element][1] == []:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "val read_{group}_{element} : trexio_file -> {type}\n" ,
"val write_{group}_{element}: trexio_file -> {type} -> unit\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = [ "val read_{group}_{element} : ?max_str_len:int -> trexio_file -> {type}\n" ,
"val write_{group}_{element}: trexio_file -> {type} -> unit\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "dim readonly" ]:
t = [ "val read_{group}_{element} : trexio_file -> {type}\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0].split()[0]) )
# Arrays
else:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "val read_safe_{group}_{element} : trexio_file -> int -> {type} array\n" ,
"val write_safe_{group}_{element}: trexio_file -> int -> {type} array -> unit\n"
"val read_{group}_{element} : trexio_file -> {type} array\n" ,
"val write_{group}_{element}: trexio_file -> {type} array -> unit\n"
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = [ "val read_safe_{group}_{element} : trexio_file -> int -> int -> {type} array\n" ,
"val write_safe_{group}_{element}: trexio_file -> int -> int -> {type} array -> unit\n"
"val read_{group}_{element} : ?max_str_len:int -> trexio_file -> {type} array\n" ,
"val write_{group}_{element}: trexio_file -> {type} array -> unit\n"
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "float sparse" ]:
size = len(data[group][element][1])
typ = "(" + "*".join( [ "int" for _ in range(size) ]) + " * float) array"
t = [ "val read_{group}_{element} : trexio_file -> offset:dim -> buffer_size:dim -> {type}\n" ,
"val write_{group}_{element} : trexio_file -> offset:dim -> {type} -> unit\n" ,
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", typ) )
f.write(content_post)
def write_ml(data):
with open("src/"+ml_file,'r') as f:
content = f.readlines()
index = -1
for i, line in enumerate(content):
if line.startswith("(**** ****)"):
index = i
break
content_pre = ''.join(content[:index])
content_post = ''.join(content[index:])
with open("lib/"+ml_file,'w') as f:
f.write(content_pre)
for group in data:
t = "external delete_{group}: trexio_file -> unit = \"caml_delete_{group}\"\n"
t += "external has_{group}: trexio_file -> bool = \"caml_has_{group}\"\n"
f.write( t.replace("{group}",group) )
for element in data[group]:
t = "external has_{group}_{element}: trexio_file -> bool = \"caml_has_{group}_{element}\"\n"
f.write( t.replace("{group}", group)
.replace("{element}", element) )
# Scalar elements
if data[group][element][1] == []:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "external read_{group}_{element} : trexio_file -> {type} = \"caml_read_{group}_{element}\"\n" ,
"external write_{group}_{element}: trexio_file -> {type} -> unit = \"caml_write_{group}_{element}\"\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
if data[group][element][0] in [ "string" ]:
t = [ "external read_{group}_{element}_c : trexio_file -> int -> {type} = \"caml_read_{group}_{element}\"\n" ,
"let read_{group}_{element} ?(max_str_len=8192) f = read_{group}_{element}_c f max_str_len\n",
"external write_{group}_{element}: trexio_file -> {type} -> unit = \"caml_write_{group}_{element}\"\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "dim readonly" ]:
t = [ "external read_{group}_{element} : trexio_file -> {type} = \"caml_read_{group}_{element}\"\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0].split()[0]) )
# Arrays
else:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "external read_safe_{group}_{element} : trexio_file -> int -> {type} array = \"caml_read_safe_{group}_{element}\"\n" ,
"external write_safe_{group}_{element}: trexio_file -> int -> {type} array -> unit = \"caml_write_safe_{group}_{element}\"\n",
"let read_{group}_{element} f = \n let size = 1 in \n"]
t_prime = []
for dim in data[group][element][1]:
try: # A dimensioning variable
dim_group, dim_element = dim.split('.')
t_prime += [f" let size = size * read_{dim_group}_{dim_element} f in\n"]
except: # Only an integer
t_prime += [f" let size = size * {dim} in\n"]
t += t_prime
t += [ " read_safe_{group}_{element} f size\n\n" ]
t += [ "let write_{group}_{element} f a = \n let size = 1 in \n"]
t += t_prime
t += [ " write_safe_{group}_{element} f size a\n\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = [ "external read_safe_{group}_{element} : trexio_file -> int -> int -> {type} array = \"caml_read_safe_{group}_{element}\"\n" ,
"external write_safe_{group}_{element}: trexio_file -> int -> int -> {type} array -> unit = \"caml_write_safe_{group}_{element}\"\n",
"let read_{group}_{element} ?(max_str_len=1024) f = \n let size = 1 in \n"]
t_prime = []
for dim in data[group][element][1]:
try: # A dimensioning variable
dim_group, dim_element = dim.split('.')
t_prime += [f" let size = size * read_{dim_group}_{dim_element} f in\n"]
except: # Only an integer
t_prime += [f" let size = size * {dim} in\n"]
t += t_prime
t += [ " read_safe_{group}_{element} f size max_str_len\n\n" ,
"let write_{group}_{element} f a = \n let size = 1 in \n",
" let max_str_len = Array.map String.length a\n" ,
" |> Array.fold_left (fun x y -> if x>y then x else y) 0\n",
" |> (+) 1 in\n" ]
t += t_prime
t += [ " write_safe_{group}_{element} f size max_str_len a\n\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "float sparse" ]:
size = len(data[group][element][1])
typ = "(" + "*".join( [ "int" for _ in range(size) ]) + " * float) array"
t = [ "external read_{group}_{element} : trexio_file -> offset:dim -> buffer_size:dim -> {type} = \"caml_read_{group}_{element}\"\n" ,
"external write_{group}_{element} : trexio_file -> offset:dim -> {type} -> unit = \"caml_write_{group}_{element}\"\n"
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", typ) )
f.write(content_post)
def main():
with open(json_file,'r') as f:
data = json.load(f)
for group in data:
for element in data[group]:
if data[group][element][0] == "str":
data[group][element][0] = "string"
write_ml(data)
write_mli(data)
write_stubs(data)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,37 @@
type trexio_file
type trexio_exit_code = int
type trexio_backend =
| HDF5
| TEXT
| AUTO
type index = int
type dim = int
external open_file : string -> char -> trexio_backend -> trexio_file = "caml_open_file"
external close_file : trexio_file -> unit = "caml_close_file"
external inquire_file : string -> bool = "caml_inquire_file"
external set_one_based : trexio_file -> unit = "caml_set_one_based"
external get_state : trexio_file -> int = "caml_get_state"
external set_state : trexio_file -> int -> unit = "caml_set_state"
external info : unit -> unit = "caml_info"
external to_orbital_list : Int64.t array -> int list = "caml_to_orbital_list"
(**** ****)
external read_determinant_list : trexio_file -> offset:int -> buffer_size:int -> (bytes * bytes) array = "caml_read_determinant_list"
external write_determinant_list : trexio_file -> offset:int -> (bytes * bytes) array -> unit = "caml_write_determinant_list"
external read_determinant_coefficient : trexio_file -> offset:int -> buffer_size:int -> float array = "caml_read_determinant_coefficient"
external write_determinant_coefficient : trexio_file -> offset:int -> float array -> unit = "caml_write_determinant_coefficient"
let to_orbital_list_up_dn (up,dn) =
(to_orbital_list up, to_orbital_list dn)

View File

@ -0,0 +1,41 @@
(*
(** Constants *)
val package_version : string
val version_major : int
val version_minor : int
val version_patch : int
val git_hash : string
*)
(** Open/close *)
type trexio_file
type trexio_exit_code
type trexio_backend =
| HDF5
| TEXT
| AUTO
type index = int
type dim = int
val open_file : string -> char -> trexio_backend -> trexio_file
val inquire_file : string -> bool
val close_file : trexio_file -> unit
val set_one_based : trexio_file -> unit
val get_state : trexio_file -> int
val set_state : trexio_file -> int -> unit
val info : unit -> unit
val to_orbital_list : Int64.t array -> int list
val to_orbital_list_up_dn : (Int64.t array)*(Int64.t array) -> (int list)*(int list)
(**** ****)
val read_determinant_list : trexio_file -> offset:int -> buffer_size:int -> (bytes * bytes) array
val write_determinant_list : trexio_file -> offset:int -> (bytes * bytes) array -> unit
val read_determinant_coefficient : trexio_file -> offset:int -> buffer_size:int -> float array
val write_determinant_coefficient : trexio_file -> offset:int -> float array -> unit

View File

@ -0,0 +1,268 @@
#include <stdio.h>
#include <trexio.h>
#include <string.h>
#define CAML_NAME_SPACE
#include <caml/alloc.h>
#include <caml/custom.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/fail.h>
#include <caml/misc.h>
static trexio_t* File_val( value file )
{
return *((trexio_t**) Data_abstract_val(file));
}
CAMLprim value caml_open_file(value filename, value mode, value backend)
{
CAMLparam3(filename, mode, backend);
trexio_exit_code rc = 0;
value v = caml_alloc(1, Abstract_tag);
trexio_t* result = trexio_open (String_val(filename),
Int_val(mode),
Int_val(backend),
&rc);
*((trexio_t **) Data_abstract_val(v)) = result;
if (rc == TREXIO_SUCCESS) {
CAMLreturn( v );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_close_file(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_close( File_val(file) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_inquire_file(value filename)
{
CAMLparam1 (filename);
trexio_exit_code rc = trexio_inquire( String_val (filename) );
CAMLreturn(Val_bool(rc == TREXIO_SUCCESS));
}
CAMLprim value caml_set_one_based(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_set_one_based( File_val(file) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_set_state(value file, value state)
{
CAMLparam2(file, state);
printf("%d\n", Int_val(state));
trexio_exit_code rc = trexio_set_state( File_val(file), (int32_t) Int_val(state) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_get_state(value file)
{
CAMLparam1(file);
int32_t result;
trexio_exit_code rc = trexio_get_state( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_int(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_info(value unit)
{
CAMLparam1(unit);
trexio_exit_code rc = trexio_info();
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_to_orbital_list(value bitfield)
{
CAMLparam1 ( bitfield );
CAMLlocal2 ( result, cons );
int32_t N_int = Wosize_val(bitfield);
bitfield_t* d1 = (bitfield_t*) malloc (N_int * sizeof(bitfield_t));
for (int i=0 ; i<N_int ; ++i) {
d1[i] = Int64_val(Field(bitfield,i));
}
int32_t* list = (int32_t*) malloc(N_int * sizeof(bitfield_t) * sizeof(int32_t));
int32_t occupied_num = 0;
trexio_exit_code rc = trexio_to_orbital_list (N_int, d1, list, &occupied_num);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(d1);
result = Val_emptylist;
for (int i=occupied_num-1 ; i >= 0 ; --i) {
cons = caml_alloc(2, 0);
Store_field(cons, 0, Val_int(list[i])); // head
Store_field(cons, 1, result); // head
result = cons;
}
free(list);
CAMLreturn(result);
}
/**** ****/
CAMLprim value caml_read_determinant_list(value file_in, value offset_in, value buffer_size_in)
{
CAMLparam3 ( file_in, offset_in, buffer_size_in );
CAMLlocal4 ( result, detup, detdn, det );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Int_val( buffer_size_in );
int32_t int_num = 0;
trexio_exit_code rc = trexio_get_int64_num(file, &int_num);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
int64_t* buffer = (int64_t*) malloc ( buffer_size * int_num * 2 * sizeof(int64_t) );
rc = trexio_read_determinant_list (file, offset, &buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(buffer_size, 0);
size_t icount = 0;
for (size_t i=0 ; i<buffer_size ; ++i) {
detup = caml_alloc_initialized_string(int_num*sizeof(int64_t), (char*) &(buffer[icount]));
icount += int_num;
detdn = caml_alloc_initialized_string(int_num*sizeof(int64_t), (char*) &(buffer[icount]));
icount += int_num;
det = caml_alloc_tuple(2);
Store_field( det, 0, detup );
Store_field( det, 1, detdn );
Store_field( result, i, det );
}
free(buffer);
CAMLreturn(result);
}
CAMLprim value caml_write_determinant_list(value file_in, value offset_in, value array)
{
CAMLparam3 ( file_in, offset_in, array );
CAMLlocal3 ( detup, detdn, det );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Wosize_val( array );
int32_t int_num = 0;
trexio_exit_code rc = trexio_get_int64_num(file, &int_num);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
int64_t* buffer = (int64_t*) malloc ( buffer_size * int_num * 2 * sizeof(int64_t) );
for (size_t i=0 ; i<buffer_size ; ++i) {
det = Field(array, i);
detup = Field(det, 0);
detdn = Field(det, 1);
memcpy(&(buffer[i*int_num*2]), String_val(detup), int_num*sizeof(int64_t));
memcpy(&(buffer[i*int_num*2 + int_num]), String_val(detdn), int_num*sizeof(int64_t));
}
rc = trexio_write_determinant_list (file, offset, buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(buffer);
CAMLreturn( Val_unit );
}
CAMLprim value caml_read_determinant_coefficient(value file_in, value offset_in, value buffer_size_in)
{
CAMLparam3 ( file_in, offset_in, buffer_size_in );
CAMLlocal1 ( result );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Int_val( buffer_size_in );
double* buffer = (double*) malloc ( buffer_size * sizeof(double) );
trexio_exit_code rc = trexio_read_determinant_coefficient (file, offset, &buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(buffer_size * Double_wosize, Double_array_tag);
for (size_t i=0 ; i<buffer_size ; ++i) {
Store_double_field( result, i, buffer[i]);
}
free(buffer);
CAMLreturn(result);
}
CAMLprim value caml_write_determinant_coefficient(value file_in, value offset_in, value array)
{
CAMLparam3 ( file_in, offset_in, array );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Wosize_val( array );
double* buffer = (double*) malloc ( buffer_size * sizeof(double) );
for (size_t i=0 ; i<buffer_size ; ++i) {
buffer[i] = Double_field(array, i);
}
trexio_exit_code rc = trexio_write_determinant_coefficient (file, offset, buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(buffer);
CAMLreturn( Val_unit );
}

View File

@ -1,8 +1,9 @@
include src/*.c
include src/trexio*.h
include examples/notebooks/*
include examples/README.md
include src/*.c
include src/trexio*.h
include examples/notebooks/*
include examples/README.md
include requirements.txt tools/set_NUMPY_INCLUDEDIR.sh
include test/benzene_data.py
exclude examples/LICENSE
exclude examples/requirements.txt

View File

@ -12,8 +12,7 @@ can be used to convert data from one input/output file format into another.
## Requirements
- python3 (>= 3.6)
- numpy (>= 1.17.3)
- numpy (>= 1.17.3)
## Installation from PyPI
@ -31,10 +30,11 @@ For more details, see the corresponding part of the [Python documentation](https
## Additional requirements (for installation from source)
- C compiler (gcc/icc/clang)
- C compiler (gcc/icc/clang)
- HDF5 library (>= 1.8)
- pkgconfig (Python package)
- build (Python package)
- pytest (Python package)
## Installation from source
@ -44,10 +44,10 @@ For more details, see the corresponding part of the [Python documentation](https
4. `pip install -r requirements.txt` (this installs all required python dependencies)
5. Export custom environment variables needed for the installation following the procedure below and replacing `/path/to/hdf5/` with your paths.
The following two steps can be skipped if HDF5 is properly configured for `pkg-config` (i.e. if executing `pkg-config --libs hdf5` returns a list of options).
1. `export H5_CFLAGS=-I/path/to/hdf5/include`
2. `export H5_LDFLAGS=-L/path/to/hdf5/lib`
- `export H5_CFLAGS=-I/path/to/hdf5/include`
- `export H5_LDFLAGS=-L/path/to/hdf5/lib`
6. `pip install .` (this installs `trexio` in your environment)
7. `cd test && python test_api.py` (this executes several tests that verify the installation)
7. `cd test && python -m pytest -v test_api.py` (this executes several tests that verify the installation)
You are ready to go!

View File

@ -82,11 +82,14 @@ function build_wheel_for_py()
# install the produced manylinux wheel in the virtual environment
python3 -m pip install wheelhouse/trexio-${TR_VERSION}-${CPYTHON}-manylinux*.whl
# install pytest for testing
pip install pytest
# run test script
cd test && python3 test_api.py && cd ..
pytest -v test/test_api.py
# cleaning
rm -rf -- dist/ build/ trexio.egg-info/
rm -rf -- dist/ build/ trexio.egg-info/
rm -- test_file_py.h5 unsafe_test_file_py.h5
# deactivate the current environment
deactivate

View File

@ -28,6 +28,7 @@ fi
# Install/upgrade packages required for the installation
python3 -m pip install --upgrade setuptools build pip
python3 -m pip install -r requirements.txt
python3 -m pip install pytest
# export NUMPY_INCLUDEDIR environment variable needed for the proper setup
#source tools/set_NUMPY_INCLUDEDIR.sh

View File

@ -1 +1 @@
__version__ = "1.2.0"
__version__ = "1.3.0"

View File

@ -9,7 +9,7 @@ from setuptools import setup, Extension
def parse_setuppy_commands():
"""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.
"""
args = sys.argv[1:]
@ -93,7 +93,12 @@ pytrexio_module = Extension('pytrexio._pytrexio',
sources = [os.path.join(srcpath, code) for code in c_files],
include_dirs = [h5_cflags, srcpath, numpy_includedir],
libraries = ['hdf5', 'hdf5_hl'],
extra_compile_args = ['-Wno-discarded-qualifiers'],
extra_compile_args = [
'-std=c99',
'-Wno-discarded-qualifiers',
'-Wno-unused-variable',
'-Wno-unused-but-set-variable'
],
extra_link_args = [h5_ldflags]
)

View File

@ -0,0 +1,49 @@
# for the nucleus group
nucleus_num = 12
point_group = 'D6h'
nucleus_label = ['C', 'C', 'C', 'C', 'C', 'C', 'H', 'H', 'H', 'H', 'H', 'H']
nucleus_charge = [6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.]
nucleus_coord = [
[ 0.00000000 , 1.39250319 , 0.00000000 ],
[-1.20594314 , 0.69625160 , 0.00000000 ],
[-1.20594314 , -0.69625160 , 0.00000000 ],
[ 0.00000000 , -1.39250319 , 0.00000000 ],
[ 1.20594314 , -0.69625160 , 0.00000000 ],
[ 1.20594314 , 0.69625160 , 0.00000000 ],
[-2.14171677 , 1.23652075 , 0.00000000 ],
[-2.14171677 , -1.23652075 , 0.00000000 ],
[ 0.00000000 , -2.47304151 , 0.00000000 ],
[ 2.14171677 , -1.23652075 , 0.00000000 ],
[ 2.14171677 , 1.23652075 , 0.00000000 ],
[ 0.00000000 , 2.47304151 , 0.00000000 ],
]
# for the basis_nucleus_index
basis_shell_num = 24
nucleus_index = [i for i in range(basis_shell_num)]
# for sparse AO_INT_2E
ao_num = 600
# prepare the sparse data representation
num_integrals = 100
indices = [i for i in range(num_integrals*4)]
values = [(3.14 + float(i)) for i in range(num_integrals)]
# for determinants
mo_num = 150
int64_num = int((mo_num - 1)/64 + 1)
# prepate the CI data
det_num = 2000
dets = [i for i in range(det_num * int64_num * 2)]
coeffs = [float(i/det_num) for i in range(det_num)]
coeffs_s2 = [float(i*2/det_num) for i in range(det_num)]
det_test = [1, 2, 3, 2, 1, 3]
orb_up_test = [0, 65, 128, 129]
orb_dn_test = [1, 64, 128, 129]

View File

@ -1,325 +1,337 @@
#!/usr/bin/env python3
import os
import shutil
import numpy as np
import pytest
import trexio
from benzene_data import *
#=========================================================#
#======== SETUP THE BACK END AND OUTPUT FILE NAME ========#
#=========================================================#
# 0: TREXIO_HDF5 ; 1: TREXIO_TEXT
TEST_TREXIO_BACKEND = 0
OUTPUT_FILENAME_TEXT = 'test_py_swig.dir'
OUTPUT_FILENAME_HDF5 = 'test_py_swig.h5'
# define TREXIO file name
if TEST_TREXIO_BACKEND == trexio.TREXIO_HDF5:
output_filename = OUTPUT_FILENAME_HDF5
elif TEST_TREXIO_BACKEND == trexio.TREXIO_TEXT:
output_filename = OUTPUT_FILENAME_TEXT
else:
raise ValueError ('Specify one of the supported back ends as TEST_TREXIO_BACKEND')
# remove TREXIO file if exists in the current directory
try:
if TEST_TREXIO_BACKEND == trexio.TREXIO_HDF5:
os.remove(output_filename)
elif TEST_TREXIO_BACKEND == trexio.TREXIO_TEXT:
shutil.rmtree(output_filename)
except:
print('Nothing to remove.')
#=========================================================#
#============ WRITE THE DATA IN THE TEST FILE ============#
#=========================================================#
FILENAME = 'test_file_py.h5'
BACK_END = trexio.TREXIO_HDF5
trexio.info()
def clean():
"""Remove test files."""
import os
# test with ... as ... block
with trexio.File(output_filename, mode='w', back_end=TEST_TREXIO_BACKEND) as tfile:
trexio.write_metadata_description(tfile, "Test file produced by the Python API")
assert trexio.has_metadata_description(tfile)
assert tfile.isOpen
# the file handle can remain existing but the file itself is closed upon exit from the `with` block
assert not tfile.isOpen
# create TREXIO file and open it for writing
test_file = trexio.File(output_filename, mode='w', back_end=TEST_TREXIO_BACKEND)
assert test_file.exists
# Print docstring of the trexio.open function
#print(trexio.open.__doc__)
nucleus_num = 12
try:
trexio.write_nucleus_num(test_file, -100)
except trexio.Error:
print("Raise error for an attempt to write negative nucleus_num: checked.")
# write nucleus_num in the file
try:
trexio.write_nucleus_num(test_file, nucleus_num)
except:
raise
try:
trexio.write_nucleus_num(test_file, nucleus_num*2)
except trexio.Error:
print("Raise error for an attempt to overwrite nucleus_num: checked.")
try:
os.remove(FILENAME)
os.remove('unsafe_' + FILENAME)
except FileNotFoundError:
pass
# initialize charge arrays as a list and convert it to numpy array
charges = [6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.]
#charges_np = np.array(charges, dtype=np.float32)
charges_np = np.array(charges, dtype=np.int32)
# function call below works with both lists and numpy arrays, dimension needed for memory-safety is derived
# from the size of the list/array by SWIG using typemaps from numpy.i
trexio.write_nucleus_charge(test_file, charges_np)
basis_shell_num = 24
# initialize arrays of nuclear indices as a list and convert it to numpy array
indices = [i for i in range(basis_shell_num)]
# type cast is important here because by default numpy transforms a list of integers into int64 array
indices_np = np.array(indices, dtype=np.int64)
# first write basis_shell_num because it is needed to check dimensions of basis_nucleus_index in TREXIO >= 2.0.0
trexio.write_basis_shell_num(test_file, basis_shell_num)
# function call below works with both lists and numpy arrays, dimension needed for memory-safety is derived
# from the size of the list/array by SWIG using typemacs from numpy.i
trexio.write_basis_nucleus_index(test_file, indices_np)
# initialize a list of nuclear coordinates
coords = [
[ 0.00000000 , 1.39250319 , 0.00000000 ],
[-1.20594314 , 0.69625160 , 0.00000000 ],
[-1.20594314 , -0.69625160 , 0.00000000 ],
[ 0.00000000 , -1.39250319 , 0.00000000 ],
[ 1.20594314 , -0.69625160 , 0.00000000 ],
[ 1.20594314 , 0.69625160 , 0.00000000 ],
[-2.14171677 , 1.23652075 , 0.00000000 ],
[-2.14171677 , -1.23652075 , 0.00000000 ],
[ 0.00000000 , -2.47304151 , 0.00000000 ],
[ 2.14171677 , -1.23652075 , 0.00000000 ],
[ 2.14171677 , 1.23652075 , 0.00000000 ],
[ 0.00000000 , 2.47304151 , 0.00000000 ],
]
# write coordinates in the file
trexio.write_nucleus_coord(test_file, coords)
# write mo_num (needed later to write sparse mo_2e_int_eri integrals)
trexio.write_mo_num(test_file, 600)
# write sparse data in the file
num_integrals = 100
indices = [i for i in range(num_integrals*4)]
values = [(3.14 + float(i)) for i in range(num_integrals)]
trexio.write_mo_2e_int_eri(test_file, 0, num_integrals, indices, values)
# write nucleus_point_group in the file
point_group = 'B3U'
trexio.write_nucleus_point_group(test_file, point_group)
# write nucleus_label in the file
labels = [
'C',
'C',
'C',
'C',
'C',
'C',
'H',
'H',
'H',
'H',
'H',
'H']
trexio.write_nucleus_label(test_file,labels)
# close TREXIO file
# this call is no longer needed as we introduced TREXIO_File class which has a desctructor that closes the file
#trexio.close(test_file)
# without calling destructor on test_file the TREXIO_FILE is not getting created and the data is not written when using TEXT back end.
# This, the user still has to explicitly call destructor on test_file object instead of the trexio.close function.
# This is only an issue when the data is getting written and read in the same session (e.g. in Jupyter notebook)
del test_file
#==========================================================#
#========== DELETE THE GROUP FROM THE TEST FILE ===========#
#==========================================================#
unsafe_file = trexio.File(output_filename, 'u', TEST_TREXIO_BACKEND)
# overwrite existing data (only allowed in 'u' - unsafe mode)
trexio.write_nucleus_num(unsafe_file, nucleus_num)
trexio.write_nucleus_charge(unsafe_file, charges_np)
trexio.write_nucleus_coord(unsafe_file, coords)
trexio.write_nucleus_label(unsafe_file,labels)
trexio.write_nucleus_point_group(unsafe_file, point_group)
print("Overwriting the data in UNSAFE mode: checked")
# delete existing group (only allowed in 'u' - unsafe mode)
trexio.delete_nucleus(unsafe_file)
assert not trexio.has_nucleus_num(unsafe_file)
assert not trexio.has_nucleus_charge(unsafe_file)
assert not trexio.has_nucleus_coord(unsafe_file)
assert not trexio.has_nucleus_label(unsafe_file)
assert not trexio.has_nucleus_point_group(unsafe_file)
print("Deleting nucleus group in UNSAFE mode: checked")
# restore the deleted data
trexio.write_nucleus_num(unsafe_file, nucleus_num)
trexio.write_nucleus_charge(unsafe_file, charges_np)
trexio.write_nucleus_coord(unsafe_file, coords)
trexio.write_nucleus_label(unsafe_file,labels)
trexio.write_nucleus_point_group(unsafe_file, point_group)
del unsafe_file
#==========================================================#
#============ READ THE DATA FROM THE TEST FILE ============#
#==========================================================#
# open previously created TREXIO file, now in 'read' mode
test_file2 = trexio.File(output_filename, 'r', trexio.TREXIO_AUTO)
assert test_file2.exists
# check for existence of some of the previously written variables
assert trexio.has_nucleus_num(test_file2)
assert trexio.has_nucleus_charge(test_file2)
assert trexio.has_nucleus_coord(test_file2)
assert trexio.has_nucleus_label(test_file2)
assert trexio.has_nucleus_point_group(test_file2)
assert trexio.has_mo_2e_int_eri(test_file2)
# read nucleus_num from file
rnum = trexio.read_nucleus_num(test_file2)
assert rnum==nucleus_num
# safe call to read_nucleus_charge array of float values
rcharges_np = trexio.read_nucleus_charge(test_file2, dim=nucleus_num)
assert rcharges_np.dtype is np.dtype(np.float64)
np.testing.assert_array_almost_equal(rcharges_np, charges_np, decimal=8)
# unsafe call to read_safe should fail with error message corresponding to TREXIO_UNSAFE_ARRAY_DIM
try:
rcharges_fail = trexio.read_nucleus_charge(test_file2, dim=nucleus_num*5)
except trexio.Error:
print("Unsafe call to safe API: checked")
# safe call to read array of int values (nuclear indices)
rindices_np_16 = trexio.read_basis_nucleus_index(test_file2, dim=basis_shell_num, dtype=np.int16)
assert rindices_np_16.dtype is np.dtype(np.int16)
for i in range(basis_shell_num):
assert rindices_np_16[i]==indices_np[i]
rindices_np_32 = trexio.read_basis_nucleus_index(test_file2, dim=basis_shell_num, dtype=np.int32)
assert rindices_np_32.dtype is np.dtype(np.int32)
for i in range(basis_shell_num):
assert rindices_np_32[i]==indices_np[i]
rindices_np_64 = trexio.read_basis_nucleus_index(test_file2)
assert rindices_np_64.dtype is np.dtype(np.int64)
assert rindices_np_64.size==basis_shell_num
for i in range(basis_shell_num):
assert rindices_np_64[i]==indices_np[i]
# read nuclear coordinates without providing optional argument dim
rcoords_np = trexio.read_nucleus_coord(test_file2)
assert rcoords_np.size==nucleus_num*3
np.testing.assert_array_almost_equal(rcoords_np, np.array(coords).reshape(nucleus_num,3), decimal=8)
# set doReshape to False to get a flat 1D array (e.g. when reading matrices like nuclear coordinates)
#rcoords_reshaped_2 = trexio.read_nucleus_coord(test_file2, doReshape=False)
# read number of integrals already present in the file
assert trexio.has_mo_2e_int_eri(test_file2)
assert trexio.read_mo_2e_int_eri_size(test_file2)==num_integrals
# read sparse arrays on mo_2e_int_eri integrals
buf_size = 60
offset_file = 0
# 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)
print(f'First complete sparse read size: {read_buf_size}')
#print(indices_sparse_np)
assert not eof
assert read_buf_size==buf_size
assert indices_sparse_np[0][0]==0
assert indices_sparse_np[read_buf_size-1][3]==read_buf_size*4-1
offset_file += buf_size
# 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)
print(f'Second incomplete sparse read size: {read_buf_size}')
#print(indices_sparse_np)
assert eof2
assert read_buf_size==(num_integrals - buf_size)
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
# read array of nuclear labels
rlabels_2d = trexio.read_nucleus_label(test_file2, dim=nucleus_num)
print(rlabels_2d)
for i in range(nucleus_num):
assert rlabels_2d[i]==labels[i]
# read a string corresponding to nuclear point group
rpoint_group = trexio.read_nucleus_point_group(test_file2)
assert rpoint_group==point_group
# another way to read only if the variable exists
if trexio.has_ao_num(test_file2):
rao_num = trexio.read_ao_num(test_file2)
else:
print("Pass on reading the non-existing variable ao_num: checked")
# close TREXIO file
#trexio.close(test_file2)
# cleaning (remove the TREXIO file)
try:
if TEST_TREXIO_BACKEND == trexio.TREXIO_HDF5:
os.remove(output_filename)
elif TEST_TREXIO_BACKEND == trexio.TREXIO_TEXT:
shutil.rmtree(output_filename)
except:
print(f'No output file {output_filename} has been produced')
#==========================================================#
#==========================================================#
#======= OPEN NON-EXISTING FILE TO TEST TREXIO.OPEN =======#
#==========================================================#
try:
void_file = trexio.File('non_existing.file', 'r', TEST_TREXIO_BACKEND)
except trexio.Error as e:
if e.error == trexio.TREXIO_OPEN_ERROR:
print("Opening non-existing file returns TREXIO_OPEN_ERROR: checked")
else:
raise ValueError("[DEV]: error handling of trexio_open function has changed; check the consistency")
#==========================================================#
def test_info():
"""Print the output of the trexio.info function."""
trexio.info()
def test_void():
"""Check raise of an error upon I/O on non-existing file."""
with pytest.raises(trexio.Error):
_ = trexio.File('void.file', 'r', BACK_END)
def test_orbital_list():
"""Convert one determinant into a list of orbitals."""
orb_list_up, orb_list_dn = trexio.to_orbital_list_up_dn(int64_num, det_test)
assert orb_list_up[0] == 0
assert orb_list_dn[0] == 1
def test_bitfield_list():
"""Convert lists of occupied up- and down-spin orbitals into determinants."""
# convert det_test list into a numpy array for .all() assertion to work
det_test_np = np.array(det_test, dtype=np.int64)
det_list_up = trexio.to_bitfield_list(int64_num, orb_up_test)
assert (det_list_up == det_test_np[:int64_num]).all()
det_list_dn = trexio.to_bitfield_list(int64_num, orb_dn_test)
assert (det_list_dn == det_test_np[int64_num:]).all()
class TestIO:
"""Unit tests for writing/reading different blocks of the TREXIO file."""
filename = FILENAME
back_end = BACK_END
mode = 'w'
test_file = None
clean()
def __del__(self):
if self.test_file:
if self.test_file.isOpen:
self.test_file.close()
def open(self, filename=None, mode=None, back_end=None):
"""Create a TREXIO file and open it for writing."""
if not filename:
filename = self.filename
else:
self.filename = filename
if not mode:
mode = self.mode
else:
self.mode = mode
if not back_end:
back_end = self.back_end
else:
self.back_end = back_end
self.test_file = trexio.File(filename, mode, back_end)
assert self.test_file.exists
def test_close(self):
"""Close the file."""
self.open()
if self.test_file.isOpen:
self.test_file.close()
assert not self.test_file.isOpen
def test_errors(self):
"""Test some exceptions based on trexio.Error class."""
self.open(filename='unsafe_' + self.filename, mode='w', back_end=self.back_end)
# try to write a negative number (should raise an error)
with pytest.raises(trexio.Error):
trexio.write_nucleus_num(self.test_file, -100)
trexio.write_nucleus_num(self.test_file, nucleus_num)
# try to overwrite a number (should raise an error)
with pytest.raises(trexio.Error):
trexio.write_nucleus_num(self.test_file, nucleus_num * 2)
def test_num(self):
"""Write a number."""
self.open()
trexio.write_nucleus_num(self.test_file, nucleus_num)
assert trexio.has_nucleus_num(self.test_file)
def test_str(self):
"""Write a string."""
self.open()
trexio.write_nucleus_point_group(self.test_file, point_group)
assert trexio.has_nucleus_point_group(self.test_file)
def test_array_str(self):
"""Write an array of strings."""
self.open()
if not trexio.has_nucleus_num(self.test_file):
self.test_num()
trexio.write_nucleus_label(self.test_file, nucleus_label)
assert trexio.has_nucleus_label(self.test_file)
def test_array_1D(self):
"""Write array of charges."""
self.open()
if not trexio.has_nucleus_num(self.test_file):
self.test_num()
trexio.write_nucleus_charge(self.test_file, nucleus_charge)
assert trexio.has_nucleus_charge(self.test_file)
def test_array_2D(self):
"""Write array of coordinates."""
self.open()
if not trexio.has_nucleus_num(self.test_file):
self.test_num()
trexio.write_nucleus_coord(self.test_file, nucleus_coord)
assert trexio.has_nucleus_coord(self.test_file)
def test_indices(self):
"""Write array of indices."""
self.open()
# type cast is important here because by default numpy transforms a list of integers into int64 array
indices_np = np.array(nucleus_index, dtype=np.int64)
# first write basis_shell_num because it is needed to check dimensions of basis_nucleus_index
trexio.write_basis_shell_num(self.test_file, basis_shell_num)
# now write the indices
trexio.write_basis_nucleus_index(self.test_file, indices_np)
assert trexio.has_basis_nucleus_index(self.test_file)
def test_sparse(self):
"""Write a sparse array."""
self.open()
# write ao_num (needed later to write sparse ao_2e_int_eri integrals)
trexio.write_ao_num(self.test_file, ao_num)
# one complete write (no chunking)
offset = 0
trexio.write_ao_2e_int_eri(self.test_file, offset, num_integrals, indices, values)
assert trexio.has_ao_2e_int_eri(self.test_file)
def test_determinant(self):
"""Write CI determinants and coefficients."""
self.open()
# write mo_num (needed later to write determinants)
trexio.write_mo_num(self.test_file, mo_num)
# get the number of bit-strings per spin component
int_num = trexio.get_int64_num(self.test_file)
assert int_num == int64_num
# write the data for the ground state
offset = 0
trexio.write_state_id(self.test_file, 0)
trexio.write_determinant_list(self.test_file, offset, det_num, dets)
assert trexio.has_determinant_list(self.test_file)
trexio.write_determinant_coefficient(self.test_file, offset, det_num, coeffs)
assert trexio.has_determinant_coefficient(self.test_file)
# manually check the consistency between coefficient_size and number of determinants
assert trexio.read_determinant_coefficient_size(self.test_file) == trexio.read_determinant_num(self.test_file)
def test_delete_group(self):
"""Delete a group."""
self.open(filename='unsafe_' + self.filename, mode='u', back_end=self.back_end)
self.test_num()
self.test_array_1D()
self.test_array_2D()
assert trexio.has_nucleus(self.test_file)
trexio.delete_nucleus(self.test_file)
assert not trexio.has_nucleus_num(self.test_file)
assert not trexio.has_nucleus_charge(self.test_file)
assert not trexio.has_nucleus_coord(self.test_file)
assert not trexio.has_nucleus(self.test_file)
def test_has_group(self):
"""Check existense of a group."""
self.open()
assert trexio.has_nucleus(self.test_file)
assert not trexio.has_rdm(self.test_file)
def test_context_manager(self):
"""Test the with ... as ... context handling."""
with trexio.File(filename=self.filename, mode='u', back_end=self.back_end) as tfile:
trexio.write_metadata_description(tfile, 'Test file produced by the Python API')
assert trexio.has_metadata_description(tfile)
assert tfile.isOpen
# the file handle can remain existing but the file itself is closed upon exit from the `with` block
assert not tfile.isOpen
def test_read_num(self):
"""Read a number."""
self.open(mode='r')
num_r = trexio.read_nucleus_num(self.test_file)
assert num_r == nucleus_num
def test_read_array_1D(self):
"""Read an array."""
self.open(mode='r')
charges_np_r = trexio.read_nucleus_charge(self.test_file)
assert charges_np_r.dtype is np.dtype(np.float64)
assert charges_np_r.size == nucleus_num
np.testing.assert_array_almost_equal(charges_np_r, np.array(nucleus_charge), decimal=8)
def test_read_array_2D(self):
"""Read an array."""
self.open(mode='r')
# read nuclear coordinates without providing optional argument dim
coords_np = trexio.read_nucleus_coord(self.test_file)
assert coords_np.dtype is np.dtype(np.float64)
assert coords_np.size == nucleus_num * 3
np.testing.assert_array_almost_equal(coords_np, np.array(nucleus_coord).reshape(nucleus_num,3), decimal=8)
def test_read_errors(self):
"""Test some reading errors."""
self.open(mode='r')
# unsafe call to read_safe should fail with error message corresponding to TREXIO_UNSAFE_ARRAY_DIM
with pytest.raises(trexio.Error):
_ = trexio.read_nucleus_charge(self.test_file, dim=nucleus_num/2)
def test_read_integers(self):
"""Read some integer arrays."""
self.open(mode='r')
indices_np_16 = trexio.read_basis_nucleus_index(self.test_file, dtype=np.int16)
assert indices_np_16.dtype is np.dtype(np.int16)
assert (indices_np_16 == np.array(nucleus_index)).all()
indices_np_32 = trexio.read_basis_nucleus_index(self.test_file, dtype=np.int32)
assert indices_np_32.dtype is np.dtype(np.int32)
assert (indices_np_32 == np.array(nucleus_index)).all()
indices_np_64 = trexio.read_basis_nucleus_index(self.test_file)
assert indices_np_64.dtype is np.dtype(np.int64)
assert indices_np_64.size == basis_shell_num
assert (indices_np_64 == np.array(nucleus_index)).all()
def test_sparse_read(self):
"""Read a sparse array."""
self.open(mode='r')
# read sparse arrays on ao_2e_int_eri integrals
buf_size = 60
offset_file = 0
# 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_ao_2e_int_eri(self.test_file, offset_file, buf_size)
#print(f'First complete sparse read size: {read_buf_size}')
assert not eof
assert read_buf_size == buf_size
assert indices_sparse_np[0][0] == 0
assert indices_sparse_np[read_buf_size-1][3] == read_buf_size * 4 - 1
offset_file += buf_size
# read incomplete buf_size (i.e. the one that does reach EOF)
indices_sparse_np, value_sparse_np, read_buf_size, eof = trexio.read_ao_2e_int_eri(self.test_file, offset_file, buf_size)
#print(f'Second incomplete sparse read size: {read_buf_size}')
assert eof
assert read_buf_size == (num_integrals - buf_size)
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
def test_determinant_read(self):
"""Read the CI determinants."""
self.open(mode='r')
# read determinants (list of ints and float coefficients)
buf_size = 100
offset_file = 0
# read full buf_size (i.e. the one that does not reach EOF)
dets_np, read_buf_size, eof = trexio.read_determinant_list(self.test_file, offset_file, buf_size)
#print(f'First complete read of determinant list: {read_buf_size}')
assert not eof
assert read_buf_size == buf_size
assert dets_np[0][0] == 0
assert dets_np[read_buf_size-1][int64_num*2-1] == read_buf_size * int64_num * 2- 1
coefficients_np, read_buf_size, eof = trexio.read_determinant_coefficient(self.test_file, offset_file, buf_size)
#print(f'First complete read of determinant coefficients: {read_buf_size}')
assert not eof
assert read_buf_size == buf_size
def test_array_str_read(self):
"""Read an array of strings."""
self.open(mode='r')
labels_r = trexio.read_nucleus_label(self.test_file)
assert len(labels_r) == nucleus_num
assert labels_r == nucleus_label
def test_str_read(self):
"""Read a string."""
self.open(mode='r')
point_group_r = trexio.read_nucleus_point_group(self.test_file)
assert point_group_r == point_group

View File

@ -36,6 +36,10 @@
/* Return num variables as part of the output tuple */
%apply int *OUTPUT { int32_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 { double* const num};
/* 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(int32_t, NPY_INT32, 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 */
%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)};
@ -93,6 +98,15 @@ import_array();
%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)};
/* 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)};
%apply (int32_t* IN_ARRAY1, int32_t DIM1) {(const int32_t* orb_list, const int32_t occupied_num)};
/* For some reasons SWIG does not apply the proper bitfield_t typemap, so one has to manually specify int64_t* ARGOUT_ARRAY1 below */
%apply (int64_t* ARGOUT_ARRAY1, int32_t DIM1) {(bitfield_t* const bit_list, const int32_t N_int)};
/* 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.

View File

@ -38,9 +38,18 @@ echo "" >> trexio_f.f90
# c front end
cat populated/pop_*.c >> trexio.c
cat populated/pop_*.h >> trexio.h
# add determinant part
cat hrw_determinant_front.h >> trexio.h
cat *_determinant_front.c >> trexio.c
# private API header file
cat populated/private_pop_front.h >> trexio_private.h
echo "#endif" >> trexio_private.h
# fortran front end
cat populated/pop_*.f90 >> trexio_f.f90
# add determinant part
cat *_determinant_front_fortran.f90 >> trexio_f.f90
# add helper functions
cat helper_fortran.f90 >> trexio_f.f90
cat populated/pop_*.fh_90 >> trexio_f.f90
@ -48,6 +57,7 @@ cat populated/pop_*.fh_90 >> trexio_f.f90
# python front end
cat basic_python.py >> trexio.py
cat populated/pop_*.py >> trexio.py
cat *_determinant_front.py >> trexio.py
# suffixes
cat suffix_s_front.h >> trexio_s.h

File diff suppressed because it is too large Load Diff

View File

@ -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_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 suffix_hdf5.h >> trexio_hdf5.h

View File

@ -60,6 +60,11 @@
* Template for HDF5 structures
Polymorphism of the ~trexio_t~ type is handled by ensuring that the
corresponding types for all back ends can be safely casted to
~trexio_t~. This is done by making the back-end structs start with
~trexio_t parent~ attribute:
#+begin_src c :tangle struct_hdf5.h
typedef struct trexio_hdf5_s {
trexio_t parent ;
@ -74,6 +79,21 @@ typedef struct trexio_hdf5_s {
trexio_exit_code trexio_hdf5_init(trexio_t* const file);
trexio_exit_code trexio_hdf5_deinit(trexio_t* const file);
trexio_exit_code trexio_hdf5_inquire(const char* file_name);
trexio_exit_code trexio_hdf5_flush(trexio_t* const file);
#+end_src
#+begin_src c :tangle basic_hdf5.c
trexio_exit_code
trexio_hdf5_flush(trexio_t* const file)
{
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
herr_t rc = H5Fflush(f->file_id, H5F_SCOPE_GLOBAL);
if (rc < 0) return TREXIO_FAILURE;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle basic_hdf5.c
@ -174,6 +194,38 @@ trexio_hdf5_deinit (trexio_t* const file)
}
#+end_src
* Template for HDF5 has a group
#+begin_src c :tangle hrw_group_hdf5.h :exports none
trexio_exit_code trexio_hdf5_has_$group$ (trexio_t* const file);
#+end_src
#+begin_src c :tangle has_group_hdf5.c
trexio_exit_code
trexio_hdf5_has_$group$ (trexio_t* const file)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
struct H5G_info_t group_info;
/* H5Gget_info return info about the HDF5 group as a group_info struct */
herr_t status = H5Gget_info(f->$group$_group, &group_info);
if (status < 0) return TREXIO_FAILURE;
/* If nlinks==0 --> the group is empty, i.e. non-existent */
if (group_info.nlinks == (hsize_t) 0) {
return TREXIO_HAS_NOT;
} else {
return TREXIO_SUCCESS;
}
}
#+end_src
* Template for HDF5 has/read/write a numerical attribute
#+begin_src c :tangle hrw_attr_num_hdf5.h :exports none
@ -265,6 +317,7 @@ trexio_hdf5_has_$group_num$ (trexio_t* const file)
if (file == NULL) return TREXIO_INVALID_ARG_1;
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);
/* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */
@ -399,6 +452,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
if (file == NULL) return TREXIO_INVALID_ARG_1;
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);
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
@ -441,7 +495,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
hid_t index_dtype;
const void* index_p;
void* index_p = NULL;
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) */
if (size_max < UINT8_MAX) {
@ -461,7 +515,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
index_p = index;
index_dtype = H5T_NATIVE_UINT16;
} else {
index_p = (const int32_t*) index_sparse;
index_p = (int32_t*) index_sparse;
index_dtype = H5T_NATIVE_INT32;
}
@ -546,11 +600,11 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file,
trexio_exit_code rc_read;
// 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;
// attempt to read values
// 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;
return rc_read;
@ -564,6 +618,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;
@ -600,6 +655,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
if (file == NULL) return TREXIO_INVALID_ARG_1;
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");
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
@ -614,6 +670,141 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
}
#+end_src
* Template for HDF5 has/read/write a dataset of buffered vectors
Chunked I/O in HDF5 for ~buffered~ data.
#+begin_src c :tangle hrw_buffered_hdf5.h :exports none
trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file);
trexio_exit_code trexio_hdf5_read_$group_dset$(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 dset);
trexio_exit_code trexio_hdf5_write_$group_dset$(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, const double* dset);
trexio_exit_code trexio_hdf5_read_$group_dset$_size(trexio_t* const file, int64_t* const size_max);
#+end_src
#+begin_src c :tangle read_buffered_hdf5.c
trexio_exit_code trexio_hdf5_read_$group_dset$(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 dset)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5;
if (dset == NULL) return TREXIO_INVALID_ARG_6;
const char dset_name[256] = "$group_dset$";
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 values (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->$group$_group, dset_name, 1, offset, count, eof_read_size, 0, dset);
}
#+end_src
#+begin_src c :tangle write_buffered_hdf5.c
trexio_exit_code trexio_hdf5_write_$group_dset$(trexio_t* const file,
const int64_t offset_file,
const uint32_t rank,
const uint64_t* dims,
const double* dset)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (dset == NULL) return TREXIO_INVALID_ARG_5;
const char dset_name[256] = "$group_dset$";
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
hid_t 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->$group$_group, dset_name) != 1 ) {
/* If the file does not exist -> create it and write */
/* Create chunked dataset with dtype datatype and write indices into it */
rc_write = trexio_hdf5_create_write_dset_sparse(f->$group$_group, dset_name, dtype, chunk_dims, dset);
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 dtype datatype and write indices into it */
rc_write = trexio_hdf5_open_write_dset_sparse(f->$group$_group, dset_name, dtype, chunk_dims, offset_data, dset);
if (rc_write != TREXIO_SUCCESS) return rc_write;
}
return TREXIO_SUCCESS;
}
trexio_exit_code
trexio_hdf5_read_$group_dset$_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;
const char dset_name[256] = "$group_dset$";
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
hid_t dset_id = H5Dopen(f->$group$_group, dset_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_buffered_hdf5.c
trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
if (f->$group$_group == (hsize_t) 0) return TREXIO_HAS_NOT;
const char dset_name[256] = "$group_dset$";
herr_t status = H5LTfind_dataset(f->$group$_group, dset_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
* Template for HDF5 has/read/write a dataset of strings
#+begin_src c :tangle hrw_dset_str_hdf5.h :exports none
@ -798,6 +989,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
if (file == NULL) return TREXIO_INVALID_ARG_1;
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);
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
@ -927,6 +1119,7 @@ trexio_hdf5_has_$group_str$ (trexio_t* const file)
if (file == NULL) return TREXIO_INVALID_ARG_1;
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);
/* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */
@ -977,6 +1170,108 @@ trexio_hdf5_delete_$group$ (trexio_t* const file)
}
#+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);
#+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);
}
#+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;
}
#+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;
}
}
#+end_src
* Helper functions
#+begin_src c :tangle helpers_hdf5.c
@ -1113,6 +1408,7 @@ trexio_hdf5_open_write_dset_sparse (const hid_t group_id,
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,
@ -1121,6 +1417,7 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
)
{
const int h5_rank = 1;
if (dset_rank == 0) return TREXIO_INVALID_ARG_3;
// get the dataset handle
hid_t dset_id = H5Dopen(group_id, dset_name, H5P_DEFAULT);
@ -1151,9 +1448,9 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
if (max_offset > ddims[0]) {
is_EOF = 1;
// 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
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
@ -1238,7 +1535,7 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
#+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_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
#+end_src

View File

@ -10,6 +10,12 @@ cat populated/pop_struct_text_group_dset.h >> trexio_text.h
cat populated/pop_struct_text_group.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_has_group_text.c >> trexio_text.c
cat populated/pop_hrw_group_text.h >> trexio_text.h
cat populated/pop_free_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
@ -24,23 +30,27 @@ cat populated/pop_has_dset_str_text.c >> trexio_text.c
cat populated/pop_has_dset_sparse_text.c >> trexio_text.c
cat populated/pop_has_attr_num_text.c >> trexio_text.c
cat populated/pop_has_attr_str_text.c >> trexio_text.c
cat populated/pop_has_buffered_text.c >> trexio_text.c
cat populated/pop_read_dset_data_text.c >> trexio_text.c
cat populated/pop_read_dset_str_text.c >> trexio_text.c
cat populated/pop_read_dset_sparse_text.c >> trexio_text.c
cat populated/pop_read_attr_str_text.c >> trexio_text.c
cat populated/pop_read_attr_num_text.c >> trexio_text.c
cat populated/pop_read_buffered_text.c >> trexio_text.c
cat populated/pop_write_dset_data_text.c >> trexio_text.c
cat populated/pop_write_dset_str_text.c >> trexio_text.c
cat populated/pop_write_dset_sparse_text.c >> trexio_text.c
cat populated/pop_write_attr_str_text.c >> trexio_text.c
cat populated/pop_write_attr_num_text.c >> trexio_text.c
cat populated/pop_write_buffered_text.c >> trexio_text.c
cat populated/pop_hrw_dset_data_text.h >> trexio_text.h
cat populated/pop_hrw_dset_str_text.h >> trexio_text.h
cat populated/pop_hrw_dset_sparse_text.h >> trexio_text.h
cat populated/pop_hrw_attr_num_text.h >> trexio_text.h
cat populated/pop_hrw_attr_str_text.h >> trexio_text.h
cat populated/pop_hrw_buffered_text.h >> trexio_text.h
cat suffix_text.h >> trexio_text.h

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ set(Tests_text
io_dset_float_text
io_dset_str_text
io_dset_sparse_text
io_determinant_text
io_safe_dset_float_text
io_dset_int_text
io_num_text
@ -23,6 +24,7 @@ if(ENABLE_HDF5)
io_dset_float_hdf5
io_dset_str_hdf5
io_dset_sparse_hdf5
io_determinant_hdf5
io_safe_dset_float_hdf5
io_dset_int_hdf5
io_num_hdf5

View File

@ -5,7 +5,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_del.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write_delete_group (const char* file_name, const back_end_t backend) {

View File

@ -26,11 +26,11 @@ int main() {
assert (rc == 0);
}
rc = system("rm -rf test_all.dir");
rc = system("rm -f -- test_all.dir/*.txt test_all.dir/*.txt.size test_all.dir/.lock && rm -fd -- test_all.dir");
assert (rc == 0);
test_write("test_all.dir", TREXIO_TEXT);
test_read ("test_all.dir", TREXIO_TEXT);
rc = system("rm -rf test_all.dir");
rc = system("rm -f -- test_all.dir/*.txt test_all.dir/*.txt.size test_all.dir/.lock && rm -fd -- test_all.dir");
assert (rc == 0);
return 0;
@ -94,6 +94,10 @@ int test_write(const char* file_name, const back_end_t backend) {
rc = trexio_write_nucleus_coord(file,coord);
assert (rc == TREXIO_SUCCESS);
// check the force flushing
rc = trexio_flush(file);
assert (rc == TREXIO_SUCCESS);
rc = trexio_write_nucleus_label(file, label, 32);
assert (rc == TREXIO_SUCCESS);
rc = trexio_write_nucleus_point_group(file, sym, 32);

326
tests/io_determinant_hdf5.c Normal file
View File

@ -0,0 +1,326 @@
#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;
// 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);
}
// get the number of int64 bit fields per determinant
int int_num;
rc = trexio_get_int64_num(file, &int_num);
assert(rc == TREXIO_SUCCESS);
assert(int_num == (MO_NUM-1)/64 + 1);
// allocate memory and fill with values to be written
det_list = (int64_t*) calloc(2 * int_num * 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 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 the state_id of a given file: 0 is ground state
if (trexio_has_state_id(file) == TREXIO_HAS_NOT) {
rc = trexio_write_state_id(file, STATE_TEST);
assert(rc == TREXIO_SUCCESS);
}
// 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[2*int_num*offset_d]);
assert(rc == TREXIO_SUCCESS);
rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
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);
// 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);
rc = trexio_has_state_id(file);
assert(rc==TREXIO_SUCCESS);
// now check that previously written determinant_coefficient exists
rc = trexio_has_determinant_coefficient(file);
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;
rc = trexio_get_int64_num(file, &int_num);
assert (rc == TREXIO_SUCCESS);
assert (int_num == (MO_NUM - 1)/64 + 1);
// define arrays to read into
int64_t* det_list_read;
double* det_coef_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));
// 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);
int32_t state_id = 666;
rc = trexio_read_state_id(file, &state_id);
assert(rc == TREXIO_SUCCESS);
assert(state_id == STATE_TEST);
// 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 = TREXIO_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");
*/
// check conversion of one orbital list into the bitfield determinant representation
int64_t* det_list_check = (int64_t*) calloc(int_num, sizeof(int64_t));
rc = trexio_to_bitfield_list (orb_list_up, occ_num_up, det_list_check, int_num);
assert (rc == TREXIO_SUCCESS);
for (int i=0; i<int_num; i++) {
assert (det_list_check[i] == det_list_read[2*int_num*5+i]);
}
// close current session
rc = trexio_close(file);
assert (rc == TREXIO_SUCCESS);
// free the memory
free(det_list_read);
free(det_coef_read);
free(det_list_check);
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;
}

326
tests/io_determinant_text.c Normal file
View File

@ -0,0 +1,326 @@
#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 -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " 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;
// 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);
}
// get the number of int64 bit fields per determinant
int int_num;
rc = trexio_get_int64_num(file, &int_num);
assert(rc == TREXIO_SUCCESS);
assert(int_num == (MO_NUM-1)/64 + 1);
// allocate memory and fill with values to be written
det_list = (int64_t*) calloc(2 * int_num * 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 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 the state_id of a given file: 0 is ground state
if (trexio_has_state_id(file) == TREXIO_HAS_NOT) {
rc = trexio_write_state_id(file, STATE_TEST);
assert(rc == TREXIO_SUCCESS);
}
// 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[2*int_num*offset_d]);
assert(rc == TREXIO_SUCCESS);
rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
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);
// 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);
rc = trexio_has_state_id(file);
assert(rc==TREXIO_SUCCESS);
// now check that previously written determinant_coefficient exists
rc = trexio_has_determinant_coefficient(file);
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;
rc = trexio_get_int64_num(file, &int_num);
assert (rc == TREXIO_SUCCESS);
assert (int_num == (MO_NUM - 1)/64 + 1);
// define arrays to read into
int64_t* det_list_read;
double* det_coef_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));
// 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);
int32_t state_id = 666;
rc = trexio_read_state_id(file, &state_id);
assert(rc == TREXIO_SUCCESS);
assert(state_id == STATE_TEST);
// 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 = TREXIO_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");
*/
// check conversion of one orbital list into the bitfield determinant representation
int64_t* det_list_check = (int64_t*) calloc(int_num, sizeof(int64_t));
rc = trexio_to_bitfield_list (orb_list_up, occ_num_up, det_list_check, int_num);
assert (rc == TREXIO_SUCCESS);
for (int i=0; i<int_num; i++) {
assert (det_list_check[i] == det_list_read[2*int_num*5+i]);
}
// close current session
rc = trexio_close(file);
assert (rc == TREXIO_SUCCESS);
// free the memory
free(det_list_read);
free(det_coef_read);
free(det_list_check);
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;
}

View File

@ -5,7 +5,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_dset_f.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write_dset (const char* file_name, const back_end_t backend) {
@ -40,7 +40,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
// write numerical attribute in an empty file
rc = trexio_write_nucleus_num(file, num);
assert (rc == TREXIO_SUCCESS);
// write numerical dataset in a file
rc = trexio_write_nucleus_coord(file, coord);
assert (rc == TREXIO_SUCCESS);
@ -144,5 +144,3 @@ int main(void) {
return 0;
}

View File

@ -27,7 +27,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
// write numerical attribute in an empty file
rc = trexio_write_basis_shell_num(file, num);
assert (rc == TREXIO_SUCCESS);
// write numerical (integer) dataset in a file
rc = trexio_write_basis_nucleus_index(file, nucl_index);
assert (rc == TREXIO_SUCCESS);
@ -51,10 +51,18 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
/*================= START OF TEST ==================*/
// open file
// open file
file = trexio_open(file_name, 'r', backend, &rc);
assert (file != NULL);
// check that the group exists
rc = trexio_has_basis(file);
assert(rc==TREXIO_SUCCESS);
// check that the group does not exist
rc = trexio_has_mo(file);
assert(rc==TREXIO_HAS_NOT);
// check that the previously written dataset exists
rc = trexio_has_basis_nucleus_index(file);
assert (rc == TREXIO_SUCCESS);
@ -130,5 +138,3 @@ int main(void) {
return 0;
}

View File

@ -5,7 +5,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_dset_i.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write_dset (const char* file_name, const back_end_t backend) {
@ -27,7 +27,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
// write numerical attribute in an empty file
rc = trexio_write_basis_shell_num(file, num);
assert (rc == TREXIO_SUCCESS);
// write numerical (integer) dataset in a file
rc = trexio_write_basis_nucleus_index(file, nucl_index);
assert (rc == TREXIO_SUCCESS);
@ -51,10 +51,18 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
/*================= START OF TEST ==================*/
// open file
// open file
file = trexio_open(file_name, 'r', backend, &rc);
assert (file != NULL);
// check that the group exists
rc = trexio_has_basis(file);
assert(rc==TREXIO_SUCCESS);
// check that the group does not exist
rc = trexio_has_mo(file);
assert(rc==TREXIO_HAS_NOT);
// check that the previously written dataset exists
rc = trexio_has_basis_nucleus_index(file);
assert (rc == TREXIO_SUCCESS);
@ -130,5 +138,3 @@ int main(void) {
return 0;
}

View File

@ -86,6 +86,14 @@ static int test_has_dset_sparse (const char* file_name, const back_end_t backend
assert (file != NULL);
assert (rc == TREXIO_SUCCESS);
// check that the group exists
rc = trexio_has_mo_2e_int(file);
assert(rc==TREXIO_SUCCESS);
// check that the group does not exist
rc = trexio_has_rdm(file);
assert(rc==TREXIO_HAS_NOT);
// first check that mo_2e_int_eri_lr (we only write non-lr component in this unit test)
rc = trexio_has_mo_2e_int_eri_lr(file);
assert(rc==TREXIO_HAS_NOT);
@ -147,7 +155,7 @@ static int test_read_dset_sparse (const char* file_name, const back_end_t backen
assert(index_read[4*offset_data_read] == 4 * (int32_t) (offset_file_read-offset));
// 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 = 97;
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
@ -159,11 +167,6 @@ static int test_read_dset_sparse (const char* file_name, const back_end_t backen
assert(chunk_read == eof_read_size_check);
assert(index_read[4*size_r-1] == 0);
assert(index_read[4*offset_data_read] == 4 * (int32_t) (offset_file_read-offset));
/*
for(int i=0; i<size_r; ++i){
printf("%d %lf\n", index_read[4*i], value_read[i]);
}
*/
// close current session
rc = trexio_close(file);

View File

@ -6,7 +6,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_dset_sparse.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
#define SIZE 100
#define N_CHUNKS 5
@ -86,6 +86,14 @@ static int test_has_dset_sparse (const char* file_name, const back_end_t backend
assert (file != NULL);
assert (rc == TREXIO_SUCCESS);
// check that the group exists
rc = trexio_has_mo_2e_int(file);
assert(rc==TREXIO_SUCCESS);
// check that the group does not exist
rc = trexio_has_rdm(file);
assert(rc==TREXIO_HAS_NOT);
// first check that mo_2e_int_eri_lr (we only write non-lr component in this unit test)
rc = trexio_has_mo_2e_int_eri_lr(file);
assert(rc==TREXIO_HAS_NOT);

View File

@ -6,7 +6,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_dset_s.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write_dset_str (const char* file_name, const back_end_t backend) {
@ -39,7 +39,7 @@ static int test_write_dset_str (const char* file_name, const back_end_t backend)
// write numerical attribute in an empty file
rc = trexio_write_nucleus_num(file, num);
assert (rc == TREXIO_SUCCESS);
// write dataset of string in the file (including FAKE statements)
int max_str_len = 16;
rc = trexio_write_nucleus_label(file, labels, max_str_len);
@ -153,5 +153,3 @@ int main(void) {
return 0;
}

View File

@ -5,7 +5,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_num.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write_num (const char* file_name, const back_end_t backend) {

View File

@ -6,7 +6,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_safe_dset_f.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write_dset (const char* file_name, const back_end_t backend) {
@ -41,7 +41,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
// write numerical attribute in an empty file
rc = trexio_write_nucleus_num(file, num);
assert (rc == TREXIO_SUCCESS);
/* write numerical dataset with an unsafe dimension
* this should return TREXIO_UNSAFE_ARRAY_DIM indicating
* that access beyong allocated memory is likely to occur */
@ -161,5 +161,3 @@ int main(void) {
return 0;
}

View File

@ -6,7 +6,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_str.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write_str (const char* file_name, const back_end_t backend) {
@ -129,5 +129,3 @@ int main(void) {
return 0;
}

View File

@ -6,7 +6,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_open.dir"
#define TREXIO_VOID "non_existing_" TREXIO_FILE
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_open_w (const char* file_name, const back_end_t backend) {

View File

@ -6,7 +6,7 @@
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_over.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_write (const char* file_name, const back_end_t backend) {

View File

@ -5,8 +5,8 @@
#include <stdint.h>
#define TEST_BACKEND TREXIO_TEXT
#define TREXIO_FILE "test_dset_sparse.dir"
#define RM_COMMAND "rm -rf " TREXIO_FILE
#define TREXIO_FILE "test_pre_close.dir"
#define RM_COMMAND "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
static int test_pre_close_1 (const char* file_name, const back_end_t backend)
{

View File

@ -6,20 +6,20 @@ program test_trexio
integer :: rc
logical :: have_hdf5
print * , "============================================"
print'(a)' , "============================================"
print'(a,a)' , " TREXIO VERSION STRING : ", TREXIO_PACKAGE_VERSION
print'(a,i3)', " TREXIO MAJOR VERSION : ", TREXIO_VERSION_MAJOR
print'(a,i3)', " TREXIO MINOR VERSION : ", TREXIO_VERSION_MINOR
print * , "============================================"
print'(a)' , "============================================"
rc = trexio_info()
call system('rm -rf -- test_write_f.dir')
call system('rm -f -- test_write_f.dir/*.txt test_write_f.dir/*.txt.size test_write_f.dir/.lock && rm -fd -- test_write_f.dir')
print *, 'call test_write(''test_write_f.dir'', TREXIO_TEXT)'
call test_write('test_write_f.dir', TREXIO_TEXT)
print *, 'call test_read(''test_write_f.dir'', TREXIO_TEXT)'
call test_read('test_write_f.dir', TREXIO_TEXT)
call system('rm -rf -- test_write_f.dir')
call system('rm -f -- test_write_f.dir/*.txt test_write_f.dir/*.txt.size test_write_f.dir/.lock && rm -fd -- test_write_f.dir')
call test_read_void('test_write_f.dir', TREXIO_TEXT)
@ -55,7 +55,7 @@ subroutine test_write(file_name, back_end)
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)
double precision :: charge(12)
@ -63,25 +63,42 @@ subroutine test_write(file_name, back_end)
character(len=:), allocatable :: sym_str
character(len=:), allocatable :: label(:)
double precision, allocatable :: energy(:)
integer , allocatable :: spin(:)
! sparse data
integer(4) :: index_sparse_mo_2e_int_eri(4,100)
double precision :: value_sparse_mo_2e_int_eri(100)
integer(4) :: index_sparse_ao_2e_int_eri(4,100)
double precision :: value_sparse_ao_2e_int_eri(100)
integer :: i, n_buffers = 5
integer(8) :: buf_size, offset
buf_size = 100/n_buffers
! determinants
integer*8 :: det_list(6, 50)
integer*8 :: det_num
integer :: int_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
index_sparse_mo_2e_int_eri(1,i) = 4*i - 3
index_sparse_mo_2e_int_eri(2,i) = 4*i+1 - 3
index_sparse_mo_2e_int_eri(3,i) = 4*i+2 - 3
index_sparse_mo_2e_int_eri(4,i) = 4*i+3 - 3
value_sparse_mo_2e_int_eri(i) = 3.14 + float(i)
index_sparse_ao_2e_int_eri(1,i) = 4*i - 3
index_sparse_ao_2e_int_eri(2,i) = 4*i+1 - 3
index_sparse_ao_2e_int_eri(3,i) = 4*i+2 - 3
index_sparse_ao_2e_int_eri(4,i) = 4*i+3 - 3
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
! parameters to be written
num = 12
nucleus_num = 12
charge = (/ 6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1. /)
coord = reshape( (/ 0.00000000d0, 1.39250319d0 , 0.00000000d0 , &
-1.20594314d0, 0.69625160d0 , 0.00000000d0 , &
@ -97,6 +114,10 @@ subroutine test_write(file_name, back_end)
0.00000000d0, 2.47304151d0 , 0.00000000d0 /), &
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_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 +139,19 @@ subroutine test_write(file_name, back_end)
rc = trexio_has_nucleus_charge(trex_file)
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2')
rc = trexio_has_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')
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_has_nucleus(trex_file)
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 5')
rc = trexio_has_ao_2e_int(trex_file)
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 6')
rc = trexio_write_nucleus_num(trex_file, nucleus_num)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE NUM')
rc = trexio_write_nucleus_charge(trex_file, charge)
@ -144,19 +174,50 @@ subroutine test_write(file_name, back_end)
rc = trexio_write_basis_nucleus_index(trex_file, basis_nucleus_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
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')
endif
allocate(energy(mo_num))
do i=1,mo_num
energy(i) = dble(i)-100.d0
enddo
rc = trexio_write_mo_energy(trex_file, energy)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE ENERGY')
deallocate(energy)
allocate(spin(mo_num))
spin(:) = 0
do i=mo_num/2+1,mo_num
spin(i) = 1
enddo
rc = trexio_write_mo_spin(trex_file, spin)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE SPIN')
deallocate(spin)
offset = 0
do i = 1,n_buffers
rc = trexio_write_mo_2e_int_eri(trex_file, offset, buf_size, &
index_sparse_mo_2e_int_eri(1,offset+1), &
value_sparse_mo_2e_int_eri(offset+1))
rc = trexio_write_ao_2e_int_eri(trex_file, offset, buf_size_sparse, &
index_sparse_ao_2e_int_eri(1,offset+1), &
value_sparse_ao_2e_int_eri(offset+1))
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
rc = trexio_has_nucleus_num(trex_file)
@ -165,9 +226,18 @@ subroutine test_write(file_name, back_end)
rc = trexio_has_nucleus_coord(trex_file)
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')
rc = trexio_has_determinant_list(trex_file)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 4')
rc = trexio_has_nucleus(trex_file)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 5')
rc = trexio_has_ao_2e_int(trex_file)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 6')
rc = trexio_close(trex_file)
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS CLOSE')
@ -201,10 +271,13 @@ subroutine test_read(file_name, back_end)
character(len=4) :: label(12) ! also works with allocatable arrays
character(len=32) :: sym_str
integer :: mo_num
double precision, allocatable :: energy(:)
integer , allocatable :: spin(:)
! sparse data
integer(4) :: index_sparse_mo_2e_int_eri(4,20)
double precision :: value_sparse_mo_2e_int_eri(20)
integer(4) :: index_sparse_ao_2e_int_eri(4,20)
double precision :: value_sparse_ao_2e_int_eri(20)
integer(8) :: read_buf_size = 10
integer(8) :: read_buf_size_save = 10
integer(8) :: offset_read = 40
@ -213,13 +286,31 @@ subroutine test_read(file_name, back_end)
integer(8) :: offset_data_eof = 1
integer(8) :: size_toread = 0
! determinant data
integer*8 :: det_list(6,50)
integer*8 :: det_list_check(3)
integer*8 :: read_buf_det_size = 20
integer*8 :: offset_det_read = 10
integer*8 :: offset_det_data_read = 5
integer*8 :: determinant_num
integer :: int_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
num = 12
basis_shell_num = 24
index_sparse_mo_2e_int_eri = 0
value_sparse_mo_2e_int_eri = 0.0d0
index_sparse_ao_2e_int_eri = 0
value_sparse_ao_2e_int_eri = 0.0d0
det_list = 0_8
orb_list_up = 0
orb_list_dn = 0
! ================= START OF TEST ===================== !
@ -259,9 +350,11 @@ subroutine test_read(file_name, back_end)
endif
rc = trexio_read_nucleus_label(trex_file, label, 2)
rc = trexio_read_nucleus_label(trex_file, label, 4)
call trexio_assert(rc, TREXIO_SUCCESS)
if (trim(label(2)) == 'Na') then
if (trim(label(2)) == 'Na' .and. &
trim(label(4)) == 'C 66' .and. &
trim(label(5)) == 'C') then
write(*,*) 'SUCCESS READ LABEL'
else
print *, 'FAILURE LABEL CHECK'
@ -289,15 +382,15 @@ subroutine test_read(file_name, back_end)
endif
rc = trexio_read_mo_2e_int_eri(trex_file, offset_read, read_buf_size, &
index_sparse_mo_2e_int_eri(1, offset_data_read + 1), &
value_sparse_mo_2e_int_eri(offset_data_read + 1))
rc = trexio_read_ao_2e_int_eri(trex_file, offset_read, read_buf_size, &
index_sparse_ao_2e_int_eri(1, offset_data_read + 1), &
value_sparse_ao_2e_int_eri(offset_data_read + 1))
!do i = 1,20
! write(*,*) index_sparse_mo_2e_int_eri(1,i)
! write(*,*) index_sparse_ao_2e_int_eri(1,i)
!enddo
call trexio_assert(rc, TREXIO_SUCCESS)
if (index_sparse_mo_2e_int_eri(1, 1) == 0 .and. &
index_sparse_mo_2e_int_eri(1, offset_data_read + 1) == offset_read*4 + 1) then
if (index_sparse_ao_2e_int_eri(1, 1) == 0 .and. &
index_sparse_ao_2e_int_eri(1, offset_data_read + 1) == offset_read*4 + 1) then
write(*,*) 'SUCCESS READ SPARSE DATA'
else
print *, 'FAILURE SPARSE DATA CHECK'
@ -307,17 +400,17 @@ subroutine test_read(file_name, back_end)
! 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)
rc = trexio_read_mo_2e_int_eri(trex_file, offset_eof, read_buf_size, &
index_sparse_mo_2e_int_eri(1, offset_data_eof + 1), &
value_sparse_mo_2e_int_eri(offset_data_eof + 1))
rc = trexio_read_ao_2e_int_eri(trex_file, offset_eof, read_buf_size, &
index_sparse_ao_2e_int_eri(1, offset_data_eof + 1), &
value_sparse_ao_2e_int_eri(offset_data_eof + 1))
!do i = 1,20
! write(*,*) index_sparse_mo_2e_int_eri(1,i)
! write(*,*) index_sparse_ao_2e_int_eri(1,i)
!enddo
call trexio_assert(rc, TREXIO_END)
if (read_buf_size == 3 .and. &
index_sparse_mo_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_mo_2e_int_eri(1, offset_data_eof + 1) == offset_eof*4 + 1) then
index_sparse_ao_2e_int_eri(1, 1) == 0 .and. &
index_sparse_ao_2e_int_eri(1, offset_data_read + 1) == offset_read*4 + 1 .and. &
index_sparse_ao_2e_int_eri(1, offset_data_eof + 1) == offset_eof*4 + 1) then
write(*,*) 'SUCCESS READ SPARSE DATA EOF'
read_buf_size = read_buf_size_save
else
@ -325,7 +418,8 @@ subroutine test_read(file_name, back_end)
call exit(-1)
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)
if (size_toread == 100) then
write(*,*) 'SUCCESS READ SPARSE SIZE'
@ -334,7 +428,99 @@ subroutine test_read(file_name, back_end)
call exit(-1)
endif
! obtain a number of int64 bit fields per determinant
rc = trexio_get_int64_num(trex_file, int_num)
call trexio_assert(rc, TREXIO_SUCCESS)
if (int_num == 3) then
write(*,*) 'SUCCESS GET INT64_NUM'
else
print *, 'FAILURE DET INT64_NUM CHECK'
call exit(-1)
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
! Print occupied orbitals for an up-spin component of a given determinant
!write(*,*) orb_list_up(1:occ_num_up)
! Print integers representanting a given determinant fully (up- and down-spin components)
!write(*,*) det_list(:, offset_det_data_read+1)
! Print binary representation of the first integer bit field of a given determinant
!write(*,'(B64.64)') det_list(1, offset_det_data_read+1)
call trexio_assert(rc, TREXIO_SUCCESS)
if (occ_num_up == 16 .and. occ_num_dn == 5) then
write(*,*) 'SUCCESS CONVERT DET LIST'
else
print *, 'FAILURE DET CONVERT CHECK'
call exit(-1)
endif
! convert one orbital list into a bitfield determinant representation
rc = trexio_to_bitfield_list(orb_list_up, occ_num_up, det_list_check, 3)
!write(*,*) occ_num_up, occ_num_dn
! Print occupied orbitals for an up-spin component of a given determinant
!write(*,*) orb_list_up(1:occ_num_up)
! Print integers representanting a given determinant fully (up- and down-spin components)
!write(*,*) det_list(1:3, offset_det_data_read+1)
!write(*,*) det_list_check(1:3)
! Print binary representation of the first integer bit field of a given determinant
!write(*,'(B64.64)') det_list(1, offset_det_data_read+1)
call trexio_assert(rc, TREXIO_SUCCESS)
if (det_list_check(1) == det_list(1, offset_det_data_read+1) .and. &
det_list_check(2) == det_list(2, offset_det_data_read+1) .and. &
det_list_check(3) == det_list(3, offset_det_data_read+1)) then
write(*,*) 'SUCCESS CONVERT ORB LIST'
else
print *, 'FAILURE ORB CONVERT CHECK'
call exit(-1)
endif
rc = trexio_read_mo_num(trex_file, mo_num)
call trexio_assert(rc, TREXIO_SUCCESS)
allocate(spin(mo_num), energy(mo_num))
rc = trexio_read_mo_energy(trex_file, energy)
call trexio_assert(rc, TREXIO_SUCCESS)
if (energy(10) /= -90.d0) then
print *, 'Failure to read MO energy: ', energy(10)
call exit(-1)
end if
rc = trexio_read_mo_spin(trex_file, spin)
call trexio_assert(rc, TREXIO_SUCCESS)
if (sum(spin) /= mo_num/2) then
print *, 'Failure to read MO spin', mo_num, sum(spin)
call exit(-1)
end if
! close the file
rc = trexio_close(trex_file)
call trexio_assert(rc, TREXIO_SUCCESS)
@ -352,7 +538,7 @@ subroutine test_read_void(file_name, back_end)
character*(*), intent(in) :: file_name
integer, intent(in) :: back_end
integer(8) :: trex_file
integer(trexio_t) :: trex_file
integer :: rc = 1
character(128) :: str
@ -365,7 +551,7 @@ subroutine test_read_void(file_name, back_end)
call trexio_assert(rc, TREXIO_OPEN_ERROR)
call trexio_string_of_error(rc, str)
print *, trim(str)
print *, 'Test error message: ', trim(str)
! ================= END OF TEST ===================== !

View File

@ -12,12 +12,12 @@ detailed_nums = get_detailed_num_dict(trex_config)
detailed_strs = get_detailed_str_dict(trex_config)
# helper dictionaries that contain names of groups, nums or dsets as keys
dsets = get_dset_dict(trex_config)
detailed_dsets_nostr, detailed_dsets_str, detailed_dsets_sparse = split_dset_dict_detailed(dsets)
detailed_dsets_nostr, detailed_dsets_str, detailed_dsets_sparse, detailed_dsets_buf = split_dset_dict_detailed(dsets)
detailed_dsets = detailed_dsets_nostr.copy()
detailed_dsets.update(detailed_dsets_str)
# build a big dictionary with all pre-processed data
detailed_all = {
'datasets' : dict(detailed_dsets_nostr, **detailed_dsets_str, **detailed_dsets_sparse),
'datasets' : dict(detailed_dsets_nostr, **detailed_dsets_str, **detailed_dsets_sparse, **detailed_dsets_buf),
'groups' : group_dict,
'numbers' : detailed_nums,
'strings' : detailed_strs
@ -62,10 +62,14 @@ for fname in files_todo['dset_str']:
for fname in files_todo['dset_sparse']:
recursive_populate_file(fname, template_paths, detailed_dsets_sparse)
# populate has/read/write_buffered functions with recursive scheme
for fname in files_todo['buffered']:
recursive_populate_file(fname, template_paths, detailed_dsets_buf)
# populate group-related functions with mixed scheme
for fname in files_todo['group']:
# recursive scheme for delete_group functions
if 'delete' in fname:
if 'delete' in fname or 'has' in fname:
recursive_populate_file(fname, template_paths, group_dict)
# mixed (iterative+recursive) scheme [text backend]
else:

View File

@ -37,8 +37,11 @@ def get_files_todo(source_files: dict) -> dict:
all_files += source_files[key]
files_todo = {}
files_todo['all'] = [f for f in all_files if 'read' in f or 'write' in f or 'has' in f or 'flush' in f or 'free' in f or 'hrw' in f or 'delete' in f]
for key in ['dset_data', 'dset_str', 'dset_sparse', 'attr_num', 'attr_str', 'group']:
files_todo['all'] = [
f for f in all_files
if 'read' in f or 'write' in f or 'has' in f or 'flush' in f or 'free' in f or 'hrw' in f or 'delete' in f
]
for key in ['dset_data', 'dset_str', 'dset_sparse', 'attr_num', 'attr_str', 'group', 'buffered']:
files_todo[key] = list(filter(lambda x: key in x, files_todo['all']))
files_todo['group'].append('struct_text_group_dset.h')
@ -105,17 +108,23 @@ def recursive_populate_file(fname: str, paths: dict, detailed_source: dict) -> N
triggers = ['group_dset_dtype', 'group_dset_py_dtype', 'group_dset_h5_dtype', 'default_prec', 'is_index',
'group_dset_f_dtype_default', 'group_dset_f_dtype_double', 'group_dset_f_dtype_single',
'group_dset_dtype_default', 'group_dset_dtype_double', 'group_dset_dtype_single',
'group_dset_rank', 'group_dset_dim_list', 'group_dset_f_dims',
'group_dset_rank', 'group_dset_unique_rank', 'group_dset_dim_list', 'group_dset_f_dims',
'group_num_f_dtype_default', 'group_num_f_dtype_double', 'group_num_f_dtype_single',
'group_num_dtype_default', 'group_num_dtype_double', 'group_num_dtype_single',
'group_num_h5_dtype', 'group_num_py_dtype',
'group_dset_format_scanf', 'group_dset_format_printf', 'group_dset_sparse_dim',
'group_num_h5_dtype', 'group_num_py_dtype', 'group_dset_format_scanf', 'group_dset_format_printf',
'group_dset_sparse_indices_printf', 'group_dset_sparse_indices_scanf',
'sparse_format_printf_8', 'sparse_format_printf_16', 'sparse_format_printf_32',
'sparse_line_length_8', 'sparse_line_length_16', 'sparse_line_length_32',
'group_dset', 'group_num', 'group_str', 'group']
for item in detailed_source.keys():
# special case to exclude write functions for readonly dimensions (like determinant_num) from the public API
if 'write' in fname and 'front' in fname and ('.f90' in fname or '.py' in fname):
if 'trex_json_int_type' in detailed_source[item].keys():
if 'readonly' in detailed_source[item]['trex_json_int_type']:
continue
with open(join(templ_path,fname), 'r') as f_in :
with open(join(templ_path,fname_new), 'a') as f_out :
num_written = []
@ -137,14 +146,27 @@ def recursive_populate_file(fname: str, paths: dict, detailed_source: dict) -> N
continue
# special case to uncomment check for positive dimensioning variables in templates
elif 'uncommented by the generator for dimensioning' in line:
# only uncomment and write the line if `num` is in the name
# only uncomment and write the line if `dim` is in the name
if 'dim' in detailed_source[item]['trex_json_int_type']:
templine = line.replace('//', '')
f_out.write(templine)
# special case to get the max dimension of sparse datasets with different dimensions
elif 'trexio_read_$group_dset_unique_dim$_64' in line:
for i in range(int(detailed_source[item]['group_dset_unique_rank'])):
templine = line.replace('$group_dset_unique_dim$', detailed_source[item]['unique_dims'][i]).replace('$dim_id$', str(i))
f_out.write(templine)
# general case of recursive replacement of inline triggers
else:
populated_line = recursive_replace_line(line, triggers, detailed_source[item])
f_out.write(populated_line)
# special case to include some functions in the private header
if 'trex_json_int_type' in detailed_source[item].keys():
if 'readonly' in detailed_source[item]['trex_json_int_type'] and 'write' in line and 'front.h' in fname:
with open(join(templ_path,'populated/private_pop_front.h'), 'a') as f_priv:
f_priv.write(populated_line)
else:
f_out.write(populated_line)
else:
f_out.write(populated_line)
f_out.write("\n")
@ -214,7 +236,7 @@ def iterative_populate_file (filename: str, paths: dict, detailed_all: dict) ->
for line in f_in :
id = check_triggers(line, triggers)
if id == 0:
# special case for proper error handling when deallocting text groups
# special case for proper error handling when deallocating text groups
error_handler = ' if (rc != TREXIO_SUCCESS) return rc;\n'
populated_line = iterative_replace_line(line, '$group$', detailed_all['groups'], add_line=error_handler)
f_out.write(populated_line)
@ -477,7 +499,22 @@ def get_dtype_dict (dtype: str, target: str, rank = None, int_len_printf = None)
f'group_{target}_format_scanf' : 'lf',
f'group_{target}_py_dtype' : 'float'
})
elif dtype in ['int', 'dim', 'index']:
elif 'buffered' in dtype:
dtype_dict.update({
'default_prec' : '64',
f'group_{target}_dtype' : 'double',
f'group_{target}_h5_dtype' : 'native_double',
f'group_{target}_f_dtype_default' : 'real(c_double)',
f'group_{target}_f_dtype_double' : 'real(c_double)',
f'group_{target}_f_dtype_single' : 'real(c_float)',
f'group_{target}_dtype_default' : 'double',
f'group_{target}_dtype_double' : 'double',
f'group_{target}_dtype_single' : 'float',
f'group_{target}_format_printf' : '24.16e',
f'group_{target}_format_scanf' : 'lf',
f'group_{target}_py_dtype' : 'float'
})
elif dtype in ['int', 'dim', 'dim readonly', 'index']:
dtype_dict.update({
'default_prec' : '32',
f'group_{target}_dtype' : 'int64_t',
@ -517,7 +554,7 @@ def get_dtype_dict (dtype: str, target: str, rank = None, int_len_printf = None)
group_dset_format_printf_16 = '"'
group_dset_format_printf_32 = '"'
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_16 += item_printf_16
group_dset_format_printf_32 += item_printf_32
@ -568,16 +605,17 @@ def get_detailed_num_dict (configuration: dict) -> dict:
tmp_num = f'{k1}_{k2}'
if not 'str' in v2[0]:
tmp_dict = {}
tmp_dict['group'] = k1
tmp_dict['group_num'] = tmp_num
num_dict[tmp_num] = tmp_dict
tmp_dict.update(get_dtype_dict(v2[0], 'num'))
if v2[0] in ['int', 'dim']:
if v2[0] in ['int', 'dim', 'dim readonly']:
tmp_dict['trex_json_int_type'] = v2[0]
else:
tmp_dict['trex_json_int_type'] = ''
num_dict[tmp_num] = tmp_dict
return num_dict
@ -638,17 +676,23 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
configuration (dict) : configuration from `trex.json`
Returns:
dset_numeric_dict, dset_string_dict (tuple) : dictionaries corresponding to all numeric- and string-based datasets, respectively.
(tuple) : dictionaries corresponding to all types of datasets in trexio.
"""
dset_numeric_dict = {}
dset_string_dict = {}
dset_sparse_dict = {}
dset_string_dict = {}
dset_sparse_dict = {}
dset_buffer_dict = {}
for k,v in datasets.items():
# create a temp dictionary
tmp_dict = {}
rank = len(v[1])
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
is_sparse = False
int_len_printf = {}
@ -674,11 +718,18 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
else:
tmp_dict['is_index'] = 'false'
# add the list of dimensions
tmp_dict['dims'] = [dim.replace('.','_') for dim in v[1]]
# get a list of unique dimensions for sparse datasets
if is_sparse:
tmp_dict['unique_dims'] = list(set(tmp_dict['dims']))
tmp_dict['group_dset_unique_rank'] = str(len(tmp_dict['unique_dims']))
# add the rank
tmp_dict['rank'] = rank
tmp_dict['group_dset_rank'] = str(rank)
# add the list of dimensions
tmp_dict['dims'] = [dim.replace('.','_') for dim in v[1]]
# build a list of dimensions to be inserted in the dims array initialization, e.g. {ao_num, ao_num}
dim_list = tmp_dict['dims'][0]
if rank > 1:
@ -695,8 +746,6 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
tmp_dict['group_dset_f_dims'] = dim_f_list
if is_sparse:
# store the max possible dim of the sparse dset (e.g. mo_num)
tmp_dict['group_dset_sparse_dim'] = tmp_dict['dims'][0]
# build printf/scanf sequence and compute line length for n-index sparse quantity
index_printf = f'*(index_sparse + {str(rank)}*i'
index_scanf = f'index_sparse + {str(rank)}*i'
@ -731,12 +780,14 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
# split datasets in numeric- and string- based
if 'str' in datatype:
dset_string_dict[k] = tmp_dict
elif 'buffered' in datatype:
dset_buffer_dict[k] = tmp_dict
elif is_sparse:
dset_sparse_dict[k] = tmp_dict
else:
dset_numeric_dict[k] = tmp_dict
return (dset_numeric_dict, dset_string_dict, dset_sparse_dict)
return (dset_numeric_dict, dset_string_dict, dset_sparse_dict, dset_buffer_dict)
def check_dim_consistency(num: dict, dset: dict) -> None:
@ -757,7 +808,10 @@ def check_dim_consistency(num: dict, dset: dict) -> None:
if dim not in dim_tocheck:
dim_tocheck.append(dim)
num_onlyDim = [attr_name for attr_name, specs in num.items() if specs['trex_json_int_type']=='dim']
num_onlyDim = [
attr_name for attr_name, specs in num.items()
if 'dim' in specs['trex_json_int_type']
]
for dim in dim_tocheck:
if not dim in num_onlyDim:

View File

@ -1,15 +1,15 @@
(define-module (gnu packages trexio)
(define-module (trexio)
#:use-module (guix packages)
#:use-module (gnu packages pkg-config)
#:use-module (gnu packages glib)
#:use-module (gnu packages gcc)
#:use-module (gnu packages autotools)
#:use-module (gnu packages maths)
#:use-module (gnu packages maths) ;; contains hdf5
#:use-module (guix download)
#:use-module (guix build-system gnu)
#:use-module (guix licenses))
(define-public trexio
(define-public trexio-2.0
(package
(name "trexio")
(version "2.0")
@ -20,15 +20,48 @@
".tar.gz"))
(sha256
(base32
;; the hash below is produced by guix download <url>
"1d2cn4w2r9gfid5b9wrq9q290kqdnbjdmvli76s1i5r58kdg5vkf"
))))
(build-system gnu-build-system)
(arguments '(#:configure-flags '("--enable-silent-rules")))
(inputs `(("hdf5" ,hdf5-1.12) ("gfortran", gfortran)))
(synopsis "TREX I/O lbrary: trexio package")
(description "APIs in C and Fortran to exchange wavefunction data.
Supports HDF5 and TEXT back ends.")
(inputs `(("hdf5" ,hdf5) ("gfortran", gfortran)))
(synopsis "TREX I/O library")
(description "The TREXIO library defines a standard format for storing wave functions, together with
a C-compatible API such that it can be easily used in any programming language.")
(home-page "https://trex-coe.github.io/trexio")
(license bsd-3)))
(define-public trexio-2.1
(package/inherit trexio-2.0
(version "2.1.0")
(source (origin
(method url-fetch)
(uri (string-append "https://github.com/TREX-CoE/trexio/releases/download/v" version
"/trexio-" version
".tar.gz"))
(sha256
(base32
;; the hash below is produced by guix download <url>
"10syfw4mq3wpp9anahmxnm7660bm1ya5xd9l5njai3xr8g4nca13"
))))))
(define-public trexio-2.2
(package/inherit trexio-2.0
(version "2.2.0")
(source (origin
(method url-fetch)
(uri (string-append "https://github.com/TREX-CoE/trexio/releases/download/v" version
"/trexio-" version
".tar.gz"))
(sha256
(base32
;; the hash below is produced by guix download <url>
"1n9n1gbk5hgvg73am991xrv7ap002rz719a3nvh8m8ff9x10qd76"
))))))
(define-public trexio
;; Default version of TREXIO.
trexio-2.2)
trexio

464
trex.org
View File

@ -22,6 +22,10 @@ variables cannot be negative. This additional constraint is required
because ~dim~ attributes are used internally to allocate memory and to
check array boundaries in the memory-safe API. Most of the times, the
~dim~ variables contain the ~num~ suffix.
You may also encounter some ~dim readonly~ variables.
It means that the value is automatically computed and written by the
TREXIO library, thus it is read-only and cannot be (over)written by the
user.
In Fortran, arrays are 1-based and in most other languages the
arrays are 0-based. Hence, we introduce the ~index~ type which is a
@ -31,8 +35,16 @@ For sparse data structures such as electron replusion integrals,
the data can be too large to fit in memory and the data needs to be
fetched using multiple function calls to perform I/O on buffers.
For more information on how to read/write sparse data structures, see
the [[./examples.html][examples]].
the [[./examples.html][examples]]. The ~sparse~ data representation implies the
[[https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_(COO)][coordinate list]] representation, namely the user has to write a list
of indices and values.
For the Configuration Interfaction (CI) and Configuration State Function (CSF)
groups, the ~buffered~ data type is introduced, which allows similar incremental
I/O as for ~sparse~ data but without the need to write indices of the sparse values.
For determinant lists (integer bit fields), the ~special~ attribute is present in the type.
This means that the source code is not produced by the generator, but hand-written.
#+begin_src python :tangle trex.json :exports none
{
@ -64,19 +76,19 @@ the [[./examples.html][examples]].
#+CALL: json(data=metadata, title="metadata")
#+RESULTS:
:RESULTS:
:results:
#+begin_src python :tangle trex.json
"metadata": {
"code_num" : [ "dim", [] ]
, "code" : [ "str", [ "metadata.code_num" ] ]
, "author_num" : [ "dim", [] ]
, "author" : [ "str", [ "metadata.author_num" ] ]
, "package_version" : [ "str", [] ]
, "description" : [ "str", [] ]
, "unsafe" : [ "int", [] ]
"code_num" : [ "dim", [] ]
, "code" : [ "str", [ "metadata.code_num" ] ]
, "author_num" : [ "dim", [] ]
, "author" : [ "str", [ "metadata.author_num" ] ]
, "package_version" : [ "str", [] ]
, "description" : [ "str", [] ]
, "unsafe" : [ "int", [] ]
} ,
#+end_src
:END:
:end:
* Electron (electron group)
@ -191,20 +203,20 @@ If you encounter the aforementioned issue, please report it to our [[https://git
#+CALL: json(data=ecp, title="ecp")
#+RESULTS:
:RESULTS:
:results:
#+begin_src python :tangle trex.json
"ecp": {
"max_ang_mom_plus_1" : [ "int" , [ "nucleus.num" ] ]
, "z_core" : [ "int" , [ "nucleus.num" ] ]
, "num" : [ "dim" , [] ]
, "ang_mom" : [ "int" , [ "ecp.num" ] ]
, "nucleus_index" : [ "index", [ "ecp.num" ] ]
, "exponent" : [ "float", [ "ecp.num" ] ]
, "coefficient" : [ "float", [ "ecp.num" ] ]
, "power" : [ "int" , [ "ecp.num" ] ]
"max_ang_mom_plus_1" : [ "int" , [ "nucleus.num" ] ]
, "z_core" : [ "int" , [ "nucleus.num" ] ]
, "num" : [ "dim" , [] ]
, "ang_mom" : [ "int" , [ "ecp.num" ] ]
, "nucleus_index" : [ "index", [ "ecp.num" ] ]
, "exponent" : [ "float", [ "ecp.num" ] ]
, "coefficient" : [ "float", [ "ecp.num" ] ]
, "power" : [ "int" , [ "ecp.num" ] ]
} ,
#+end_src
:END:
:end:
** Example
@ -310,6 +322,7 @@ power = [
| ~nucleus_index~ | ~index~ | ~(basis.shell_num)~ | One-to-one correspondence between shells and atomic indices |
| ~shell_ang_mom~ | ~int~ | ~(basis.shell_num)~ | One-to-one correspondence between shells and angular momenta |
| ~shell_factor~ | ~float~ | ~(basis.shell_num)~ | Normalization factor of each shell ($\mathcal{N}_s$) |
| ~r_power~ | ~int~ | ~(basis.shell_num)~ | Power to which $r$ is raised ($n_s$) |
| ~shell_index~ | ~index~ | ~(basis.prim_num)~ | One-to-one correspondence between primitives and shell index |
| ~exponent~ | ~float~ | ~(basis.prim_num)~ | Exponents of the primitives ($\gamma_{ks}$) |
| ~coefficient~ | ~float~ | ~(basis.prim_num)~ | Coefficients of the primitives ($a_{ks}$) |
@ -318,22 +331,23 @@ power = [
#+CALL: json(data=basis, title="basis")
#+RESULTS:
:RESULTS:
:results:
#+begin_src python :tangle trex.json
"basis": {
"type" : [ "str" , [] ]
, "prim_num" : [ "dim" , [] ]
, "shell_num" : [ "dim" , [] ]
, "nucleus_index" : [ "index", [ "basis.shell_num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.shell_num" ] ]
, "shell_factor" : [ "float", [ "basis.shell_num" ] ]
, "shell_index" : [ "index", [ "basis.prim_num" ] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
"type" : [ "str" , [] ]
, "prim_num" : [ "dim" , [] ]
, "shell_num" : [ "dim" , [] ]
, "nucleus_index" : [ "index", [ "basis.shell_num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.shell_num" ] ]
, "shell_factor" : [ "float", [ "basis.shell_num" ] ]
, "r_power" : [ "int" , [ "basis.shell_num" ] ]
, "shell_index" : [ "index", [ "basis.prim_num" ] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
} ,
#+end_src
:END:
:end:
** Example
@ -464,16 +478,16 @@ prim_factor =
#+CALL: json(data=ao, title="ao")
#+RESULTS:
:RESULTS:
:results:
#+begin_src python :tangle trex.json
"ao": {
"cartesian" : [ "int" , [] ]
, "num" : [ "dim" , [] ]
, "shell" : [ "index", [ "ao.num" ] ]
, "normalization" : [ "float", [ "ao.num" ] ]
"cartesian" : [ "int" , [] ]
, "num" : [ "dim" , [] ]
, "shell" : [ "index", [ "ao.num" ] ]
, "normalization" : [ "float", [ "ao.num" ] ]
} ,
#+end_src
:END:
:end:
** One-electron integrals (~ao_1e_int~ group)
:PROPERTIES:
@ -492,13 +506,18 @@ prim_factor =
over atomic orbitals.
#+NAME: ao_1e_int
| Variable | Type | Dimensions | Description |
|--------------------+---------+--------------------+--------------------------------------------------------|
| ~overlap~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert q \rangle$ |
| ~kinetic~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{T}_e \vert q \rangle$ |
| ~potential_n_e~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{V}_{\text{ne}} \vert q \rangle$ |
| ~ecp~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{V}_{\text{ecp}} \vert q \rangle$ |
| ~core_hamiltonian~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{h} \vert q \rangle$ |
| Variable | Type | Dimensions | Description |
|-----------------------+---------+--------------------+-----------------------------------------------------------------------------------|
| ~overlap~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert q \rangle$ (real part, general case) |
| ~kinetic~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{T}_e \vert q \rangle$ (real part, general case) |
| ~potential_n_e~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{V}_{\text{ne}} \vert q \rangle$ (real part, general case) |
| ~ecp~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{V}_{\text{ecp}} \vert q \rangle$ (real part, general case) |
| ~core_hamiltonian~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{h} \vert q \rangle$ (real part, general case) |
| ~overlap_im~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert q \rangle$ (imaginary part) (imaginary part) |
| ~kinetic_im~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{T}_e \vert q \rangle$ (imaginary part) |
| ~potential_n_e_im~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{V}_{\text{ne}} \vert q \rangle$ (imaginary part) |
| ~ecp_im~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{V}_{\text{ECP}} \vert q \rangle$ (imaginary part) |
| ~core_hamiltonian_im~ | ~float~ | ~(ao.num, ao.num)~ | $\langle p \vert \hat{h} \vert q \rangle$ (imaginary part) |
#+CALL: json(data=ao_1e_int, title="ao_1e_int")
@ -506,11 +525,16 @@ prim_factor =
:results:
#+begin_src python :tangle trex.json
"ao_1e_int": {
"overlap" : [ "float", [ "ao.num", "ao.num" ] ]
, "kinetic" : [ "float", [ "ao.num", "ao.num" ] ]
, "potential_n_e" : [ "float", [ "ao.num", "ao.num" ] ]
, "ecp" : [ "float", [ "ao.num", "ao.num" ] ]
, "core_hamiltonian" : [ "float", [ "ao.num", "ao.num" ] ]
"overlap" : [ "float", [ "ao.num", "ao.num" ] ]
, "kinetic" : [ "float", [ "ao.num", "ao.num" ] ]
, "potential_n_e" : [ "float", [ "ao.num", "ao.num" ] ]
, "ecp" : [ "float", [ "ao.num", "ao.num" ] ]
, "core_hamiltonian" : [ "float", [ "ao.num", "ao.num" ] ]
, "overlap_im" : [ "float", [ "ao.num", "ao.num" ] ]
, "kinetic_im" : [ "float", [ "ao.num", "ao.num" ] ]
, "potential_n_e_im" : [ "float", [ "ao.num", "ao.num" ] ]
, "ecp_im" : [ "float", [ "ao.num", "ao.num" ] ]
, "core_hamiltonian_im" : [ "float", [ "ao.num", "ao.num" ] ]
} ,
#+end_src
:end:
@ -556,30 +580,36 @@ prim_factor =
* Molecular orbitals (mo group)
#+NAME: mo
| Variable | Type | Dimensions | Description |
|---------------+---------+--------------------+--------------------------------------------------------------------------|
| ~type~ | ~str~ | | Free text to identify the set of MOs (HF, Natural, Local, CASSCF, /etc/) |
| ~num~ | ~dim~ | | Number of MOs |
| ~coefficient~ | ~float~ | ~(ao.num, mo.num)~ | MO coefficients |
| ~class~ | ~str~ | ~(mo.num)~ | Choose among: Core, Inactive, Active, Virtual, Deleted |
| ~symmetry~ | ~str~ | ~(mo.num)~ | Symmetry in the point group |
| ~occupation~ | ~float~ | ~(mo.num)~ | Occupation number |
| Variable | Type | Dimensions | Description |
|------------------+---------+--------------------+--------------------------------------------------------------------------|
| ~type~ | ~str~ | | Free text to identify the set of MOs (HF, Natural, Local, CASSCF, /etc/) |
| ~num~ | ~dim~ | | Number of MOs |
| ~coefficient~ | ~float~ | ~(ao.num, mo.num)~ | MO coefficients (real part, general case) |
| ~coefficient_im~ | ~float~ | ~(ao.num, mo.num)~ | MO coefficients (imaginary part, for periodic calculations) |
| ~class~ | ~str~ | ~(mo.num)~ | Choose among: Core, Inactive, Active, Virtual, Deleted |
| ~symmetry~ | ~str~ | ~(mo.num)~ | Symmetry in the point group |
| ~occupation~ | ~float~ | ~(mo.num)~ | Occupation number |
| ~energy~ | ~float~ | ~(mo.num)~ | For canonical MOs, corresponding eigenvalue |
| ~spin~ | ~int~ | ~(mo.num)~ | For UHF wave functions, 0 is $\alpha$ and 1 is $\beta$ |
#+CALL: json(data=mo, title="mo")
#+RESULTS:
:RESULTS:
:results:
#+begin_src python :tangle trex.json
"mo": {
"type" : [ "str" , [] ]
, "num" : [ "dim" , [] ]
, "coefficient" : [ "float", [ "mo.num", "ao.num" ] ]
, "class" : [ "str" , [ "mo.num" ] ]
, "symmetry" : [ "str" , [ "mo.num" ] ]
, "occupation" : [ "float", [ "mo.num" ] ]
"type" : [ "str" , [] ]
, "num" : [ "dim" , [] ]
, "coefficient" : [ "float", [ "mo.num", "ao.num" ] ]
, "coefficient_im" : [ "float", [ "mo.num", "ao.num" ] ]
, "class" : [ "str" , [ "mo.num" ] ]
, "symmetry" : [ "str" , [ "mo.num" ] ]
, "occupation" : [ "float", [ "mo.num" ] ]
, "energy" : [ "float", [ "mo.num" ] ]
, "spin" : [ "int" , [ "mo.num" ] ]
} ,
#+end_src
:END:
:end:
** One-electron integrals (~mo_1e_int~ group)
@ -588,13 +618,18 @@ prim_factor =
the basis of molecular orbitals.
#+NAME: mo_1e_int
| Variable | Type | Dimensions | Description |
|--------------------+---------+--------------------+--------------------------------------------------------|
| ~overlap~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert j \rangle$ |
| ~kinetic~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{T}_e \vert j \rangle$ |
| ~potential_n_e~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{V}_{\text{ne}} \vert j \rangle$ |
| ~ecp~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{V}_{\text{ECP}} \vert j \rangle$ |
| ~core_hamiltonian~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{h} \vert j \rangle$ |
| Variable | Type | Dimensions | Description |
|-----------------------+---------+--------------------+-----------------------------------------------------------------------------------|
| ~overlap~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert j \rangle$ (real part, general case) |
| ~kinetic~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{T}_e \vert j \rangle$ (real part, general case) |
| ~potential_n_e~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{V}_{\text{ne}} \vert j \rangle$ (real part, general case) |
| ~ecp~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{V}_{\text{ECP}} \vert j \rangle$ (real part, general case) |
| ~core_hamiltonian~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{h} \vert j \rangle$ (real part, general case) |
| ~overlap_im~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert j \rangle$ (imaginary part) (imaginary part) |
| ~kinetic_im~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{T}_e \vert j \rangle$ (imaginary part) |
| ~potential_n_e_im~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{V}_{\text{ne}} \vert j \rangle$ (imaginary part) |
| ~ecp_im~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{V}_{\text{ECP}} \vert j \rangle$ (imaginary part) |
| ~core_hamiltonian_im~ | ~float~ | ~(mo.num, mo.num)~ | $\langle i \vert \hat{h} \vert j \rangle$ (imaginary part) |
#+CALL: json(data=mo_1e_int, title="mo_1e_int")
@ -602,26 +637,41 @@ prim_factor =
:results:
#+begin_src python :tangle trex.json
"mo_1e_int": {
"overlap" : [ "float", [ "mo.num", "mo.num" ] ]
, "kinetic" : [ "float", [ "mo.num", "mo.num" ] ]
, "potential_n_e" : [ "float", [ "mo.num", "mo.num" ] ]
, "ecp" : [ "float", [ "mo.num", "mo.num" ] ]
, "core_hamiltonian" : [ "float", [ "mo.num", "mo.num" ] ]
"overlap" : [ "float", [ "mo.num", "mo.num" ] ]
, "kinetic" : [ "float", [ "mo.num", "mo.num" ] ]
, "potential_n_e" : [ "float", [ "mo.num", "mo.num" ] ]
, "ecp" : [ "float", [ "mo.num", "mo.num" ] ]
, "core_hamiltonian" : [ "float", [ "mo.num", "mo.num" ] ]
, "overlap_im" : [ "float", [ "mo.num", "mo.num" ] ]
, "kinetic_im" : [ "float", [ "mo.num", "mo.num" ] ]
, "potential_n_e_im" : [ "float", [ "mo.num", "mo.num" ] ]
, "ecp_im" : [ "float", [ "mo.num", "mo.num" ] ]
, "core_hamiltonian_im" : [ "float", [ "mo.num", "mo.num" ] ]
} ,
#+end_src
:end:
** Two-electron integrals (~mo_2e_int~ group)
The operators as the same as those defined in the
The operators are the same as those defined in the
[[#ao_two_e][AO two-electron integrals section]]. Here, the integrals are given in
the basis of molecular orbitals.
The Cholesky decomposition of the integrals can also be stored:
\[
\A_{ijkl} = \sum_{\alpha} G_{il\alpha} G_{jl\alpha}
\]
#+NAME: mo_2e_int
| Variable | Type | Dimensions | Description |
|----------+----------------+------------------------------------+-----------------------------------------|
| ~eri~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | Electron repulsion integrals |
| ~eri_lr~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | Long-range Electron repulsion integrals |
| Variable | Type | Dimensions | Description |
|-----------------------+----------------+---------------------------------------------------+-----------------------------------------------|
| ~eri~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | Electron repulsion integrals |
| ~eri_lr~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | Long-range Electron repulsion integrals |
| ~eri_cholesky_num~ | ~dim~ | | Number of Cholesky vectors for ERI |
| ~eri_cholesky~ | ~float sparse~ | ~(mo.num, mo.num, mo_2e_int.eri_cholesky_num)~ | Cholesky decomposition of the ERI |
| ~eri_lr_cholesky_num~ | ~dim~ | | Number of Cholesky vectors for long range ERI |
| ~eri_lr_cholesky~ | ~float sparse~ | ~(mo.num, mo.num, mo_2e_int.eri_lr_cholesky_num)~ | Cholesky decomposition of the long range ERI |
#+CALL: json(data=mo_2e_int, title="mo_2e_int")
@ -629,19 +679,141 @@ prim_factor =
:results:
#+begin_src python :tangle trex.json
"mo_2e_int": {
"eri" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "eri_lr" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
"eri" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "eri_lr" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "eri_cholesky_num" : [ "dim" , [] ]
, "eri_cholesky" : [ "float sparse", [ "mo_2e_int.eri_cholesky_num", "mo.num", "mo.num" ] ]
, "eri_lr_cholesky_num" : [ "dim" , [] ]
, "eri_lr_cholesky" : [ "float sparse", [ "mo_2e_int.eri_lr_cholesky_num", "mo.num", "mo.num" ] ]
} ,
#+end_src
: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 occupied orbitals.
However, this becomes unfeasible for larger expansions and requires more advanced data structures.
The bit field representation is used here, namely a given determinant is represented as $N_{\text{int}}$
64-bit integers where j-th bit is set to 1 if there is an electron in the j-th orbital and 0 otherwise.
This gives access to larger determinant expansions by optimising the storage of the determinant lists
in the memory.
\[
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.
Note: the ~special~ attribute is present in the types, meaning that the source node is not
produced by the code generator.
An illustration on how to read determinants is presented in the [[./examples.html][examples]].
#+NAME: determinant
| Variable | Type | Dimensions | Description |
|---------------+------------------+---------------------+--------------------------------------------------------|
| ~num~ | ~dim readonly~ | | Number of determinants |
| ~list~ | ~int special~ | ~(determinant.num)~ | List of determinants as integer bit fields |
| ~coefficient~ | ~float buffered~ | ~(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 readonly" , [] ]
, "list" : [ "int special" , [ "determinant.num" ] ]
, "coefficient" : [ "float buffered", [ "determinant.num" ] ]
} ,
#+end_src
:end:
* Configuration state functions (csf group)
The configuration interaction (CI) wave function $\Psi$ can be
expanded in the basis of [[https://en.wikipedia.org/wiki/Configuration_state_function][configuration state functions]] (CSFs)
$\Psi_I$ as follows
\[
\Psi = \sum_I C_I \psi_I.
\]
Each CSF is a linear combination of Slater determinants. Slater
determinants are stored in the =determinant= section. In this group
we store the CI coefficients in the basis of CSFs, and the
matrix $\langle D_I | \psi_J \rangle$ needed to project the CSFs in
the basis of Slater determinants.
#+NAME: csf
| Variable | Type | Dimensions | Description |
|-------------------+------------------+-----------------------------+------------------------------------------------|
| ~num~ | ~dim readonly~ | | Number of CSFs |
| ~coefficient~ | ~float buffered~ | ~(csf.num)~ | Coefficients of the CSFs from the CI expansion |
| ~det_coefficient~ | ~float sparse~ | ~(determinant.num,csf.num)~ | Projection on the determinant basis |
#+CALL: json(data=csf, title="csf")
#+RESULTS:
:results:
#+begin_src python :tangle trex.json
"csf": {
"num" : [ "dim readonly" , [] ]
, "coefficient" : [ "float buffered", [ "csf.num" ] ]
, "det_coefficient" : [ "float sparse" , [ "csf.num", "determinant.num" ] ]
} ,
#+end_src
:end:
* Excited states (state group)
This group contains information about excited state. Since TREXIO version 2.3.0
the state-specific data (e.g. CI/CSF coeffcients, RDMs) is written in a separate
file in order to avoid over-complicated internal logics and global state switches.
The ~file_name~ and ~label~ arrays have to be written only for the master file,
e.g. the one containing the ground state wave function.
The ~id~ and ~current_label~ attributes have to be specified for each file
(containing both ground and excited state data).
#+NAME: state
| Variable | Type | Dimensions | Description |
|-----------------+-------+---------------+-----------------------------------------------------------------------------------------------|
| ~num~ | ~dim~ | | Number of states (including the ground state) |
| ~id~ | ~int~ | | Index of a current state (0 is ground state) |
| ~label~ | ~str~ | ~(state.num)~ | Labels of all states related to this file (e.g. 'S' for singlets) |
| ~current_label~ | ~str~ | | Labels of the current state that is in a file |
| ~file_name~ | ~str~ | ~(state.num)~ | Names of the TREXIO files linked to the current one (i.e. containing data for excited states) |
#+CALL: json(data=state, title="state")
#+RESULTS:
:results:
#+begin_src python :tangle trex.json
"state": {
"num" : [ "dim", [] ]
, "id" : [ "int", [] ]
, "label" : [ "str", [ "state.num" ] ]
, "current_label" : [ "str", [] ]
, "file_name" : [ "str", [ "state.num" ] ]
} ,
#+end_src
:end:
* Reduced density matrices (rdm group)
The reduced density matrices are defined in the basis of molecular
orbitals.
The $\uparrow$-spin and $\downarrow$-spin components of the one-body
The \uparrow-spin and \downarrow-spin components of the one-body
density matrix are given by
\begin{eqnarray*}
\gamma_{ij}^{\uparrow} &=& \langle \Psi | \hat{a}^{\dagger}_{j\alpha}\, \hat{a}_{i\alpha} | \Psi \rangle \\
@ -677,17 +849,43 @@ prim_factor =
\frac{1}{2} \sum_{ijlk} \Gamma_{ijkl} \langle k l | i j \rangle
\]
To compress the storage, the Cholesky decomposition of the RDMs can
be stored:
\[
\Gamma_{ijkl} = \sum_{\alpha} G_{ij\alpha} G_{kl\alpha}
\]
Warning: as opposed to electron repulsion integrals, the
decomposition is made such that the Cholesky vectors are expanded
in a two-electron basis
$f_{ij}(\mathbf{r}_1,\mathbf{r}_2) = \phi_i(\mathbf{r}_1) \phi_j(\mathbf{r}_2)$,
whereas in electron repulsion integrals each Cholesky vector is
expressed in a basis of a one-electron function
$g_{ik}(\mathbf{r}_1) = \phi_i(\mathbf{r}_1) \phi_k(\mathbf{r}_1)$.
#+NAME: rdm
| Variable | Type | Dimensions | Description |
|-----------+----------------+------------------------------------+-----------------------------------------------------------------------|
| ~1e~ | ~float~ | ~(mo.num, mo.num)~ | One body density matrix |
| ~1e_up~ | ~float~ | ~(mo.num, mo.num)~ | \uparrow-spin component of the one body density matrix |
| ~1e_dn~ | ~float~ | ~(mo.num, mo.num)~ | \downarrow-spin component of the one body density matrix |
| ~2e~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | Two-body reduced density matrix (spin trace) |
| ~2e_upup~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \uparrow\uparrow component of the two-body reduced density matrix |
| ~2e_dndn~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \downarrow\downarrow component of the two-body reduced density matrix |
| ~2e_updn~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \uparrow\downarrow component of the two-body reduced density matrix |
| ~2e_dnup~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \downarrow\uparrow component of the two-body reduced density matrix |
| Variable | Type | Dimensions | Description |
|------------------------+----------------+----------------------------------------------+-----------------------------------------------------------------------|
| ~1e~ | ~float~ | ~(mo.num, mo.num)~ | One body density matrix |
| ~1e_up~ | ~float~ | ~(mo.num, mo.num)~ | \uparrow-spin component of the one body density matrix |
| ~1e_dn~ | ~float~ | ~(mo.num, mo.num)~ | \downarrow-spin component of the one body density matrix |
| ~2e~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | Two-body reduced density matrix (spin trace) |
| ~2e_upup~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \uparrow\uparrow component of the two-body reduced density matrix |
| ~2e_dndn~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \downarrow\downarrow component of the two-body reduced density matrix |
| ~2e_updn~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \uparrow\downarrow component of the two-body reduced density matrix |
| ~2e_dnup~ | ~float sparse~ | ~(mo.num, mo.num, mo.num, mo.num)~ | \downarrow\uparrow component of the two-body reduced density matrix |
| ~2e_cholesky_num~ | ~dim~ | | Number of Cholesky vectors |
| ~2e_cholesky~ | ~float sparse~ | ~(mo.num, mo.num, rdm.2e_cholesky_num)~ | Cholesky decomposition of the Two-body RDM (spin trace) |
| ~2e_upup_cholesky_num~ | ~dim~ | | Number of Cholesky vectors |
| ~2e_upup_cholesky~ | ~float sparse~ | ~(mo.num, mo.num, rdm.2e_upup_cholesky_num)~ | Cholesky decomposition of the Two-body RDM (\uparrow\uparrow) |
| ~2e_dndn_cholesky_num~ | ~dim~ | | Number of Cholesky vectors |
| ~2e_dndn_cholesky~ | ~float sparse~ | ~(mo.num, mo.num, rdm.2e_dndn_cholesky_num)~ | Cholesky decomposition of the Two-body RDM (\downarrow\downarrow) |
| ~2e_updn_cholesky_num~ | ~dim~ | | Number of Cholesky vectors |
| ~2e_updn_cholesky~ | ~float sparse~ | ~(mo.num, mo.num, rdm.2e_updn_cholesky_num)~ | Cholesky decomposition of the Two-body RDM (\uparrow\downarrow) |
| ~2e_dnup_cholesky_num~ | ~dim~ | | Number of Cholesky vectors |
| ~2e_dnup_cholesky~ | ~float sparse~ | ~(mo.num, mo.num, rdm.2e_dnup_cholesky_num)~ | Cholesky decomposition of the Two-body RDM (\downarrow\uparrow) |
#+CALL: json(data=rdm, title="rdm")
@ -695,14 +893,66 @@ prim_factor =
:results:
#+begin_src python :tangle trex.json
"rdm": {
"1e" : [ "float" , [ "mo.num", "mo.num" ] ]
, "1e_up" : [ "float" , [ "mo.num", "mo.num" ] ]
, "1e_dn" : [ "float" , [ "mo.num", "mo.num" ] ]
, "2e" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_upup" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_dndn" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_updn" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_dnup" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
"1e" : [ "float" , [ "mo.num", "mo.num" ] ]
, "1e_up" : [ "float" , [ "mo.num", "mo.num" ] ]
, "1e_dn" : [ "float" , [ "mo.num", "mo.num" ] ]
, "2e" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_upup" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_dndn" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_updn" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_dnup" : [ "float sparse", [ "mo.num", "mo.num", "mo.num", "mo.num" ] ]
, "2e_cholesky_num" : [ "dim" , [] ]
, "2e_cholesky" : [ "float sparse", [ "rdm.2e_cholesky_num", "mo.num", "mo.num" ] ]
, "2e_upup_cholesky_num" : [ "dim" , [] ]
, "2e_upup_cholesky" : [ "float sparse", [ "rdm.2e_upup_cholesky_num", "mo.num", "mo.num" ] ]
, "2e_dndn_cholesky_num" : [ "dim" , [] ]
, "2e_dndn_cholesky" : [ "float sparse", [ "rdm.2e_dndn_cholesky_num", "mo.num", "mo.num" ] ]
, "2e_updn_cholesky_num" : [ "dim" , [] ]
, "2e_updn_cholesky" : [ "float sparse", [ "rdm.2e_updn_cholesky_num", "mo.num", "mo.num" ] ]
, "2e_dnup_cholesky_num" : [ "dim" , [] ]
, "2e_dnup_cholesky" : [ "float sparse", [ "rdm.2e_dnup_cholesky_num", "mo.num", "mo.num" ] ]
} ,
#+end_src
:end:
* Cell (cell group)
#+NAME: cell
| Variable | Type | Dimensions | Description |
|----------+---------+------------+-------------------------|
| ~a~ | ~float~ | ~(3)~ | First unit cell vector |
| ~b~ | ~float~ | ~(3)~ | Second unit cell vector |
| ~c~ | ~float~ | ~(3)~ | Third unit cell vector |
#+CALL: json(data=cell, title="cell")
#+RESULTS:
:results:
#+begin_src python :tangle trex.json
"cell": {
"a" : [ "float", [ "3" ] ]
, "b" : [ "float", [ "3" ] ]
, "c" : [ "float", [ "3" ] ]
} ,
#+end_src
:end:
* Periodic boundary calculations (pbc group)
#+NAME: pbc
| Variable | Type | Dimensions | Description |
|------------+---------+------------+-------------------------|
| ~periodic~ | ~int~ | | ~1~: true or ~0~: false |
| ~k_point~ | ~float~ | ~(3)~ | k-point sampling |
#+CALL: json(data=pbc, title="pbc")
#+RESULTS:
:results:
#+begin_src python :tangle trex.json
"pbc": {
"periodic" : [ "int" , [] ]
, "k_point" : [ "float", [ "3" ] ]
} ,
#+end_src
:end:
@ -724,9 +974,9 @@ prim_factor =
| ~point~ | ~float~ | ~(3, electron.num, qmc.num)~ | 3N-dimensional points |
| ~psi~ | ~float~ | ~(qmc.num)~ | Wave function evaluated at the points |
| ~e_loc~ | ~float~ | ~(qmc.num)~ | Local energy evaluated at the points |
#+CALL: json(data=qmc, title="qmc", last=1)
#+RESULTS:
:results:
#+begin_src python :tangle trex.json