diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index abed670..3b90893 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -24,7 +24,7 @@ jobs: run: ./autogen.sh - name: ./configure - run: QMCKL_DEVEL=1 ./configure --enable-silent-rules --enable-maintainer-mode + run: QMCKL_DEVEL=1 ./configure --enable-silent-rules --enable-maintainer-mode --without-trexio - name: make run: make -j 8 html diff --git a/org/qmckl_verificarlo.org b/org/qmckl_verificarlo.org new file mode 100644 index 0000000..548e513 --- /dev/null +++ b/org/qmckl_verificarlo.org @@ -0,0 +1,328 @@ +#+TITLE: Verificarlo CI +#+SETUPFILE: ../tools/theme.setup +#+INCLUDE: ../tools/lib.org + +* Headers :noexport: + + #+begin_src c :tangle (eval h_private_func) +#ifndef QMCKL_VERIFICARLO_HPT +#define QMCKL_VERIFICARLO_HPT + +#include + + +#ifdef VFC_CI +#include +extern vfc_probes * probes; +#endif + + + #+end_src + + #+begin_src c :tangle (eval c) +#include +#include +#include +#include + +#ifdef VFC_CI +#include +vfc_probes probes; +#else + +/* Disable GCC warnings with unused variables */ +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#endif + + #+end_src + +* Verificarlo probes + +This file contains utility functions to enable the Verificarlo +Continuous Integration system (~VFC_CI~). + +It is a wrapper to Verificarlo's ~vfc_probes~ system. The goal of QMCkl +probes is to simplify the use of ~vfc_probes~, and to provide functions that +can be called either with or without ~VFC_CI~ support by using ~#ifndef~ +statements : + +- when ~VFC_CI~ is disabled, the functions will either return ~false~ + (no error) or perform a check based on a reference value + +- when ~VFC_CI~ is enabled, the functions will simply encapsulate +calls to ~vfc_probe~. + +Moreover, one does not have to worry about the life cycle of the probes +structure, as it is automatically created, dumped and freed by this wrapper. + +~VFC_CI~ support can be enabled by using the following configure command : + + #+begin_src bash +QMCKL_DEVEL=1 ./configure --prefix=$PWD/_install --enable-silent-rules \ + --enable-maintainer-mode CC=verificarlo-f FC=verificarlo-f --host=x86_64 + #+end_src + +Finally, this wrapper also comes with a Fortran interface (in its dedicated +file). + +To learn more about Verificarlo CI : +https://github.com/verificarlo/verificarlo/blob/master/doc/06-Postprocessing.md#verificarlo-ci + + +** Automatically initialize the vfc_probe object if ~VFC_CI~ is defined + + #+begin_src c :tangle (eval h_private_func) +#ifdef VFC_CI +void qmckl_init_probes() __attribute__((constructor)); +#endif + #+end_src + + #+begin_src c :tangle (eval c) +#ifdef VFC_CI +void __attribute__((constructor)) qmckl_init_probes(){ + probes = vfc_init_probes(); +} +#endif + #+end_src + +** Standard probe, without check + + - if ~VFC_CI~ is defined, place a standard probe + - if ~VFC_CI~ is undefined, return ~false~ (no error) + + #+begin_src c :tangle (eval h_private_func) +bool qmckl_probe( + char * testName, + char * varName, + double value +); + #+end_src + + #+begin_src c :tangle (eval c) +bool qmckl_probe( + char * testName, + char * varName, + double value) +{ +#ifdef VFC_CI + return vfc_probe(&probes, testName, varName, value); +#else + return false; +#endif +} + #+end_src + +** Probe with absolute check + + - if VFC_CI is defined, place a probe with an absolute check + - if VFC_CI is undefined, perform an absolute check based on target value + and accuracy + + #+begin_src c :tangle (eval h_private_func) +bool qmckl_probe_check( + char * testName, + char * varName, + double value, + double expectedValue, + double accuracyTarget +); + #+end_src + + #+begin_src c :tangle (eval c) +bool qmckl_probe_check( + char * testName, + char * varName, + double value, + double expectedValue, + double accuracyTarget) +{ +#ifdef VFC_CI + return vfc_probe_check(&probes, testName, varName, value, accuracyTarget); +#else + return !(fabs(value - expectedValue) < accuracyTarget); +#endif +} + #+end_src + +** Probe with relative check + + - if VFC_CI is defined, place a probe with a relative check + - if VFC_CI is undefined, perform a relative check based on target value + and accuracy + + #+begin_src c :tangle (eval h_private_func) +bool qmckl_probe_check_relative( + char * testName, + char * varName, + double value, + double expectedValue, + double accuracyTarget +); + #+end_src + + #+begin_src c :tangle (eval c) +bool qmckl_probe_check_relative ( + char * testName, + char * varName, + double value, + double expectedValue, + double accuracyTarget) +{ +#ifdef VFC_CI + return vfc_probe_check_relative(&probes, testName, varName, value, accuracyTarget); +#else + return !(fabs(value - expectedValue) / fabs(expectedValue) < accuracyTarget); +#endif +} + #+end_src + +** Automatically delete and dump the vfc_probe object if ~VFC_CI~ is defined + + #+begin_src c :tangle (eval h_private_func) +#ifdef VFC_CI +void qmckl_dump_probes() __attribute__((destructor)); +#endif + #+end_src + + #+begin_src c :tangle (eval c) +#ifdef VFC_CI +void __attribute__((destructor)) qmckl_dump_probes(){ + vfc_dump_probes(&probes); +} +#endif + #+end_src + +* Fortran wrappers + + #+begin_src c :tangle (eval h_private_func) +bool qmckl_probe_f( + char * testName, + char * varName, + double * value +); + +bool qmckl_probe_check_f( + char * testName, + char * varName, + double * value, + double * expectedValue, + double * accuracyTarget +); + + +bool qmckl_probe_check_relative_f( + char * testName, + char * varName, + double * value, + double * expectedValue, + double * accuracyTarget +); + #+end_src + + #+begin_src c :tangle (eval c) +bool qmckl_probe_f( + char * testName, + char * varName, + double * value) +{ + return qmckl_probe(testName, varName, *value); +} + + +bool qmckl_probe_check_f( + char * testName, + char * varName, + double * value, + double * expectedValue, + double * accuracyTarget) +{ + return qmckl_probe_check( + testName, varName, + ,*value, *expectedValue, *accuracyTarget + ); +} + + +bool qmckl_probe_check_relative_f( + char * testName, + char * varName, + double * value, + double * expectedValue, + double * accuracyTarget) +{ + return qmckl_probe_check_relative( + testName, varName, + ,*value, *expectedValue, *accuracyTarget + ); +} + #+end_src + + #+begin_src f90 :tangle (eval f) +module qmckl_verificarlo_f + interface + logical(c_bool) function qmckl_probe & + (testName, varName, val) & + bind(C, name="qmckl_probe_f") + + use, intrinsic :: iso_c_binding + import + implicit none + + character(C_CHAR), dimension(*) :: testName + character(C_CHAR), dimension(*) :: varName + + real(C_DOUBLE) :: val + end function qmckl_probe + + logical(c_bool) function qmckl_probe_check & + (testName, varName, val, expectedValue, accuracyTarget) & + bind(C, name="qmckl_probe_check_f") + + use, intrinsic :: iso_c_binding + import + implicit none + + character(C_CHAR), dimension(*) :: testName + character(C_CHAR), dimension(*) :: varName + + real(C_DOUBLE) :: val + real(C_DOUBLE) :: expectedValue + real(C_DOUBLE) :: accuracyTarget + end function qmckl_probe_check + + logical(c_bool) function qmckl_probe_check_relative & + (testName, varName, val, expectedValue, accuracyTarget) & + bind(C, name="qmckl_probe_check_relative_f") + + use, intrinsic :: iso_c_binding + import + implicit none + + character(C_CHAR), dimension(*) :: testName + character(C_CHAR), dimension(*) :: varName + + real(C_DOUBLE) :: val + real(C_DOUBLE) :: expectedValue + real(C_DOUBLE) :: accuracyTarget + end function qmckl_probe_check_relative + end interface +end module qmckl_verificarlo_f + #+end_src + +* End of files :noexport: + + #+begin_src c :tangle (eval c) +#ifndef VFC_CI +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif +#endif + #+end_src + + #+begin_src c :comments link :tangle (eval h_private_func) +#endif + #+end_src