diff --git a/docs/theme.setup b/docs/theme.setup new file mode 100644 index 0000000..c56aee9 --- /dev/null +++ b/docs/theme.setup @@ -0,0 +1,7 @@ +# -*- mode: org; -*- + +#+HTML_LINK_HOME: index.html +#+OPTIONS: H:4 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t +#+SETUPFILE: ../docs/org-html-themes/org/theme-readtheorg.setup + + diff --git a/src/Makefile b/src/Makefile index 8d9ff83..90ee33a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,37 +1,9 @@ -COMPILER=GNU -#COMPILER=INTEL -#COMPILER=LLVM +# Header :noexport: -ifeq ($(COMPILER),GNU) -CC=gcc -g -CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra -FC=gfortran -g -FFLAGS=-fPIC -fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation -Wreal-q-constant -Wuninitialized -fbacktrace -ffpe-trap=zero,overflow,underflow -finit-real=nan +# This file was created by tools/Building.org -LIBS=-lgfortran -lm -endif - -ifeq ($(COMPILER),INTEL) -CC=icc -xHost -CFLAGS=-fPIC -g -O2 - -FC=ifort -xHost -FFLAGS=-fPIC -g -O2 - -LIBS=-lm -lifcore -lirc -endif - -#TODO -ifeq ($(COMPILER),LLVM) -CC=clang -CFLAGS=-fPIC -g -O2 - -FC=flang -FFLAGS=fPIC -g -O2 - -LIBS=-lm -endif +# Variables QMCKL_ROOT=$(shell dirname $(CURDIR)) @@ -40,6 +12,70 @@ export CC CFLAGS FC FFLAGS LIBS QMCKL_ROOT ORG_SOURCE_FILES=$(wildcard *.org) OBJECT_FILES=$(filter-out $(EXCLUDED_OBJECTS), $(patsubst %.org,%.o,$(ORG_SOURCE_FILES))) +INCLUDE=-I$(QMCKL_ROOT)/include/ + +# Compiler options + +# GNU, Intel and LLVM compilers are supported. Choose here: + + +COMPILER=GNU +#COMPILER=INTEL +#COMPILER=LLVM + +# GNU + + +ifeq ($(COMPILER),GNU) +#---------------------------------------------------------- +CC=gcc -g +CFLAGS=-fPIC $(INCLUDE) \ + -fexceptions -Wall -Werror -Wpedantic -Wextra -fmax-errors=3 + +FC=gfortran -g +FFLAGS=-fPIC $(INCLUDE) \ + -fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising \ + -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation \ + -Wreal-q-constant -Wuninitialized -fbacktrace -finit-real=nan \ + -ffpe-trap=zero,overflow,underflow + +LIBS=-lgfortran -lm +#---------------------------------------------------------- +endif + +# Intel + + +ifeq ($(COMPILER),INTEL) +#---------------------------------------------------------- +CC=icc -xHost +CFLAGS=-fPIC -g -O2 $(INCLUDE) + +FC=ifort -xHost +FFLAGS=-fPIC -g -O2 $(INCLUDE) + +LIBS=-lm -lifcore -lirc +#---------------------------------------------------------- +CC=icc -xHost +endif + +# LLVM + + +ifeq ($(COMPILER),LLVM) +#---------------------------------------------------------- +CC=clang +CFLAGS=-fPIC -g -O2 $(INCLUDE) + +FC=flang +FFLAGS=fPIC -g -O2 $(INCLUDE) + +LIBS=-lm +#---------------------------------------------------------- +endif + +# Rules + .PHONY: clean .SECONDARY: # Needed to keep the produced C and Fortran files @@ -50,14 +86,13 @@ libqmckl.so: Makefile.generated test: Makefile.generated $(MAKE) -f Makefile.generated test - doc: $(ORG_SOURCE_FILES) $(QMCKL_ROOT)/tools/create_doc.sh - clean: - rm -f qmckl.h test_qmckl_* test_qmckl.c test_qmckl qmckl_*.f90 qmckl_*.c qmckl_*.o qmckl_*.h Makefile.generated libqmckl.so *.html *.fh *.mod + $(RM) qmckl.h test_qmckl_* test_qmckl.c test_qmckl \ + qmckl_*.f90 qmckl_*.c qmckl_*.o qmckl_*.h \ + Makefile.generated libqmckl.so *.html *.mod Makefile.generated: Makefile $(QMCKL_ROOT)/tools/create_makefile.sh $(ORG_SOURCE_FILES) - $(QMCKL_ROOT)/tools/create_makefile.sh - + $(QMCKL_ROOT)/tools/create_makefile.sh diff --git a/src/README.org b/src/README.org index a2c2c9e..d09949d 100644 --- a/src/README.org +++ b/src/README.org @@ -1,8 +1,8 @@ #+TITLE: QMCkl source code documentation #+EXPORT_FILE_NAME: index.html #+PROPERTY: comments org +#+SETUPFILE: ../docs/theme.setup -#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup * Introduction diff --git a/src/qmckl.org b/src/qmckl.org index 22cd3aa..b9a736f 100644 --- a/src/qmckl.org +++ b/src/qmckl.org @@ -1,38 +1,19 @@ +#+TITLE: Header files +#+SETUPFILE: ../docs/theme.setup -** =qmckl.h= header file +The =qmckl.h= header file has to be included in <<>> codes when +QMCkl functions are used: - The =qmckl.h= header file has to be included in <<>> codes when - QMCkl functions are used: - - #+BEGIN_SRC C :tangle none - #include "qmckl.h" - #+END_SRC f90 +#+begin_src c :tangle none +#include "qmckl.h" +#+end_src f90 - In <<>> programs, the =qmckl_f.f90= interface file should be - included in the source code using the library, and the Fortran codes - should use the ~qmckl~ module as +In <<>> programs, the =qmckl_f.f90= interface file should be +included in the source code using the library, and the Fortran codes +should use the ~qmckl~ module as - #+BEGIN_SRC f90 :tangle none - use qmckl - #+END_SRC f90 +#+begin_src f90 :tangle none +use qmckl +#+end_src f90 -*** Top of header files :noexport: - - #+BEGIN_SRC C :tangle qmckl.h :noweb yes -#ifndef QMCKL_H -#define QMCKL_H -#include -#include - -<> - - #+END_SRC - - #+BEGIN_SRC f90 :tangle qmckl_f.f90 -module qmckl - use, intrinsic :: iso_c_binding - #+END_SRC - - The bottoms of the files are located in the [[qmckl_footer.org]] file. - diff --git a/src/qmckl_ao.org b/src/qmckl_ao.org index b0f9671..5430b06 100644 --- a/src/qmckl_ao.org +++ b/src/qmckl_ao.org @@ -1,91 +1,89 @@ -** Atomic Orbitals - :PROPERTIES: - :f: qmckl_ao.f90 - :c_test: test_qmckl_ao.c - :fh: qmckl_f.f90 - :h: qmckl.h - :f_test: test_qmckl_ao_f.f90 - :END: +#+TITLE: Atomic Orbitals +#+SETUPFILE: ../docs/theme.setup + + The routines for the computation of the values, gradients and + Laplacian of atomic basis functions are defined here. + +* Headers :noexport: + + #+NAME: filename + #+begin_src elisp tangle: no +(file-name-nondirectory (substring buffer-file-name 0 -4)) + #+end_src - This files contains all the routines for the computation of the - values, gradients and Laplacian of the atomic basis functions. - - 3 files are produced: - - a source file : =qmckl_ao.f90= - - a C test file : =test_qmckl_ao.c= - - a Fortran test file : =test_qmckl_ao_f.f90= - -*** Test :noexport: - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) + #+begin_src c :tangle (eval c_test) :noweb yes #include "qmckl.h" #include "munit.h" -MunitResult test_qmckl_ao() { +MunitResult test_<>() { qmckl_context context; context = qmckl_context_create(); - #+END_SRC + #+end_src -*** Polynomials +* Polynomials - \[ - P_l(\mathbf{r},\mathbf{R}_i) = (x-X_i)^a (y-Y_i)^b (z-Z_i)^c - \] + \[ + P_l(\mathbf{r},\mathbf{R}_i) = (x-X_i)^a (y-Y_i)^b (z-Z_i)^c + \] - \begin{eqnarray*} - \frac{\partial }{\partial x} P_l\left(\mathbf{r},\mathbf{R}_i \right) & - = & a (x-X_i)^{a-1} (y-Y_i)^b (z-Z_i)^c \\ - \frac{\partial }{\partial y} P_l\left(\mathbf{r},\mathbf{R}_i \right) & - = & b (x-X_i)^a (y-Y_i)^{b-1} (z-Z_i)^c \\ - \frac{\partial }{\partial z} P_l\left(\mathbf{r},\mathbf{R}_i \right) & - = & c (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1} \\ - \end{eqnarray*} + \begin{eqnarray*} + \frac{\partial }{\partial x} P_l\left(\mathbf{r},\mathbf{R}_i \right) & + = & a (x-X_i)^{a-1} (y-Y_i)^b (z-Z_i)^c \\ + \frac{\partial }{\partial y} P_l\left(\mathbf{r},\mathbf{R}_i \right) & + = & b (x-X_i)^a (y-Y_i)^{b-1} (z-Z_i)^c \\ + \frac{\partial }{\partial z} P_l\left(\mathbf{r},\mathbf{R}_i \right) & + = & c (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1} \\ + \end{eqnarray*} - \begin{eqnarray*} - \left( \frac{\partial }{\partial x^2} + - \frac{\partial }{\partial y^2} + - \frac{\partial }{\partial z^2} \right) P_l - \left(\mathbf{r},\mathbf{R}_i \right) & = & - a(a-1) (x-X_i)^{a-2} (y-Y_i)^b (z-Z_i)^c + \\ - && b(b-1) (x-X_i)^a (y-Y_i)^{b-1} (z-Z_i)^c + \\ - && c(c-1) (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1} - \end{eqnarray*} + \begin{eqnarray*} + \left( \frac{\partial }{\partial x^2} + + \frac{\partial }{\partial y^2} + + \frac{\partial }{\partial z^2} \right) P_l + \left(\mathbf{r},\mathbf{R}_i \right) & = & + a(a-1) (x-X_i)^{a-2} (y-Y_i)^b (z-Z_i)^c + \\ + && b(b-1) (x-X_i)^a (y-Y_i)^{b-1} (z-Z_i)^c + \\ + && c(c-1) (x-X_i)^a (y-Y_i)^b (z-Z_i)^{c-1} + \end{eqnarray*} -**** ~qmckl_ao_power~ +** <<<~qmckl_ao_power~>>> - Computes all the powers of the ~n~ input data up to the given - maximum value given in input for each of the $n$ points: + Computes all the powers of the ~n~ input data up to the given + maximum value given in input for each of the $n$ points: - \[ P_{ij} = X_j^i \] + \[ P_{ij} = X_j^i \] -***** Arguments +*** Arguments - | ~context~ | input | Global state | - | ~n~ | input | Number of values | - | ~X(n)~ | input | Array containing the input values | - | ~LMAX(n)~ | input | Array containing the maximum power for each value | - | ~P(LDP,n)~ | output | Array containing all the powers of ~X~ | - | ~LDP~ | input | Leading dimension of array ~P~ | + | ~context~ | input | Global state | + | ~n~ | input | Number of values | + | ~X(n)~ | input | Array containing the input values | + | ~LMAX(n)~ | input | Array containing the maximum power for each value | + | ~P(LDP,n)~ | output | Array containing all the powers of ~X~ | + | ~LDP~ | input | Leading dimension of array ~P~ | -***** Requirements +*** Requirements - - ~context~ is not 0 - - ~n~ > 0 - - ~X~ is allocated with at least $n \times 8$ bytes - - ~LMAX~ is allocated with at least $n \times 4$ bytes - - ~P~ is allocated with at least $n \times \max_i \text{LMAX}_i \times 8$ bytes - - ~LDP~ >= $\max_i$ ~LMAX[i]~ + - ~context~ is not 0 + - ~n~ > 0 + - ~X~ is allocated with at least $n \times 8$ bytes + - ~LMAX~ is allocated with at least $n \times 4$ bytes + - ~P~ is allocated with at least $n \times \max_i \text{LMAX}_i \times 8$ bytes + - ~LDP~ >= $\max_i$ ~LMAX[i]~ -***** Header - #+BEGIN_SRC C :tangle (org-entry-get nil "h" t) -qmckl_exit_code qmckl_ao_power(const qmckl_context context, - const int64_t n, - const double *X, const int32_t *LMAX, - const double *P, const int64_t LDP); - #+END_SRC +*** Header + #+begin_src c :tangle (eval h) +qmckl_exit_code +qmckl_ao_power(const qmckl_context context, + const int64_t n, + const double *X, + const int32_t *LMAX, + const double *P, + const int64_t LDP); + #+end_src -***** Source - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f" t) +*** Source + #+begin_src f90 :tangle (eval f) integer function qmckl_ao_power_f(context, n, X, LMAX, P, ldp) result(info) implicit none integer*8 , intent(in) :: context @@ -117,10 +115,10 @@ integer function qmckl_ao_power_f(context, n, X, LMAX, P, ldp) result(info) end do end function qmckl_ao_power_f - #+END_SRC + #+end_src -***** C interface :noexport: - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f" t) +*** C interface :noexport: + #+begin_src f90 :tangle (eval f) integer(c_int32_t) function qmckl_ao_power(context, n, X, LMAX, P, ldp) & bind(C) result(info) use, intrinsic :: iso_c_binding @@ -135,9 +133,9 @@ integer(c_int32_t) function qmckl_ao_power(context, n, X, LMAX, P, ldp) & integer, external :: qmckl_ao_power_f info = qmckl_ao_power_f(context, n, X, LMAX, P, ldp) end function qmckl_ao_power - #+END_SRC + #+end_src - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) + #+begin_src f90 :tangle (eval fh) interface integer(c_int32_t) function qmckl_ao_power(context, n, X, LMAX, P, ldp) bind(C) use, intrinsic :: iso_c_binding @@ -149,10 +147,10 @@ end function qmckl_ao_power real (c_double) , intent(out) :: P(ldp,n) end function qmckl_ao_power end interface - #+END_SRC + #+end_src -***** Test :noexport: - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f_test" t) +*** Test :noexport: + #+begin_src f90 :tangle (eval f_test) integer(c_int32_t) function test_qmckl_ao_power(context) bind(C) use qmckl implicit none @@ -195,68 +193,72 @@ integer(c_int32_t) function test_qmckl_ao_power(context) bind(C) test_qmckl_ao_power = 0 deallocate(X,P,LMAX) end function test_qmckl_ao_power - #+END_SRC + #+end_src - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) + #+begin_src c :tangle (eval c_test) int test_qmckl_ao_power(qmckl_context context); munit_assert_int(0, ==, test_qmckl_ao_power(context)); - #+END_SRC + #+end_src - -**** ~qmckl_ao_polynomial_vgl~ +** <<<~qmckl_ao_polynomial_vgl~>>> - Computes the values, gradients and Laplacians at a given point of - all polynomials with an angular momentum up to ~lmax~. + Computes the values, gradients and Laplacians at a given point of + all polynomials with an angular momentum up to ~lmax~. + +*** Arguments -***** Arguments - - | ~context~ | input | Global state | - | ~X(3)~ | input | Array containing the coordinates of the points | - | ~R(3)~ | input | Array containing the x,y,z coordinates of the center | - | ~lmax~ | input | Maximum angular momentum | - | ~n~ | output | Number of computed polynomials | - | ~L(ldl,n)~ | output | Contains a,b,c for all ~n~ results | - | ~ldl~ | input | Leading dimension of ~L~ | - | ~VGL(ldv,n)~ | output | Value, gradients and Laplacian of the polynomials | - | ~ldv~ | input | Leading dimension of array ~VGL~ | + | ~context~ | input | Global state | + | ~X(3)~ | input | Array containing the coordinates of the points | + | ~R(3)~ | input | Array containing the x,y,z coordinates of the center | + | ~lmax~ | input | Maximum angular momentum | + | ~n~ | output | Number of computed polynomials | + | ~L(ldl,n)~ | output | Contains a,b,c for all ~n~ results | + | ~ldl~ | input | Leading dimension of ~L~ | + | ~VGL(ldv,n)~ | output | Value, gradients and Laplacian of the polynomials | + | ~ldv~ | input | Leading dimension of array ~VGL~ | -***** Requirements +*** Requirements - - ~context~ is not 0 - - ~n~ > 0 - - ~lmax~ >= 0 - - ~ldl~ >= 3 - - ~ldv~ >= 5 - - ~X~ is allocated with at least $3 \times 8$ bytes - - ~R~ is allocated with at least $3 \times 8$ bytes - - ~n~ >= ~(lmax+1)(lmax+2)(lmax+3)/6~ - - ~L~ is allocated with at least $3 \times n \times 4$ bytes - - ~VGL~ is allocated with at least $5 \times n \times 8$ bytes - - On output, ~n~ should be equal to ~(lmax+1)(lmax+2)(lmax+3)/6~ - - On output, the powers are given in the following order (l=a+b+c): - - Increase values of ~l~ - - Within a given value of ~l~, alphabetical order of the - string made by a*"x" + b*"y" + c*"z" (in Python notation). - For example, with a=0, b=2 and c=1 the string is "yyz" + - ~context~ is not 0 + - ~n~ > 0 + - ~lmax~ >= 0 + - ~ldl~ >= 3 + - ~ldv~ >= 5 + - ~X~ is allocated with at least $3 \times 8$ bytes + - ~R~ is allocated with at least $3 \times 8$ bytes + - ~n~ >= ~(lmax+1)(lmax+2)(lmax+3)/6~ + - ~L~ is allocated with at least $3 \times n \times 4$ bytes + - ~VGL~ is allocated with at least $5 \times n \times 8$ bytes + - On output, ~n~ should be equal to ~(lmax+1)(lmax+2)(lmax+3)/6~ + - On output, the powers are given in the following order (l=a+b+c): + - Increase values of ~l~ + - Within a given value of ~l~, alphabetical order of the + string made by a*"x" + b*"y" + c*"z" (in Python notation). + For example, with a=0, b=2 and c=1 the string is "yyz" -***** Error codes +*** Error codes - | -1 | Null context | - | -2 | Inconsistent ~ldl~ | - | -3 | Inconsistent ~ldv~ | - | -4 | Inconsistent ~lmax~ | + | -1 | Null context | + | -2 | Inconsistent ~ldl~ | + | -3 | Inconsistent ~ldv~ | + | -4 | Inconsistent ~lmax~ | -***** Header - #+BEGIN_SRC C :tangle (org-entry-get nil "h" t) -qmckl_exit_code qmckl_ao_polynomial_vgl(const qmckl_context context, - const double *X, const double *R, - const int32_t lmax, const int64_t *n, - const int32_t *L, const int64_t ldl, - const double *VGL, const int64_t ldv); - #+END_SRC +*** Header + #+begin_src c :tangle (eval h) +qmckl_exit_code +qmckl_ao_polynomial_vgl(const qmckl_context context, + const double *X, + const double *R, + const int32_t lmax, + const int64_t *n, + const int32_t *L, + const int64_t ldl, + const double *VGL, + const int64_t ldv); + #+end_src -***** Source - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f" t) +*** Source + #+begin_src f90 :tangle (eval f) integer function qmckl_ao_polynomial_vgl_f(context, X, R, lmax, n, L, ldl, VGL, ldv) result(info) implicit none integer*8 , intent(in) :: context @@ -383,10 +385,10 @@ integer function qmckl_ao_polynomial_vgl_f(context, X, R, lmax, n, L, ldl, VGL, info = 0 end function qmckl_ao_polynomial_vgl_f - #+END_SRC + #+end_src -***** C interface :noexport: - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f" t) +*** C interface :noexport: + #+begin_src f90 :tangle (eval f) integer(c_int32_t) function qmckl_ao_polynomial_vgl(context, X, R, lmax, n, L, ldl, VGL, ldv) & bind(C) result(info) use, intrinsic :: iso_c_binding @@ -403,10 +405,10 @@ integer(c_int32_t) function qmckl_ao_polynomial_vgl(context, X, R, lmax, n, L, l integer, external :: qmckl_ao_polynomial_vgl_f info = qmckl_ao_polynomial_vgl_f(context, X, R, lmax, n, L, ldl, VGL, ldv) end function qmckl_ao_polynomial_vgl - #+END_SRC + #+end_src -***** Fortran interface :noexport: - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface :noexport: + #+begin_src f90 :tangle (eval fh) interface integer(c_int32_t) function qmckl_ao_polynomial_vgl(context, X, R, lmax, n, L, ldl, VGL, ldv) & bind(C) @@ -421,9 +423,9 @@ end function qmckl_ao_polynomial_vgl real (c_double) , intent(out) :: VGL(ldv,(lmax+1)*(lmax+2)*(lmax+3)/6) end function qmckl_ao_polynomial_vgl end interface - #+END_SRC -***** Test :noexport: - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f_test" t) + #+end_src +*** Test :noexport: + #+begin_src f90 :tangle (eval f_test) integer(c_int32_t) function test_qmckl_ao_polynomial_vgl(context) bind(C) use qmckl implicit none @@ -516,57 +518,61 @@ integer(c_int32_t) function test_qmckl_ao_polynomial_vgl(context) bind(C) deallocate(L,VGL) end function test_qmckl_ao_polynomial_vgl - #+END_SRC + #+end_src - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) + #+begin_src c :tangle (eval c_test) int test_qmckl_ao_polynomial_vgl(qmckl_context context); munit_assert_int(0, ==, test_qmckl_ao_polynomial_vgl(context)); - #+END_SRC + #+end_src -*** Gaussian basis functions +* Gaussian basis functions -**** ~qmckl_ao_gaussian_vgl~ +** <<<~qmckl_ao_gaussian_vgl~>>> - Computes the values, gradients and Laplacians at a given point of - ~n~ Gaussian functions centered at the same point: + Computes the values, gradients and Laplacians at a given point of + ~n~ Gaussian functions centered at the same point: - \[ v_i = \exp(-a_i |X-R|^2) \] - \[ \nabla_x v_i = -2 a_i (X_x - R_x) v_i \] - \[ \nabla_y v_i = -2 a_i (X_y - R_y) v_i \] - \[ \nabla_z v_i = -2 a_i (X_z - R_z) v_i \] - \[ \Delta v_i = a_i (4 |X-R|^2 a_i - 6) v_i \] + \[ v_i = \exp(-a_i |X-R|^2) \] + \[ \nabla_x v_i = -2 a_i (X_x - R_x) v_i \] + \[ \nabla_y v_i = -2 a_i (X_y - R_y) v_i \] + \[ \nabla_z v_i = -2 a_i (X_z - R_z) v_i \] + \[ \Delta v_i = a_i (4 |X-R|^2 a_i - 6) v_i \] -***** Arguments +*** Arguments - | ~context~ | input | Global state | - | ~X(3)~ | input | Array containing the coordinates of the points | - | ~R(3)~ | input | Array containing the x,y,z coordinates of the center | - | ~n~ | input | Number of computed gaussians | - | ~A(n)~ | input | Exponents of the Gaussians | - | ~VGL(ldv,5)~ | output | Value, gradients and Laplacian of the Gaussians | - | ~ldv~ | input | Leading dimension of array ~VGL~ | + | ~context~ | input | Global state | + | ~X(3)~ | input | Array containing the coordinates of the points | + | ~R(3)~ | input | Array containing the x,y,z coordinates of the center | + | ~n~ | input | Number of computed gaussians | + | ~A(n)~ | input | Exponents of the Gaussians | + | ~VGL(ldv,5)~ | output | Value, gradients and Laplacian of the Gaussians | + | ~ldv~ | input | Leading dimension of array ~VGL~ | -***** Requirements +*** Requirements - - ~context~ is not 0 - - ~n~ > 0 - - ~ldv~ >= 5 - - ~A(i)~ > 0 for all ~i~ - - ~X~ is allocated with at least $3 \times 8$ bytes - - ~R~ is allocated with at least $3 \times 8$ bytes - - ~A~ is allocated with at least $n \times 8$ bytes - - ~VGL~ is allocated with at least $n \times 5 \times 8$ bytes + - ~context~ is not 0 + - ~n~ > 0 + - ~ldv~ >= 5 + - ~A(i)~ > 0 for all ~i~ + - ~X~ is allocated with at least $3 \times 8$ bytes + - ~R~ is allocated with at least $3 \times 8$ bytes + - ~A~ is allocated with at least $n \times 8$ bytes + - ~VGL~ is allocated with at least $n \times 5 \times 8$ bytes -***** Header - #+BEGIN_SRC C :tangle (org-entry-get nil "h" t) -qmckl_exit_code qmckl_ao_gaussian_vgl(const qmckl_context context, - const double *X, const double *R, - const int64_t *n, const int64_t *A, - const double *VGL, const int64_t ldv); - #+END_SRC +*** Header + #+begin_src c :tangle (eval h) +qmckl_exit_code +qmckl_ao_gaussian_vgl(const qmckl_context context, + const double *X, + const double *R, + const int64_t *n, + const int64_t *A, + const double *VGL, + const int64_t ldv); + #+end_src -***** Source - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f" t) +*** Source + #+begin_src f90 :tangle (eval f) integer function qmckl_ao_gaussian_vgl_f(context, X, R, n, A, VGL, ldv) result(info) implicit none integer*8 , intent(in) :: context @@ -626,10 +632,10 @@ integer function qmckl_ao_gaussian_vgl_f(context, X, R, n, A, VGL, ldv) result(i end do end function qmckl_ao_gaussian_vgl_f - #+END_SRC + #+end_src -***** C interface :noexport: - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f" t) +*** C interface :noexport: + #+begin_src f90 :tangle (eval f) integer(c_int32_t) function qmckl_ao_gaussian_vgl(context, X, R, n, A, VGL, ldv) & bind(C) result(info) use, intrinsic :: iso_c_binding @@ -644,9 +650,9 @@ integer(c_int32_t) function qmckl_ao_gaussian_vgl(context, X, R, n, A, VGL, ldv) integer, external :: qmckl_ao_gaussian_vgl_f info = qmckl_ao_gaussian_vgl_f(context, X, R, n, A, VGL, ldv) end function qmckl_ao_gaussian_vgl - #+END_SRC + #+end_src - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) + #+begin_src f90 :tangle (eval fh) interface integer(c_int32_t) function qmckl_ao_gaussian_vgl(context, X, R, n, A, VGL, ldv) & bind(C) @@ -658,9 +664,9 @@ end function qmckl_ao_gaussian_vgl real (c_double) , intent(out) :: VGL(ldv,5) end function qmckl_ao_gaussian_vgl end interface - #+END_SRC -***** Test :noexport: - #+BEGIN_SRC f90 :tangle (org-entry-get nil "f_test" t) + #+end_src +*** Test :noexport: + #+begin_src f90 :tangle (eval f_test) integer(c_int32_t) function test_qmckl_ao_gaussian_vgl(context) bind(C) use qmckl implicit none @@ -725,27 +731,26 @@ integer(c_int32_t) function test_qmckl_ao_gaussian_vgl(context) bind(C) deallocate(VGL) end function test_qmckl_ao_gaussian_vgl - #+END_SRC + #+end_src - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) -int test_qmckl_ao_gaussian_vgl(qmckl_context context); + #+begin_src c :tangle (eval c_test) :exports none +int test_qmckl_ao_gaussian_vgl(qmckl_context context); munit_assert_int(0, ==, test_qmckl_ao_gaussian_vgl(context)); - #+END_SRC + #+end_src - -*** TODO Slater basis functions +* TODO Slater basis functions -*** End of files :noexport: +* End of files :noexport: -***** Test - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) +*** Test + #+begin_src c :tangle (eval c_test) if (qmckl_context_destroy(context) != QMCKL_SUCCESS) return QMCKL_FAILURE; return MUNIT_OK; } - #+END_SRC + #+end_src - # -*- mode: org -*- - # vim: syntax=c +# -*- mode: org -*- +# vim: syntax=c diff --git a/src/qmckl_context.org b/src/qmckl_context.org index fc8f0da..6edfe2c 100644 --- a/src/qmckl_context.org +++ b/src/qmckl_context.org @@ -1,101 +1,78 @@ -** Context - :PROPERTIES: - :c: qmckl_context.c - :c_test: test_qmckl_context.c - :fh: qmckl_f.f90 - :h: qmckl.h - :END: +#+TITLE: Context +#+SETUPFILE: ../docs/theme.setup - This file is written in C because it is more natural to express the - context in C than in Fortran. + This file is written in C because it is more natural to express the + context in C than in Fortran. - 2 files are produced: - - a source file : =qmckl_context.c= - - a test file : =test_qmckl_context.c= + The context variable is a handle for the state of the library, + and is stored in a data structure, which can't be seen outside of + the library. To simplify compatibility with other languages, the + pointer to the internal data structure is converted into a 64-bit + signed integer, defined in the ~qmckl_context~ type. A value of ~0~ + for the context is equivalent to a ~NULL~ pointer. -*** Headers :noexport: - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) -#include "qmckl.h" -#include -#include -#include - #+END_SRC + #+begin_src c :comments org :tangle (eval h) +typedef int64_t qmckl_context ; + #+end_src - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) +* Headers :noexport: + + #+NAME: filename + #+begin_src elisp tangle: no +(file-name-nondirectory (substring buffer-file-name 0 -4)) + #+end_src + + + #+begin_src c :tangle (eval c_test) :noweb yes #include "qmckl.h" #include "munit.h" -MunitResult test_qmckl_context() { - #+END_SRC +MunitResult test_<>() { + #+end_src -*** Context + #+begin_src c :tangle (eval h_private) +#ifndef __QMCKL_CONTEXT__ +#define __QMCKL_CONTEXT__ - The <<>> variable is a handle for the state of the library, and - is stored in the following data structure, which can't be seen - outside of the library. To simplify compatibility with other - languages, the pointer to the internal data structure is converted - into a 64-bit signed integer, defined in the ~qmckl_context~ type. - A value of ~0~ for the context is equivalent to a ~NULL~ pointer. +#include +#include "qmckl_error.h" - #+BEGIN_SRC C :comments org :tangle qmckl.h -typedef int64_t qmckl_context ; - #+END_SRC + #+end_src -**** Data for error handling + #+begin_src c :tangle (eval c) +#include +#include +#include +#include +#include - We define here the the data structure containing the strings - necessary for error handling. - - #+BEGIN_SRC C :comments org :tangle qmckl.h -#define QMCKL_MAX_FUN_LEN 256 -#define QMCKL_MAX_MSG_LEN 1024 +#include "qmckl_error.h" +#include "qmckl_context_private.h" +#include "qmckl_context.h" +#include "qmckl_memory.h" +#include "qmckl_precision.h" -typedef struct qmckl_error_struct { + #+end_src - qmckl_exit_code exit_code; - char function[QMCKL_MAX_FUN_LEN]; - char message [QMCKL_MAX_MSG_LEN]; -} qmckl_error_struct; - #+END_SRC +* Context handling - -**** Basis set data structure + The tag is used internally to check if the memory domain pointed + by a pointer is a valid <<>>. - Data structure for the info related to the atomic orbitals - basis set. + #+begin_src c :comments org :tangle (eval h_private) :noweb yes +<> +<> - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) -typedef struct qmckl_ao_basis_struct { - - int64_t shell_num; - int64_t prim_num; - int64_t * shell_center; - int32_t * shell_ang_mom; - double * shell_factor; - double * exponent ; - double * coefficient ; - int64_t * shell_prim_num; - char type; - -} qmckl_ao_basis_struct; - #+END_SRC - -***** Source - - The tag is used internally to check if the memory domain pointed - by a pointer is a valid context. - - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) typedef struct qmckl_context_struct { struct qmckl_context_struct * prev; /* Molecular system */ - // struct qmckl_nucleus_struct * nucleus; - // struct qmckl_electron_struct * electron; - struct qmckl_ao_basis_struct * ao_basis; - // struct qmckl_mo_struct * mo; - // struct qmckl_determinant_struct * det; + // qmckl_nucleus_struct * nucleus; + // qmckl_electron_struct * electron; + qmckl_ao_basis_struct * ao_basis; + // qmckl_mo_struct * mo; + // qmckl_determinant_struct * det; /* Numerical precision */ uint32_t tag; @@ -103,105 +80,26 @@ typedef struct qmckl_context_struct { int32_t range; /* Error handling */ - struct qmckl_error_struct * error; + qmckl_error_struct * error; } qmckl_context_struct; #define VALID_TAG 0xBEEFFACE #define INVALID_TAG 0xDEADBEEF - #+END_SRC + #+end_src -**** ~qmckl_context_update_error~ +** ~qmckl_context_check~ - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) -qmckl_exit_code -qmckl_context_update_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message); - #+END_SRC + Checks if the domain pointed by the pointer is a valid context. + Returns the input ~qmckl_context~ if the context is valid, 0 + otherwise. -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) -qmckl_exit_code -qmckl_context_update_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message) -{ - assert (context != 0); - assert (function != NULL); - assert (message != NULL); - assert (exit_code > 0); - assert (exit_code < QMCKL_INVALID_EXIT_CODE); - - qmckl_context_struct* ctx = (qmckl_context_struct*) context; - if (ctx == NULL) return QMCKL_FAILURE; - - if (ctx->error != NULL) { - free(ctx->error); - ctx->error = NULL; - } - - qmckl_error_struct* error = (qmckl_error_struct*) qmckl_malloc (context, sizeof(qmckl_error_struct)); - error->exit_code = exit_code; - strcpy(error->function, function); - strcpy(error->message, message); - - ctx->error = error; - - return QMCKL_SUCCESS; -} - #+END_SRC - -***** TODO Test - -**** ~qmckl_context_set_error~ - - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) -qmckl_context -qmckl_context_set_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message); - #+END_SRC - -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) -qmckl_context -qmckl_context_set_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message) -{ - assert (context != 0); - assert (function != NULL); - assert (message != NULL); - assert (exit_code > 0); - assert (exit_code < QMCKL_INVALID_EXIT_CODE); - - qmckl_context new_context = qmckl_context_copy(context); - if (new_context == 0) return context; - - if (qmckl_context_update_error(new_context, exit_code, - function, message) != QMCKL_SUCCESS) { - return context; - } - - return new_context; -} - #+END_SRC - -***** TODO Test - -***** Test :noexport: - - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) -qmckl_context context; -qmckl_context new_context; - #+END_SRC - - -**** ~qmckl_context_check~ - - Checks if the domain pointed by the pointer is a valid context. - Returns the input ~qmckl_context~ if the context is valid, 0 - otherwise. - - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) + #+begin_src c :comments org :tangle (eval h) qmckl_context qmckl_context_check(const qmckl_context context) ; - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_context qmckl_context_check(const qmckl_context context) { if (context == (qmckl_context) 0) return (qmckl_context) 0; @@ -212,20 +110,20 @@ qmckl_context qmckl_context_check(const qmckl_context context) { return context; } - #+END_SRC + #+end_src -**** ~qmckl_context_create~ +** ~qmckl_context_create~ - To create a new context, use ~qmckl_context_create()~. - - On success, returns a pointer to a context using the ~qmckl_context~ type - - Returns ~0~ upon failure to allocate the internal data structure + To create a new context, use ~qmckl_context_create()~. + - On success, returns a pointer to a context using the ~qmckl_context~ type + - Returns ~0~ upon failure to allocate the internal data structure - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) + #+begin_src c :comments org :tangle (eval h) qmckl_context qmckl_context_create(); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_context qmckl_context_create() { qmckl_context_struct* context = @@ -243,38 +141,38 @@ qmckl_context qmckl_context_create() { return (qmckl_context) context; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int64_t) function qmckl_context_create() bind(C) use, intrinsic :: iso_c_binding end function qmckl_context_create end interface - #+END_SRC + #+end_src -***** Test :noexport: - #+BEGIN_SRC C :comments link :tangle (org-entry-get nil "c_test" t) -context = qmckl_context_create(); +*** Test :noexport: + #+begin_src c :comments link :tangle (eval c_test) +qmckl_context context = qmckl_context_create(); munit_assert_int64( context, !=, (qmckl_context) 0); munit_assert_int64( qmckl_context_check(context), ==, context); - #+END_SRC + #+end_src -**** ~qmckl_context_copy~ +** ~qmckl_context_copy~ - This function makes a shallow copy of the current context. - - Copying the 0-valued context returns 0 - - On success, returns a pointer to the new context using the ~qmckl_context~ type - - Returns 0 upon failure to allocate the internal data structure - for the new context + This function makes a shallow copy of the current context. + - Copying the 0-valued context returns 0 + - On success, returns a pointer to the new context using the ~qmckl_context~ type + - Returns 0 upon failure to allocate the internal data structure + for the new context - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) + #+begin_src c :comments org :tangle (eval h) qmckl_context qmckl_context_copy(const qmckl_context context); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_context qmckl_context_copy(const qmckl_context context) { const qmckl_context checked_context = qmckl_context_check(context); @@ -301,39 +199,39 @@ qmckl_context qmckl_context_copy(const qmckl_context context) { return (qmckl_context) new_context; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int64_t) function qmckl_context_copy(context) bind(C) use, intrinsic :: iso_c_binding integer (c_int64_t), intent(in), value :: context end function qmckl_context_copy end interface - #+END_SRC + #+end_src -***** Test :noexport: - #+BEGIN_SRC C :comments link :tangle (org-entry-get nil "c_test" t) -new_context = qmckl_context_copy(context); +*** Test :noexport: + #+begin_src c :comments link :tangle (eval c_test) +qmckl_context new_context = qmckl_context_copy(context); munit_assert_int64(new_context, !=, (qmckl_context) 0); munit_assert_int64(new_context, !=, context); munit_assert_int64(qmckl_context_check(new_context), ==, new_context); - #+END_SRC + #+end_src -**** ~qmckl_context_previous~ +** ~qmckl_context_previous~ - Returns the previous context - - On success, returns the ancestor of the current context - - Returns 0 for the initial context - - Returns 0 for the 0-valued context + Returns the previous context + - On success, returns the ancestor of the current context + - Returns 0 for the initial context + - Returns 0 for the 0-valued context - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) + #+begin_src c :comments org :tangle (eval h) qmckl_context qmckl_context_previous(const qmckl_context context); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_context qmckl_context_previous(const qmckl_context context) { const qmckl_context checked_context = qmckl_context_check(context); @@ -344,40 +242,40 @@ qmckl_context qmckl_context_previous(const qmckl_context context) { const qmckl_context_struct* ctx = (qmckl_context_struct*) checked_context; return qmckl_context_check((qmckl_context) ctx->prev); } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int64_t) function qmckl_context_previous(context) bind(C) use, intrinsic :: iso_c_binding integer (c_int64_t), intent(in), value :: context end function qmckl_context_previous end interface - #+END_SRC + #+end_src -***** Test :noexport: - #+BEGIN_SRC C :comments link :tangle (org-entry-get nil "c_test" t) +*** Test :noexport: + #+begin_src c :comments link :tangle (eval c_test) munit_assert_int64(qmckl_context_previous(new_context), !=, (qmckl_context) 0); munit_assert_int64(qmckl_context_previous(new_context), ==, context); munit_assert_int64(qmckl_context_previous(context), ==, (qmckl_context) 0); munit_assert_int64(qmckl_context_previous((qmckl_context) 0), ==, (qmckl_context) 0); - #+END_SRC + #+end_src -**** ~qmckl_context_destroy~ +** ~qmckl_context_destroy~ - Destroys the current context, leaving the ancestors untouched. - - Succeeds if the current context is properly destroyed - - Fails otherwise - - Fails if the 0-valued context is given in argument - - Fails if the the pointer is not a valid context + Destroys the current context, leaving the ancestors untouched. + - Succeeds if the current context is properly destroyed + - Fails otherwise + - Fails if the 0-valued context is given in argument + - Fails if the the pointer is not a valid context - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) + #+begin_src c :comments org :tangle (eval h) qmckl_exit_code qmckl_context_destroy(qmckl_context context); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_exit_code qmckl_context_destroy(const qmckl_context context) { const qmckl_context checked_context = qmckl_context_check(context); @@ -389,33 +287,170 @@ qmckl_exit_code qmckl_context_destroy(const qmckl_context context) { ctx->tag = INVALID_TAG; return qmckl_free(context,ctx); } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int32_t) function qmckl_context_destroy(context) bind(C) use, intrinsic :: iso_c_binding integer (c_int64_t), intent(in), value :: context end function qmckl_context_destroy end interface - #+END_SRC + #+end_src -***** Test :noexport: - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) +*** Test :noexport: + #+begin_src c :tangle (eval c_test) munit_assert_int64(qmckl_context_check(new_context), ==, new_context); munit_assert_int64(new_context, !=, (qmckl_context) 0); munit_assert_int32(qmckl_context_destroy(new_context), ==, QMCKL_SUCCESS); munit_assert_int64(qmckl_context_check(new_context), !=, new_context); munit_assert_int64(qmckl_context_check(new_context), ==, (qmckl_context) 0); munit_assert_int64(qmckl_context_destroy((qmckl_context) 0), ==, QMCKL_FAILURE); - #+END_SRC + #+end_src -**** Basis set +* Error handling +** Data structure + + #+NAME: qmckl_error_struct + #+begin_src c :comments org +#define QMCKL_MAX_FUN_LEN 256 +#define QMCKL_MAX_MSG_LEN 1024 - For H_2 with the following basis set, +typedef struct qmckl_error_struct { - #+BEGIN_EXAMPLE + qmckl_exit_code exit_code; + char function[QMCKL_MAX_FUN_LEN]; + char message [QMCKL_MAX_MSG_LEN]; + +} qmckl_error_struct; + #+end_src + +** ~qmckl_context_update_error~ + + #+begin_src c :comments org :tangle (eval h) +qmckl_exit_code +qmckl_context_update_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message); + #+end_src + +*** Source + #+begin_src c :tangle (eval c) +qmckl_exit_code +qmckl_context_update_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message) +{ + assert (context != 0); + assert (function != NULL); + assert (message != NULL); + assert (exit_code > 0); + assert (exit_code < QMCKL_INVALID_EXIT_CODE); + + qmckl_context_struct* ctx = (qmckl_context_struct*) context; + if (ctx == NULL) return QMCKL_FAILURE; + + if (ctx->error != NULL) { + free(ctx->error); + ctx->error = NULL; + } + + qmckl_error_struct* error = (qmckl_error_struct*) qmckl_malloc (context, sizeof(qmckl_error_struct)); + error->exit_code = exit_code; + strcpy(error->function, function); + strcpy(error->message, message); + + ctx->error = error; + + return QMCKL_SUCCESS; +} + #+end_src + +*** TODO Test + +** ~qmckl_context_set_error~ + + #+begin_src c :comments org :tangle (eval h) +qmckl_context +qmckl_context_set_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message); + #+end_src + +*** Source + #+begin_src c :tangle (eval c) +qmckl_context +qmckl_context_set_error(qmckl_context context, const qmckl_exit_code exit_code, const char* function, const char* message) +{ + assert (context != 0); + assert (function != NULL); + assert (message != NULL); + assert (exit_code > 0); + assert (exit_code < QMCKL_INVALID_EXIT_CODE); + + qmckl_context new_context = qmckl_context_copy(context); + if (new_context == 0) return context; + + if (qmckl_context_update_error(new_context, exit_code, + function, message) != QMCKL_SUCCESS) { + return context; + } + + return new_context; +} + #+end_src + +*** TODO Test + +*** Test :noexport: + +** ~qmckl_failwith~ + + To make a function fail, the <<<~qmckl_failwith~>>> function should be + called, such that information about the failure is stored in + the context. The desired exit code is given as an argument, as + well as the name of the function and an error message. The return + code of the function is the desired return code. + + #+begin_src c :comments org :tangle (eval h) +qmckl_exit_code qmckl_failwith(qmckl_context context, + const qmckl_exit_code exit_code, + const char* function, + const char* message) ; + #+end_src + + #+begin_src c :comments org :tangle (eval c) +qmckl_exit_code qmckl_failwith(qmckl_context context, + const qmckl_exit_code exit_code, + const char* function, + const char* message) { + + if (context == 0) return QMCKL_NULL_CONTEXT; + assert (exit_code > 0); + assert (exit_code < QMCKL_INVALID_EXIT_CODE); + assert (function != NULL); + assert (message != NULL); + assert (strlen(function) < QMCKL_MAX_FUN_LEN); + assert (strlen(message) < QMCKL_MAX_MSG_LEN); + + context = qmckl_context_set_error(context, exit_code, function, message); + return exit_code; +} + + #+end_src + + For example, this function can be used as + #+begin_src c :tangle no +if (x < 0) { + return qmckl_failwith(context, + QMCKL_INVALID_ARG_2, + "qmckl_function", + "Expected x >= 0"); + } + #+end_src + + # To decode the error messages, ~qmckl_strerror~ converts an + # error code into a string. +* Basis set + + For H_2 with the following basis set, + + #+BEGIN_EXAMPLE HYDROGEN S 5 1 3.387000E+01 6.068000E-03 @@ -433,11 +468,11 @@ P 1 1 3.880000E-01 1.000000E+00 D 1 1 1.057000E+00 1.0000000 - #+END_EXAMPLE + #+END_EXAMPLE - we have: + we have: - #+BEGIN_EXAMPLE + #+BEGIN_EXAMPLE type = 'G' shell_num = 12 prim_num = 20 @@ -451,24 +486,43 @@ EXPONENT = [ 33.87, 5.095, 1.159, 0.3258, 0.1027, 0.3258, 0.1027, COEFFICIENT = [ 0.006068, 0.045308, 0.202822, 0.503903, 0.383421, 1.0, 1.0, 1.0, 1.0, 1.0, 0.006068, 0.045308, 0.202822, 0.503903, 0.383421, 1.0, 1.0, 1.0, 1.0, 1.0] - #+END_EXAMPLE + #+END_EXAMPLE -**** ~qmckl_context_update_ao_basis~ +** Data structure - Updates the data describing the AO basis set into the context. + #+NAME: qmckl_ao_basis_struct + #+begin_src c :comments org :tangle no +typedef struct qmckl_ao_basis_struct { - | ~type~ | Gaussian or Slater | - | ~shell_num~ | Number of shells | - | ~prim_num~ | Total number of primitives | - | ~SHELL_CENTER(shell_num)~ | Id of the nucleus on which the shell is centered | - | ~SHELL_ANG_MOM(shell_num)~ | Id of the nucleus on which the shell is centered | - | ~SHELL_FACTOR(shell_num)~ | Normalization factor for the shell | - | ~SHELL_PRIM_NUM(shell_num)~ | Number of primitives in the shell | - | ~SHELL_PRIM_INDEX(shell_num)~ | Address of the first primitive of the shelll in the ~EXPONENT~ array | - | ~EXPONENT(prim_num)~ | Array of exponents | - | ~COEFFICIENT(prim_num)~ | Array of coefficients | + int64_t shell_num; + int64_t prim_num; + int64_t * shell_center; + int32_t * shell_ang_mom; + double * shell_factor; + double * exponent ; + double * coefficient ; + int64_t * shell_prim_num; + char type; - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +} qmckl_ao_basis_struct; + #+end_src + +** ~qmckl_context_update_ao_basis~ + + Updates the data describing the AO basis set into the context. + + | ~type~ | Gaussian or Slater | + | ~shell_num~ | Number of shells | + | ~prim_num~ | Total number of primitives | + | ~SHELL_CENTER(shell_num)~ | Id of the nucleus on which the shell is centered | + | ~SHELL_ANG_MOM(shell_num)~ | Id of the nucleus on which the shell is centered | + | ~SHELL_FACTOR(shell_num)~ | Normalization factor for the shell | + | ~SHELL_PRIM_NUM(shell_num)~ | Number of primitives in the shell | + | ~SHELL_PRIM_INDEX(shell_num)~ | Address of the first primitive of the shelll in the ~EXPONENT~ array | + | ~EXPONENT(prim_num)~ | Array of exponents | + | ~COEFFICIENT(prim_num)~ | Array of coefficients | + + #+begin_src c :comments org :tangle (eval h) qmckl_exit_code qmckl_context_update_ao_basis(qmckl_context context , const char type, const int64_t shell_num , const int64_t prim_num, @@ -476,10 +530,10 @@ qmckl_context_update_ao_basis(qmckl_context context , const char type const double * SHELL_FACTOR, const int64_t * SHELL_PRIM_NUM, const int64_t * SHELL_PRIM_INDEX, const double * EXPONENT , const double * COEFFICIENT); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_exit_code qmckl_context_update_ao_basis(qmckl_context context , const char type, const int64_t shell_num , const int64_t prim_num, @@ -591,10 +645,10 @@ qmckl_context_update_ao_basis(qmckl_context context , const char type ctx->ao_basis = basis; return QMCKL_SUCCESS; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int32_t) function qmckl_context_update_ao_basis(context, & typ, shell_num, prim_num, SHELL_CENTER, SHELL_ANG_MOM, SHELL_FACTOR, & @@ -613,26 +667,26 @@ qmckl_context_update_ao_basis(qmckl_context context , const char type double precision , intent(in) :: COEFFICIENT(prim_num) end function qmckl_context_update_ao_basis end interface - #+END_SRC + #+end_src -***** TODO Test +*** TODO Test -**** ~qmckl_context_set_ao_basis~ +** ~qmckl_context_set_ao_basis~ - Sets the data describing the AO basis set into the context. + Sets the data describing the AO basis set into the context. - | ~type~ | Gaussian or Slater | - | ~shell_num~ | Number of shells | - | ~prim_num~ | Total number of primitives | - | ~SHELL_CENTER(shell_num)~ | Id of the nucleus on which the shell is centered | - | ~SHELL_ANG_MOM(shell_num)~ | Id of the nucleus on which the shell is centered | - | ~SHELL_FACTOR(shell_num)~ | Normalization factor for the shell | - | ~SHELL_PRIM_NUM(shell_num)~ | Number of primitives in the shell | - | ~SHELL_PRIM_INDEX(shell_num)~ | Address of the first primitive of the shelll in the ~EXPONENT~ array | - | ~EXPONENT(prim_num)~ | Array of exponents | - | ~COEFFICIENT(prim_num)~ | Array of coefficients | + | ~type~ | Gaussian or Slater | + | ~shell_num~ | Number of shells | + | ~prim_num~ | Total number of primitives | + | ~SHELL_CENTER(shell_num)~ | Id of the nucleus on which the shell is centered | + | ~SHELL_ANG_MOM(shell_num)~ | Id of the nucleus on which the shell is centered | + | ~SHELL_FACTOR(shell_num)~ | Normalization factor for the shell | + | ~SHELL_PRIM_NUM(shell_num)~ | Number of primitives in the shell | + | ~SHELL_PRIM_INDEX(shell_num)~ | Address of the first primitive of the shelll in the ~EXPONENT~ array | + | ~EXPONENT(prim_num)~ | Array of exponents | + | ~COEFFICIENT(prim_num)~ | Array of coefficients | - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) + #+begin_src c :comments org :tangle (eval h) qmckl_context qmckl_context_set_ao_basis(const qmckl_context context , const char type, const int64_t shell_num , const int64_t prim_num, @@ -640,10 +694,10 @@ qmckl_context_set_ao_basis(const qmckl_context context , const char typ const double * SHELL_FACTOR, const int64_t * SHELL_PRIM_NUM, const int64_t * SHELL_PRIM_INDEX, const double * EXPONENT , const double * COEFFICIENT); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_context qmckl_context_set_ao_basis(const qmckl_context context , const char type, const int64_t shell_num , const int64_t prim_num, @@ -665,10 +719,10 @@ qmckl_context_set_ao_basis(const qmckl_context context , const char typ return new_context; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int64_t) function qmckl_context_set_ao_basis(context, & typ, shell_num, prim_num, SHELL_CENTER, SHELL_ANG_MOM, SHELL_FACTOR, & @@ -687,29 +741,29 @@ qmckl_context_set_ao_basis(const qmckl_context context , const char typ double precision , intent(in) :: COEFFICIENT(prim_num) end function qmckl_context_set_ao_basis end interface - #+END_SRC + #+end_src -***** TODO Test +*** TODO Test -**** Precision +* Precision - The following functions set and get the expected required - precision and range. ~precision~ should be an integer between 2 - and 53, and ~range~ should be an integer between 2 and 11. + The following functions set and get the expected required + precision and range. ~precision~ should be an integer between 2 + and 53, and ~range~ should be an integer between 2 and 11. - The setter functions functions return a new context as a 64-bit - integer. The getter functions return the value, as a 32-bit - integer. The update functions return ~QMCKL_SUCCESS~ or - ~QMCKL_FAILURE~. + The setter functions functions return a new context as a 64-bit + integer. The getter functions return the value, as a 32-bit + integer. The update functions return ~QMCKL_SUCCESS~ or + ~QMCKL_FAILURE~. -**** ~qmckl_context_update_precision~ - Modifies the parameter for the numerical precision in a given context. - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +** ~qmckl_context_update_precision~ + Modifies the parameter for the numerical precision in a given context. + #+begin_src c :comments org :tangle (eval h) qmckl_exit_code qmckl_context_update_precision(const qmckl_context context, const int precision); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_exit_code qmckl_context_update_precision(const qmckl_context context, const int precision) { if (precision < 2) return QMCKL_FAILURE; @@ -721,10 +775,10 @@ qmckl_exit_code qmckl_context_update_precision(const qmckl_context context, cons ctx->precision = precision; return QMCKL_SUCCESS; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int32_t) function qmckl_context_update_precision(context, precision) bind(C) use, intrinsic :: iso_c_binding @@ -732,17 +786,17 @@ qmckl_exit_code qmckl_context_update_precision(const qmckl_context context, cons integer (c_int32_t), intent(in), value :: precision end function qmckl_context_update_precision end interface - #+END_SRC + #+end_src -***** TODO Tests :noexport: -**** ~qmckl_context_update_range~ - Modifies the parameter for the numerical range in a given context. - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +*** TODO Tests :noexport: +** ~qmckl_context_update_range~ + Modifies the parameter for the numerical range in a given context. + #+begin_src c :comments org :tangle (eval h) qmckl_exit_code qmckl_context_update_range(const qmckl_context context, const int range); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_exit_code qmckl_context_update_range(const qmckl_context context, const int range) { if (range < 2) return QMCKL_FAILURE; @@ -754,10 +808,10 @@ qmckl_exit_code qmckl_context_update_range(const qmckl_context context, const in ctx->range = range; return QMCKL_SUCCESS; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int32_t) function qmckl_context_update_range(context, range) bind(C) use, intrinsic :: iso_c_binding @@ -765,17 +819,17 @@ qmckl_exit_code qmckl_context_update_range(const qmckl_context context, const in integer (c_int32_t), intent(in), value :: range end function qmckl_context_update_range end interface - #+END_SRC + #+end_src -***** TODO Tests :noexport: -**** ~qmckl_context_set_precision~ - Returns a copy of the context with a different precision parameter. - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +*** TODO Tests :noexport: +** ~qmckl_context_set_precision~ + Returns a copy of the context with a different precision parameter. + #+begin_src c :comments org :tangle (eval h) qmckl_context qmckl_context_set_precision(const qmckl_context context, const int precision); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_context qmckl_context_set_precision(const qmckl_context context, const int precision) { qmckl_context new_context = qmckl_context_copy(context); if (new_context == 0) return 0; @@ -784,10 +838,10 @@ qmckl_context qmckl_context_set_precision(const qmckl_context context, const int return new_context; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int64_t) function qmckl_context_set_precision(context, precision) bind(C) use, intrinsic :: iso_c_binding @@ -795,17 +849,17 @@ qmckl_context qmckl_context_set_precision(const qmckl_context context, const int integer (c_int32_t), intent(in), value :: precision end function qmckl_context_set_precision end interface - #+END_SRC + #+end_src -***** TODO Tests :noexport: -**** ~qmckl_context_set_range~ - Returns a copy of the context with a different precision parameter. - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +*** TODO Tests :noexport: +** ~qmckl_context_set_range~ + Returns a copy of the context with a different precision parameter. + #+begin_src c :comments org :tangle (eval h) qmckl_context qmckl_context_set_range(const qmckl_context context, const int range); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) qmckl_context qmckl_context_set_range(const qmckl_context context, const int range) { qmckl_context new_context = qmckl_context_copy(context); if (new_context == 0) return 0; @@ -814,10 +868,10 @@ qmckl_context qmckl_context_set_range(const qmckl_context context, const int ran return new_context; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int64_t) function qmckl_context_set_range(context, range) bind(C) use, intrinsic :: iso_c_binding @@ -825,98 +879,101 @@ qmckl_context qmckl_context_set_range(const qmckl_context context, const int ran integer (c_int32_t), intent(in), value :: range end function qmckl_context_set_range end interface - #+END_SRC + #+end_src -***** TODO Tests :noexport: +*** TODO Tests :noexport: -**** ~qmckl_context_get_precision~ - Returns the value of the numerical precision in the context - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +** ~qmckl_context_get_precision~ + Returns the value of the numerical precision in the context + #+begin_src c :comments org :tangle (eval h) int32_t qmckl_context_get_precision(const qmckl_context context); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) int qmckl_context_get_precision(const qmckl_context context) { const qmckl_context_struct* ctx = (qmckl_context_struct*) context; return ctx->precision; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int32_t) function qmckl_context_get_precision(context) bind(C) use, intrinsic :: iso_c_binding integer (c_int64_t), intent(in), value :: context end function qmckl_context_get_precision end interface - #+END_SRC + #+end_src -***** TODO Tests :noexport: -**** ~qmckl_context_get_range~ - Returns the value of the numerical range in the context - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +*** TODO Tests :noexport: +** ~qmckl_context_get_range~ + Returns the value of the numerical range in the context + #+begin_src c :comments org :tangle (eval h) int32_t qmckl_context_get_range(const qmckl_context context); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) int qmckl_context_get_range(const qmckl_context context) { const qmckl_context_struct* ctx = (qmckl_context_struct*) context; return ctx->range; } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface integer (c_int32_t) function qmckl_context_get_range(context) bind(C) use, intrinsic :: iso_c_binding integer (c_int64_t), intent(in), value :: context end function qmckl_context_get_range end interface - #+END_SRC + #+end_src -***** TODO Tests :noexport: +*** TODO Tests :noexport: -**** ~qmckl_context_get_epsilon~ - Returns $\epsilon = 2^{1-n}$ where ~n~ is the precision - #+BEGIN_SRC C :comments org :tangle (org-entry-get nil "h" t) +** ~qmckl_context_get_epsilon~ + Returns $\epsilon = 2^{1-n}$ where ~n~ is the precision + #+begin_src c :comments org :tangle (eval h) double qmckl_context_get_epsilon(const qmckl_context context); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) +*** Source + #+begin_src c :tangle (eval c) double qmckl_context_get_epsilon(const qmckl_context context) { const qmckl_context_struct* ctx = (qmckl_context_struct*) context; return pow(2.0,(double) 1-ctx->precision); } - #+END_SRC + #+end_src -***** Fortran interface - #+BEGIN_SRC f90 :tangle (org-entry-get nil "fh" t) +*** Fortran interface + #+begin_src f90 :tangle (eval fh) interface real (c_double) function qmckl_context_get_epsilon(context) bind(C) use, intrinsic :: iso_c_binding integer (c_int64_t), intent(in), value :: context end function qmckl_context_get_epsilon end interface - #+END_SRC + #+end_src -***** TODO Tests :noexport: +*** TODO Tests :noexport: +* End of files :noexport: + #+begin_src c :comments link :tangle (eval h_private) -*** End of files :noexport: - -***** Test - #+BEGIN_SRC C :comments link :tangle (org-entry-get nil "c_test" t) +#endif + #+end_src + +*** Test + #+begin_src c :comments link :tangle (eval c_test) return MUNIT_OK; } - #+END_SRC + #+end_src - # -*- mode: org -*- - # vim: syntax=c +# -*- mode: org -*- +# vim: syntax=c diff --git a/src/qmckl_distance.org b/src/qmckl_distance.org index 57e5531..e797393 100644 --- a/src/qmckl_distance.org +++ b/src/qmckl_distance.org @@ -1,77 +1,78 @@ -** Computation of distances +#+TITLE: Distances +#+SETUPFILE: ../docs/theme.setup - Function for the computation of distances between particles. +Functions for the computation of distances between particles. - 3 files are produced: - - a source file : =qmckl_distance.f90= - - a C test file : =test_qmckl_distance.c= - - a Fortran test file : =test_qmckl_distance_f.f90= +* Headers :noexport: -**** Headers :noexport: - #+BEGIN_SRC C :comments link :tangle test_qmckl_distance.c + #+NAME: filename + #+begin_src elisp tangle: no +(file-name-nondirectory (substring buffer-file-name 0 -4)) + #+end_src + + #+begin_src c :comments link :tangle (eval c_test) :noweb yes #include "qmckl.h" #include "munit.h" -MunitResult test_qmckl_distance() { +MunitResult test_<>() { qmckl_context context; context = qmckl_context_create(); - #+END_SRC + #+end_src +* Squared distance -*** Squared distance +** ~qmckl_distance_sq~ -**** ~qmckl_distance_sq~ + Computes the matrix of the squared distances between all pairs of + points in two sets, one point within each set: + \[ + C_{ij} = \sum_{k=1}^3 (A_{k,i}-B_{k,j})^2 + \] - Computes the matrix of the squared distances between all pairs of - points in two sets, one point within each set: - \[ - C_{ij} = \sum_{k=1}^3 (A_{k,i}-B_{k,j})^2 - \] +*** Arguments -***** Arguments + | ~context~ | input | Global state | + | ~transa~ | input | Array ~A~ is ~N~: Normal, ~T~: Transposed | + | ~transb~ | input | Array ~B~ is ~N~: Normal, ~T~: Transposed | + | ~m~ | input | Number of points in the first set | + | ~n~ | input | Number of points in the second set | + | ~A(lda,3)~ | input | Array containing the $m \times 3$ matrix $A$ | + | ~lda~ | input | Leading dimension of array ~A~ | + | ~B(ldb,3)~ | input | Array containing the $n \times 3$ matrix $B$ | + | ~ldb~ | input | Leading dimension of array ~B~ | + | ~C(ldc,n)~ | output | Array containing the $m \times n$ matrix $C$ | + | ~ldc~ | input | Leading dimension of array ~C~ | - | ~context~ | input | Global state | - | ~transa~ | input | Array ~A~ is ~N~: Normal, ~T~: Transposed | - | ~transb~ | input | Array ~B~ is ~N~: Normal, ~T~: Transposed | - | ~m~ | input | Number of points in the first set | - | ~n~ | input | Number of points in the second set | - | ~A(lda,3)~ | input | Array containing the $m \times 3$ matrix $A$ | - | ~lda~ | input | Leading dimension of array ~A~ | - | ~B(ldb,3)~ | input | Array containing the $n \times 3$ matrix $B$ | - | ~ldb~ | input | Leading dimension of array ~B~ | - | ~C(ldc,n)~ | output | Array containing the $m \times n$ matrix $C$ | - | ~ldc~ | input | Leading dimension of array ~C~ | +*** Requirements -***** Requirements + - ~context~ is not 0 + - ~m~ > 0 + - ~n~ > 0 + - ~lda~ >= 3 if ~transa~ is ~N~ + - ~lda~ >= m if ~transa~ is ~T~ + - ~ldb~ >= 3 if ~transb~ is ~N~ + - ~ldb~ >= n if ~transb~ is ~T~ + - ~ldc~ >= m + - ~A~ is allocated with at least $3 \times m \times 8$ bytes + - ~B~ is allocated with at least $3 \times n \times 8$ bytes + - ~C~ is allocated with at least $m \times n \times 8$ bytes - - ~context~ is not 0 - - ~m~ > 0 - - ~n~ > 0 - - ~lda~ >= 3 if ~transa~ is ~N~ - - ~lda~ >= m if ~transa~ is ~T~ - - ~ldb~ >= 3 if ~transb~ is ~N~ - - ~ldb~ >= n if ~transb~ is ~T~ - - ~ldc~ >= m - - ~A~ is allocated with at least $3 \times m \times 8$ bytes - - ~B~ is allocated with at least $3 \times n \times 8$ bytes - - ~C~ is allocated with at least $m \times n \times 8$ bytes +*** Performance -***** Performance + This function might be more efficient when ~A~ and ~B~ are + transposed. - This function might be more efficient when ~A~ and ~B~ are - transposed. - - #+BEGIN_SRC C :comments org :tangle qmckl.h + #+begin_src c :comments org :tangle (eval h) qmckl_exit_code qmckl_distance_sq(const qmckl_context context, const char transa, const char transb, const int64_t m, const int64_t n, const double *A, const int64_t lda, const double *B, const int64_t ldb, const double *C, const int64_t ldc); - #+END_SRC + #+end_src -***** Source - #+BEGIN_SRC f90 :tangle qmckl_distance.f90 +*** Source + #+begin_src f90 :tangle (eval f) integer function qmckl_distance_sq_f(context, transa, transb, m, n, A, LDA, B, LDB, C, LDC) result(info) implicit none integer*8 , intent(in) :: context @@ -196,10 +197,10 @@ integer function qmckl_distance_sq_f(context, transa, transb, m, n, A, LDA, B, L end select end function qmckl_distance_sq_f - #+END_SRC - -***** C interface :noexport: - #+BEGIN_SRC f90 :tangle qmckl_distance.f90 + #+end_src + +*** C interface :noexport: + #+begin_src f90 :tangle (eval f) integer(c_int32_t) function qmckl_distance_sq(context, transa, transb, m, n, A, LDA, B, LDB, C, LDC) & bind(C) result(info) use, intrinsic :: iso_c_binding @@ -217,9 +218,9 @@ integer(c_int32_t) function qmckl_distance_sq(context, transa, transb, m, n, A, integer, external :: qmckl_distance_sq_f info = qmckl_distance_sq_f(context, transa, transb, m, n, A, LDA, B, LDB, C, LDC) end function qmckl_distance_sq - #+END_SRC + #+end_src - #+BEGIN_SRC f90 :tangle qmckl_f.f90 + #+begin_src f90 :tangle (eval fh) interface integer(c_int32_t) function qmckl_distance_sq(context, transa, transb, m, n, A, LDA, B, LDB, C, LDC) & bind(C) @@ -236,10 +237,10 @@ end function qmckl_distance_sq real (c_double) , intent(out) :: C(ldc,n) end function qmckl_distance_sq end interface - #+END_SRC + #+end_src -***** Test :noexport: - #+BEGIN_SRC f90 :tangle test_qmckl_distance_f.f90 +*** Test :noexport: + #+begin_src f90 :tangle (eval f_test) integer(c_int32_t) function test_qmckl_distance_sq(context) bind(C) use qmckl implicit none @@ -335,22 +336,22 @@ integer(c_int32_t) function test_qmckl_distance_sq(context) bind(C) deallocate(A,B,C) end function test_qmckl_distance_sq - #+END_SRC + #+end_src - #+BEGIN_SRC C :comments link :tangle test_qmckl_distance.c + #+begin_src c :comments link :tangle (eval c_test) int test_qmckl_distance_sq(qmckl_context context); munit_assert_int(0, ==, test_qmckl_distance_sq(context)); - #+END_SRC -*** End of files :noexport: + #+end_src +* End of files :noexport: - #+BEGIN_SRC C :comments link :tangle test_qmckl_distance.c + #+begin_src c :comments link :tangle (eval c_test) if (qmckl_context_destroy(context) != QMCKL_SUCCESS) return QMCKL_FAILURE; return MUNIT_OK; } - #+END_SRC + #+end_src - # -*- mode: org -*- - # vim: syntax=c +# -*- mode: org -*- +# vim: syntax=c diff --git a/src/qmckl_error.org b/src/qmckl_error.org index dda5996..b1338e3 100644 --- a/src/qmckl_error.org +++ b/src/qmckl_error.org @@ -1,193 +1,138 @@ -# This file is part of the qmckl.h file -** Error handling - :PROPERTIES: - :c: qmckl_error.c - :c_test: test_qmckl_error.c - :fh: qmckl_f.f90 - :h: qmckl.h - :END: +#+TITLE: Error handling +#+SETUPFILE: ../docs/theme.setup - This file is written in C because it is more natural to express the - error handling in C than in Fortran. + This file is written in C because it is more natural to express the + error handling in C than in Fortran. - 2 files are produced: - - a source file : =qmckl_error.c= - - a test file : =test_qmckl_error.c= +** Headers :noexport: -*** Headers :noexport: - #+BEGIN_SRC C :tangle (org-entry-get nil "c" t) -#include "qmckl.h" -#include -#include -#include -#include - #+END_SRC + #+NAME: filename + #+begin_src elisp tangle: no +(file-name-nondirectory (substring buffer-file-name 0 -4)) + #+end_src - #+BEGIN_SRC C :tangle (org-entry-get nil "c_test" t) + #+begin_src c :tangle (eval c) +#include +#include "qmckl_error.h" + #+end_src + + #+begin_src c :tangle (eval c_test) :noweb yes #include "qmckl.h" #include "munit.h" -MunitResult test_qmckl_error() { - #+END_SRC +MunitResult test_<>() { + #+end_src -*** Error handling +** Error handling - The library should never make the calling programs abort, nor - perform any input/output operations. This decision has to be taken - by the developer of the code calling the library. + The library should never make the calling programs abort, nor + perform any input/output operations. This decision has to be taken + by the developer of the code calling the library. - All the functions return with an <<>>, defined as - #+NAME: type-exit-code - #+BEGIN_SRC C :comments org :tangle qmckl.h + All the functions return with an <<>>, defined as + #+NAME: type-exit-code + #+begin_src c :comments org :tangle (eval h) typedef int32_t qmckl_exit_code; - #+END_SRC + #+end_src - The exit code returns the completion status of the function to the - calling program. When a function call completed successfully, the - ~QMCKL_SUCCESS~ exit code is returned. If one of the functions of - the library fails to complete the requested task, an appropriate - error code is returned to the program. + The exit code returns the completion status of the function to the + calling program. When a function call completed successfully, the + ~QMCKL_SUCCESS~ exit code is returned. If one of the functions of + the library fails to complete the requested task, an appropriate + error code is returned to the program. - Here is the complete list of exit codes. + Here is the complete list of exit codes. - #+NAME: table-exit-codes - | ~QMCKL_SUCCESS~ | 0 | - | ~QMCKL_INVALID_ARG_1~ | 1 | - | ~QMCKL_INVALID_ARG_2~ | 2 | - | ~QMCKL_INVALID_ARG_3~ | 3 | - | ~QMCKL_INVALID_ARG_4~ | 4 | - | ~QMCKL_INVALID_ARG_5~ | 5 | - | ~QMCKL_INVALID_ARG_6~ | 6 | - | ~QMCKL_INVALID_ARG_7~ | 7 | - | ~QMCKL_INVALID_ARG_8~ | 8 | - | ~QMCKL_INVALID_ARG_9~ | 9 | - | ~QMCKL_INVALID_ARG_10~ | 10 | - | ~QMCKL_NULL_CONTEXT~ | 101 | - | ~QMCKL_FAILURE~ | 102 | - | ~QMCKL_ERRNO~ | 103 | - | ~QMCKL_INVALID_EXIT_CODE~ | 104 | + #+NAME: table-exit-codes + | ~QMCKL_SUCCESS~ | 0 | + | ~QMCKL_INVALID_ARG_1~ | 1 | + | ~QMCKL_INVALID_ARG_2~ | 2 | + | ~QMCKL_INVALID_ARG_3~ | 3 | + | ~QMCKL_INVALID_ARG_4~ | 4 | + | ~QMCKL_INVALID_ARG_5~ | 5 | + | ~QMCKL_INVALID_ARG_6~ | 6 | + | ~QMCKL_INVALID_ARG_7~ | 7 | + | ~QMCKL_INVALID_ARG_8~ | 8 | + | ~QMCKL_INVALID_ARG_9~ | 9 | + | ~QMCKL_INVALID_ARG_10~ | 10 | + | ~QMCKL_NULL_CONTEXT~ | 101 | + | ~QMCKL_FAILURE~ | 102 | + | ~QMCKL_ERRNO~ | 103 | + | ~QMCKL_INVALID_EXIT_CODE~ | 104 | - # We need to force Emacs not to indent the Python code: - # -*- org-src-preserve-indentation: t - #+BEGIN_SRC python :var table=table-exit-codes :results drawer :exports result + # We need to force Emacs not to indent the Python code: + # -*- org-src-preserve-indentation: t + #+begin_src python :var table=table-exit-codes :results drawer :exports result """ This script generates the C and Fortran constants for the error codes from the org-mode table. """ -result = [ "#+BEGIN_SRC C :comments org :tangle qmckl.h" ] +result = [ "#+begin_src c :comments org :tangle (eval h)" ] for (text, code) in table: text=text.replace("~","") result += [ f"#define {text:30s} {code:d}" ] -result += [ "#+END_SRC" ] +result += [ "#+end_src" ] result += [ "" ] -result += [ "#+BEGIN_SRC f90 :comments org :tangle qmckl_f.f90" ] +result += [ "#+begin_src f90 :comments org :tangle (eval fh)" ] for (text, code) in table: text=text.replace("~","") result += [ f" integer, parameter :: {text:30s} = {code:d}" ] -result += [ "#+END_SRC" ] +result += [ "#+end_src" ] return '\n'.join(result) - #+END_SRC + #+end_src - #+RESULTS: - :results: - #+BEGIN_SRC C :comments org :tangle qmckl.h - #define QMCKL_SUCCESS 0 - #define QMCKL_INVALID_ARG_1 1 - #define QMCKL_INVALID_ARG_2 2 - #define QMCKL_INVALID_ARG_3 3 - #define QMCKL_INVALID_ARG_4 4 - #define QMCKL_INVALID_ARG_5 5 - #define QMCKL_INVALID_ARG_6 6 - #define QMCKL_INVALID_ARG_7 7 - #define QMCKL_INVALID_ARG_8 8 - #define QMCKL_INVALID_ARG_9 9 - #define QMCKL_INVALID_ARG_10 10 - #define QMCKL_NULL_CONTEXT 101 - #define QMCKL_FAILURE 102 - #define QMCKL_ERRNO 103 - #define QMCKL_INVALID_EXIT_CODE 104 - #+END_SRC + #+RESULTS: + :results: + #+begin_src c :comments org :tangle (eval h) + #define QMCKL_SUCCESS 0 + #define QMCKL_INVALID_ARG_1 1 + #define QMCKL_INVALID_ARG_2 2 + #define QMCKL_INVALID_ARG_3 3 + #define QMCKL_INVALID_ARG_4 4 + #define QMCKL_INVALID_ARG_5 5 + #define QMCKL_INVALID_ARG_6 6 + #define QMCKL_INVALID_ARG_7 7 + #define QMCKL_INVALID_ARG_8 8 + #define QMCKL_INVALID_ARG_9 9 + #define QMCKL_INVALID_ARG_10 10 + #define QMCKL_NULL_CONTEXT 101 + #define QMCKL_FAILURE 102 + #define QMCKL_ERRNO 103 + #define QMCKL_INVALID_EXIT_CODE 104 + #+end_src - #+BEGIN_SRC f90 :comments org :tangle qmckl_f.f90 - integer, parameter :: QMCKL_SUCCESS = 0 - integer, parameter :: QMCKL_INVALID_ARG_1 = 1 - integer, parameter :: QMCKL_INVALID_ARG_2 = 2 - integer, parameter :: QMCKL_INVALID_ARG_3 = 3 - integer, parameter :: QMCKL_INVALID_ARG_4 = 4 - integer, parameter :: QMCKL_INVALID_ARG_5 = 5 - integer, parameter :: QMCKL_INVALID_ARG_6 = 6 - integer, parameter :: QMCKL_INVALID_ARG_7 = 7 - integer, parameter :: QMCKL_INVALID_ARG_8 = 8 - integer, parameter :: QMCKL_INVALID_ARG_9 = 9 - integer, parameter :: QMCKL_INVALID_ARG_10 = 10 - integer, parameter :: QMCKL_NULL_CONTEXT = 101 - integer, parameter :: QMCKL_FAILURE = 102 - integer, parameter :: QMCKL_ERRNO = 103 - integer, parameter :: QMCKL_INVALID_EXIT_CODE = 104 - #+END_SRC - :end: + #+begin_src f90 :comments org :tangle (eval fh) + integer, parameter :: QMCKL_SUCCESS = 0 + integer, parameter :: QMCKL_INVALID_ARG_1 = 1 + integer, parameter :: QMCKL_INVALID_ARG_2 = 2 + integer, parameter :: QMCKL_INVALID_ARG_3 = 3 + integer, parameter :: QMCKL_INVALID_ARG_4 = 4 + integer, parameter :: QMCKL_INVALID_ARG_5 = 5 + integer, parameter :: QMCKL_INVALID_ARG_6 = 6 + integer, parameter :: QMCKL_INVALID_ARG_7 = 7 + integer, parameter :: QMCKL_INVALID_ARG_8 = 8 + integer, parameter :: QMCKL_INVALID_ARG_9 = 9 + integer, parameter :: QMCKL_INVALID_ARG_10 = 10 + integer, parameter :: QMCKL_NULL_CONTEXT = 101 + integer, parameter :: QMCKL_FAILURE = 102 + integer, parameter :: QMCKL_ERRNO = 103 + integer, parameter :: QMCKL_INVALID_EXIT_CODE = 104 + #+end_src + :end: - To make a function fail, the <<<~qmckl_failwith~>>> function should be - called, such that information about the failure is stored in - the context. The desired exit code is given as an argument, as - well as the name of the function and an error message. The return - code of the function is the desired return code. - - #+BEGIN_SRC C :comments org :tangle qmckl.h -qmckl_exit_code qmckl_failwith(qmckl_context context, - const qmckl_exit_code exit_code, - const char* function, - const char* message) ; - #+END_SRC - - #+BEGIN_SRC C :comments org :tangle qmckl_error.c -qmckl_exit_code qmckl_failwith(qmckl_context context, - const qmckl_exit_code exit_code, - const char* function, - const char* message) { - if (context == 0) return QMCKL_NULL_CONTEXT; - assert (exit_code > 0); - assert (exit_code < QMCKL_INVALID_EXIT_CODE); - assert (function != NULL); - assert (message != NULL); - assert (strlen(function) < QMCKL_MAX_FUN_LEN); - assert (strlen(message) < QMCKL_MAX_MSG_LEN); - - context = qmckl_context_set_error(context, exit_code, function, message); - return exit_code; -} - - #+END_SRC - - For example, this function can be used as - #+BEGIN_SRC C :tangle no -if (x < 0) { - return qmckl_failwith(context, - QMCKL_INVALID_ARG_2, - "qmckl_function", - "Expected x >= 0"); - } - #+END_SRC +** End of files :noexport: - # To decode the error messages, the <<<~qmckl_strerror~>>> converts an - # error code into a string. - -*** End of files :noexport: - -***** Test - #+BEGIN_SRC C :comments link :tangle (org-entry-get nil "c_test" t) +*** Test + #+begin_src c :comments link :tangle (eval c_test) return MUNIT_OK; } - #+END_SRC + #+end_src + +# -*- mode: org -*- +# vim: syntax=c - - # -*- mode: org -*- - # vim: syntax=c - - # -*- mode: org -*- - # vim: syntax=c diff --git a/src/qmckl_footer.org b/src/qmckl_footer.org index 5ed01c7..ad448d6 100644 --- a/src/qmckl_footer.org +++ b/src/qmckl_footer.org @@ -3,16 +3,6 @@ [[https://trex-coe.eu/sites/default/files/inline-images/euflag.jpg]] [[https://trex-coe.eu][TREX: Targeting Real Chemical Accuracy at the Exascale]] project has received funding from the European Union’s Horizon 2020 - Research and Innovation program - under grant agreement no. 952165. The content of this document does not represent the opinion of the European Union, and the European Union is not responsible for any use that might be made of such content. -* End of header files :noexport: - -#+BEGIN_SRC C :tangle qmckl.h -#endif -#+END_SRC - -#+BEGIN_SRC f90 :tangle qmckl_f.f90 -end module qmckl -#+END_SRC - # -*- mode: org -*- diff --git a/src/qmckl_memory.org b/src/qmckl_memory.org index d861c13..47d6962 100644 --- a/src/qmckl_memory.org +++ b/src/qmckl_memory.org @@ -1,36 +1,45 @@ -** Memory management +#+TITLE: Memory management +#+SETUPFILE: ../docs/theme.setup - We override the allocation functions to enable the possibility of - optimized libraries to fine-tune the memory allocation. +We override the allocation functions to enable the possibility of +optimized libraries to fine-tune the memory allocation. - 2 files are produced: - - a source file : =qmckl_memory.c= - - a test file : =test_qmckl_memory.c= -*** Headers :noexport: - #+BEGIN_SRC C :tangle qmckl_memory.c -#include "qmckl.h" -#include - #+END_SRC +* Headers :noexport: - #+BEGIN_SRC C :tangle test_qmckl_memory.c + #+NAME: filename + #+begin_src elisp tangle: no +(file-name-nondirectory (substring buffer-file-name 0 -4)) + #+end_src + + #+begin_src c :tangle (eval c) +#include +#include +#include "qmckl_error.h" +#include "qmckl_context.h" +#include "qmckl_memory.h" + #+end_src + + #+begin_src c :tangle (eval c_test) :noweb yes #include "qmckl.h" #include "munit.h" -MunitResult test_qmckl_memory() { - #+END_SRC +MunitResult test_<>() { + #+end_src -*** ~qmckl_malloc~ +* ~qmckl_malloc~ - Memory allocation function, letting the library choose how the - memory will be allocated, and a pointer is returned to the user. - The context is passed to let the library store data related to the - allocation inside the context. + Memory allocation function, letting the library choose how the + memory will be allocated, and a pointer is returned to the user. + The context is passed to let the library store data related to the + allocation inside the context. If the allocation failed, the ~NULL~ + pointer is returned. - #+BEGIN_SRC C :tangle qmckl.h -void* qmckl_malloc(const qmckl_context ctx, const size_t size); - #+END_SRC + #+begin_src c :tangle (eval h) +void* qmckl_malloc(qmckl_context ctx, + const size_t size); + #+end_src - #+BEGIN_SRC f90 :tangle qmckl_f.f90 + #+begin_src f90 :tangle (eval fh) interface type (c_ptr) function qmckl_malloc (context, size) bind(C) use, intrinsic :: iso_c_binding @@ -38,43 +47,46 @@ void* qmckl_malloc(const qmckl_context ctx, const size_t size); integer (c_int64_t), intent(in), value :: size end function qmckl_malloc end interface - #+END_SRC + #+end_src + +** Source + + #+begin_src c :tangle (eval c) +void* qmckl_malloc(qmckl_context ctx, const size_t size) { -**** Source - #+BEGIN_SRC C :tangle qmckl_memory.c -void* qmckl_malloc(const qmckl_context ctx, const size_t size) { if (ctx == (qmckl_context) 0) {}; /* Avoid unused argument warning */ void * result = malloc( (size_t) size ); - assert (result != NULL) ; return result; + } - #+END_SRC + #+end_src -**** Test :noexport: - #+BEGIN_SRC C :tangle test_qmckl_memory.c -int *a = NULL; -munit_assert(a == NULL); -a = (int*) qmckl_malloc( (qmckl_context) 1, 3*sizeof(int)); -munit_assert(a != NULL); -a[0] = 1; -a[1] = 2; -a[2] = 3; -munit_assert_int(a[0], ==, 1); -munit_assert_int(a[1], ==, 2); -munit_assert_int(a[2], ==, 3); - #+END_SRC +** Test :noexport: + #+begin_src c :tangle (eval c_test) + int *a = NULL; + munit_assert(a == NULL); + a = (int*) qmckl_malloc( (qmckl_context) 1, 3*sizeof(int)); + munit_assert(a != NULL); + a[0] = 1; + a[1] = 2; + a[2] = 3; + munit_assert_int(a[0], ==, 1); + munit_assert_int(a[1], ==, 2); + munit_assert_int(a[2], ==, 3); + #+end_src -*** ~qmckl_free~ +* ~qmckl_free~ - The context is passed, in case some important information has been - stored related to memory allocation and needs to be updated. + The context is passed, in case some important information has been + stored related to memory allocation and needs to be updated. - #+BEGIN_SRC C :tangle qmckl.h -qmckl_exit_code qmckl_free(qmckl_context context, void *ptr); - #+END_SRC + #+begin_src c :tangle (eval h) +qmckl_exit_code qmckl_free(qmckl_context context, + void *ptr); + #+end_src - #+BEGIN_SRC f90 :tangle qmckl_f.f90 + #+begin_src f90 :tangle (eval fh) interface integer (c_int32_t) function qmckl_free (context, ptr) bind(C) use, intrinsic :: iso_c_binding @@ -82,36 +94,38 @@ qmckl_exit_code qmckl_free(qmckl_context context, void *ptr); type (c_ptr), intent(in), value :: ptr end function qmckl_free end interface - #+END_SRC + #+end_src -**** Source - #+BEGIN_SRC C :tangle qmckl_memory.c +** Source + #+begin_src c :tangle (eval c) qmckl_exit_code qmckl_free(qmckl_context context, void *ptr) { + if (context == 0) return QMCKL_INVALID_ARG_1; if (ptr == NULL) return QMCKL_INVALID_ARG_2; free(ptr); return QMCKL_SUCCESS; -} - #+END_SRC -**** Test :noexport: - #+BEGIN_SRC C :tangle test_qmckl_memory.c +} + #+end_src + +** Test :noexport: + #+begin_src c :tangle (eval c_test) munit_assert(a != NULL); qmckl_exit_code rc; rc = qmckl_free( (qmckl_context) 1, a); munit_assert(rc == QMCKL_SUCCESS); - #+END_SRC + #+end_src -*** End of files :noexport: +* End of files :noexport: -**** Test - #+BEGIN_SRC C :comments org :tangle test_qmckl_memory.c +** Test + #+begin_src c :comments org :tangle (eval c_test) return MUNIT_OK; } - #+END_SRC + #+end_src - # -*- mode: org -*- - # vim: syntax=c +# -*- mode: org -*- +# vim: syntax=c diff --git a/src/qmckl_precision.org b/src/qmckl_precision.org index 60c8fd0..ca24c0a 100644 --- a/src/qmckl_precision.org +++ b/src/qmckl_precision.org @@ -1,21 +1,58 @@ -# This file is part of the qmckl.h file +#+TITLE: Multi-precision +#+SETUPFILE: ../docs/theme.setup -*** Multi-precision related constants +#+NAME: filename +#+begin_src elisp tangle: no +(file-name-nondirectory (substring buffer-file-name 0 -4)) +#+end_src - Controlling numerical precision enables optimizations. Here, the - default parameters determining the target numerical precision and - range are defined. + Controlling numerical precision enables optimizations. Here, the + default parameters determining the target numerical precision and + range are defined. - #+BEGIN_SRC C :comments org :tangle qmckl.h -#define QMCKL_DEFAULT_PRECISION 53 -#define QMCKL_DEFAULT_RANGE 11 - #+END_SRC + #+NAME: table-precision + | ~QMCKL_DEFAULT_PRECISION~ | 53 | + | ~QMCKL_DEFAULT_RANGE~ | 11 | - #+BEGIN_SRC f90 :comments org :tangle qmckl_f.f90 - integer, parameter :: QMCKL_DEFAULT_PRECISION = 53 - integer, parameter :: QMCKL_DEFAULT_RANGE = 11 - #+END_SRC - + # We need to force Emacs not to indent the Python code: + # -*- org-src-preserve-indentation: t - # -*- mode: org -*- - # vim: syntax=c +#+begin_src python :var table=table-precision :results drawer :exports result +""" This script generates the C and Fortran constants for the error + codes from the org-mode table. +""" + +result = [ "#+begin_src c :comments org :tangle (eval h)" ] +for (text, code) in table: + text=text.replace("~","") + result += [ f"#define {text:30s} {code:d}" ] +result += [ "#+end_src" ] + +result += [ "" ] + +result += [ "#+begin_src f90 :comments org :tangle (eval fh)" ] +for (text, code) in table: + text=text.replace("~","") + result += [ f" integer, parameter :: {text:30s} = {code:d}" ] +result += [ "#+end_src" ] + +return '\n'.join(result) + +#+end_src + +#+RESULTS: +:results: +#+begin_src c :comments org :tangle (eval h) +#define QMCKL_DEFAULT_PRECISION 53 +#define QMCKL_DEFAULT_RANGE 11 +#+end_src + +#+begin_src f90 :comments org :tangle (eval fh) + integer, parameter :: QMCKL_DEFAULT_PRECISION = 53 + integer, parameter :: QMCKL_DEFAULT_RANGE = 11 +#+end_src +:end: + + +# -*- mode: org -*- +# vim: syntax=c diff --git a/src/table_of_contents b/src/table_of_contents index 2fbbb05..7929b05 100644 --- a/src/table_of_contents +++ b/src/table_of_contents @@ -1,9 +1,9 @@ -qmckl.org -qmckl_context.org -qmckl_error.org -qmckl_precision.org -qmckl_memory.org -qmckl_distance.org -qmckl_ao.org +qmckl.org +qmckl_error.org +qmckl_context.org +qmckl_precision.org +qmckl_memory.org +qmckl_distance.org +qmckl_ao.org test_qmckl.org -qmckl_footer.org +qmckl_footer.org diff --git a/src/test_qmckl.org b/src/test_qmckl.org index cc0f169..5633963 100644 --- a/src/test_qmckl.org +++ b/src/test_qmckl.org @@ -1,19 +1,22 @@ +#+TITLE: Testing +#+SETUPFILE: ../docs/theme.setup + * QMCkl test :noexport: This file is the main program of the unit tests. The tests rely on the $\mu$unit framework, which is provided as a git submodule. - First, we use a script to find the list of all the produced test files: + First, we use a script to find the list of all the generated test files: #+NAME: test-files - #+BEGIN_SRC sh :exports none :results value -grep BEGIN_SRC *.org | \ + #+begin_src sh :exports none :results value +grep begin_src *.org | \ grep test_qmckl_ | \ rev | \ cut -d ' ' -f 1 | \ rev | \ sort | \ uniq - #+END_SRC + #+end_src #+RESULTS: test-files | test_qmckl_ao.c | @@ -22,48 +25,48 @@ grep BEGIN_SRC *.org | \ | test_qmckl_memory.c | We generate the function headers - #+BEGIN_SRC sh :var files=test-files :exports output :results raw + #+begin_src sh :var files=test-files :exports output :results raw echo "#+NAME: headers" -echo "#+BEGIN_SRC C :tangle no" +echo "#+begin_src c :tangle no" for file in $files do routine=${file%.c} echo "MunitResult ${routine}();" done -echo "#+END_SRC" - #+END_SRC +echo "#+end_src" + #+end_src #+RESULTS: #+NAME: headers - #+BEGIN_SRC C :tangle no + #+begin_src c :tangle no MunitResult test_qmckl_ao(); MunitResult test_qmckl_context(); MunitResult test_qmckl_distance(); MunitResult test_qmckl_memory(); - #+END_SRC + #+end_src and the required function calls: - #+BEGIN_SRC sh :var files=test-files :exports output :results raw + #+begin_src sh :var files=test-files :exports output :results raw echo "#+NAME: calls" -echo "#+BEGIN_SRC C :tangle no" +echo "#+begin_src c :tangle no" for file in $files do routine=${file%.c} echo " { (char*) \"${routine}\", ${routine}, NULL,NULL,MUNIT_TEST_OPTION_NONE,NULL}," done -echo "#+END_SRC" - #+END_SRC +echo "#+end_src" + #+end_src #+RESULTS: #+NAME: calls - #+BEGIN_SRC C :tangle no + #+begin_src c :tangle no { (char*) "test_qmckl_ao", test_qmckl_ao, NULL,NULL,MUNIT_TEST_OPTION_NONE,NULL}, { (char*) "test_qmckl_context", test_qmckl_context, NULL,NULL,MUNIT_TEST_OPTION_NONE,NULL}, { (char*) "test_qmckl_distance", test_qmckl_distance, NULL,NULL,MUNIT_TEST_OPTION_NONE,NULL}, { (char*) "test_qmckl_memory", test_qmckl_memory, NULL,NULL,MUNIT_TEST_OPTION_NONE,NULL}, - #+END_SRC + #+end_src - #+BEGIN_SRC C :comments link :noweb yes :tangle test_qmckl.c + #+begin_src c :comments link :noweb yes :tangle test_qmckl.c #include "qmckl.h" #include "munit.h" <> @@ -82,4 +85,4 @@ int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) { return munit_suite_main(&test_suite, (void*) "µnit", argc, argv); } - #+END_SRC + #+end_src diff --git a/tools/Building.org b/tools/Building.org new file mode 100644 index 0000000..12a6ab6 --- /dev/null +++ b/tools/Building.org @@ -0,0 +1,406 @@ +#+TITLE: Building tools + +This file contains all the tools needed to build the QMCkl library. + +* Helper functions + #+NAME: header + #+begin_src sh :tangle no :exports none :output none +echo "This file was created by tools/Building.org" + #+end_src + + #+NAME: check-src + #+begin_src bash +if [[ $(basename $PWD) != "src" ]] ; then + echo "This script needs to be run in the src directory" + exit -1 +fi + #+end_src + + #+NAME: url-issues + : https://github.com/trex-coe/qmckl/issues + + #+NAME: url-web + : https://trex-coe.github.io/qmckl + + #+NAME: license + #+begin_example +BSD 3-Clause License + +Copyright (c) 2020, TREX Center of Excellence +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +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. + + #+end_example + +* Makefile + :PROPERTIES: + :header-args: :tangle ../src/Makefile :noweb yes :comments org + :END: + + This is the main Makefile invoked by the ~make~ command. + The Makefile compiling the library is =Makefile.generated=, and is + generated by the script detailed in the next section. +** Header :noexport: + + #+begin_src makefile +# <> + #+end_src + +** Variables + + #+begin_src makefile +QMCKL_ROOT=$(shell dirname $(CURDIR)) + +export CC CFLAGS FC FFLAGS LIBS QMCKL_ROOT + +ORG_SOURCE_FILES=$(wildcard *.org) +OBJECT_FILES=$(filter-out $(EXCLUDED_OBJECTS), $(patsubst %.org,%.o,$(ORG_SOURCE_FILES))) +INCLUDE=-I$(QMCKL_ROOT)/include/ + #+end_src + +** Compiler options + + GNU, Intel and LLVM compilers are supported. Choose here: + + #+begin_src makefile +COMPILER=GNU +#COMPILER=INTEL +#COMPILER=LLVM + #+end_src + +*** GNU + + #+begin_src makefile +ifeq ($(COMPILER),GNU) +#---------------------------------------------------------- +CC=gcc -g +CFLAGS=-fPIC $(INCLUDE) \ + -fexceptions -Wall -Werror -Wpedantic -Wextra -fmax-errors=3 + +FC=gfortran -g +FFLAGS=-fPIC $(INCLUDE) \ + -fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising \ + -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation \ + -Wreal-q-constant -Wuninitialized -fbacktrace -finit-real=nan \ + -ffpe-trap=zero,overflow,underflow + +LIBS=-lgfortran -lm +#---------------------------------------------------------- +endif + #+end_src + +*** Intel + + #+begin_src makefile +ifeq ($(COMPILER),INTEL) +#---------------------------------------------------------- +CC=icc -xHost +CFLAGS=-fPIC -g -O2 $(INCLUDE) + +FC=ifort -xHost +FFLAGS=-fPIC -g -O2 $(INCLUDE) + +LIBS=-lm -lifcore -lirc +#---------------------------------------------------------- +CC=icc -xHost +endif + #+end_src + +*** LLVM + + #+begin_src makefile +ifeq ($(COMPILER),LLVM) +#---------------------------------------------------------- +CC=clang +CFLAGS=-fPIC -g -O2 $(INCLUDE) + +FC=flang +FFLAGS=fPIC -g -O2 $(INCLUDE) + +LIBS=-lm +#---------------------------------------------------------- +endif + #+end_src + +** Rules + + The source files are created during the generation of the file ~Makefile.generated~. + + #+begin_src makefile +.PHONY: clean +.SECONDARY: # Needed to keep the produced C and Fortran files + +libqmckl.so: Makefile.generated + $(MAKE) -f Makefile.generated + +test: Makefile.generated + $(MAKE) -f Makefile.generated test + +doc: $(ORG_SOURCE_FILES) + $(QMCKL_ROOT)/tools/create_doc.sh + +clean: + $(RM) qmckl.h test_qmckl_* test_qmckl.c test_qmckl \ + qmckl_*.f90 qmckl_*.c qmckl_*.o qmckl_*.h \ + Makefile.generated libqmckl.so *.html *.mod + +Makefile.generated: Makefile $(QMCKL_ROOT)/tools/create_makefile.sh $(ORG_SOURCE_FILES) + $(QMCKL_ROOT)/tools/create_makefile.sh + #+end_src + +* Script to tangle the org-mode files + :PROPERTIES: + :header-args: :tangle tangle.sh :noweb yes :shebang #!/bin/bash :comments org + :END: + + #+begin_src bash +# <> + +<> + #+end_src + + This file needs to be run from the QMCKL =src= directory. + + It tangles all the files in the directory. It uses the + =config_tangle.el= file, which contains information required to + compute the current file names using for example ~(eval c)~ to get + the name of the produced C file. + + The file is not tangled if the last modification date of the org + file is less recent than one of the tangled files. + #+begin_src bash +function tangle() +{ + if [[ -f ${1%.org}.c && $1 -ot ${1%.org}.c ]] + then return + elif [[ -f ${1%.org}.f90 && $1 -ot ${1%.org}.f90 ]] + then return + fi + emacs --batch $1 --load=../tools/config_tangle.el -f org-babel-tangle +} + + +for i in $@ +do + echo "--- $i ----" + tangle $i +done + #+end_src + +* Script to generate auto-generated Makefile + :PROPERTIES: + :header-args: :tangle create_makefile.sh :noweb yes :shebang #!/bin/bash :comments org + :END: + + This script generates the Makefile that compiles the library. + The ~OUTPUT~ variable contains the name of the generated Makefile,typically + =Makefile.generated=. + + #+begin_src bash +# <> + +<> + +OUTPUT=Makefile.generated + #+end_src + + We start by tangling all the org-mode files. + + #+begin_src bash +${QMCKL_ROOT}/tools/tangle.sh *.org + #+end_src + + Then we create the list of ~*.o~ files to be created, for library + functions: + + #+begin_src bash +OBJECTS="" +for i in $(ls qmckl_*.c) ; do + FILE=${i%.c} + OBJECTS="${OBJECTS} ${FILE}.o" +done >> $OUTPUT + +for i in $(ls qmckl_*_f.f90) ; do + FILE=${i%.f90} + OBJECTS="${OBJECTS} ${FILE}.o" +done >> $OUTPUT + #+end_src + + for tests in C: + + #+begin_src bash +TESTS="" +for i in $(ls test_qmckl_*.c) ; do + FILE=${i%.c}.o + TESTS="${TESTS} ${FILE}" +done >> $OUTPUT + #+end_src + + and for tests in Fortran: + + #+begin_src bash +TESTS_F="" +for i in $(ls test_qmckl_*_f.f90) ; do + FILE=${i%.f90}.o + TESTS_F="${TESTS_F} ${FILE}" +done >> $OUTPUT + #+end_src + + Finally, we append the rules to the Makefile + + #+begin_src bash +cat << EOF > ${OUTPUT} +CC=$CC +CFLAGS=$CFLAGS -I../munit/ + +FC=$FC +FFLAGS=$FFLAGS +OBJECT_FILES=$OBJECTS +TESTS=$TESTS +TESTS_F=$TESTS_F + +LIBS=$LIBS + +libqmckl.so: \$(OBJECT_FILES) + \$(CC) -shared \$(OBJECT_FILES) -o libqmckl.so + +%.o: %.c + \$(CC) \$(CFLAGS) -c \$*.c -o \$*.o + + +qmckl_f.o: ../include/qmckl_f.f90 + \$(FC) \$(FFLAGS) -c ../include/qmckl_f.f90 -o qmckl_f.o + +%.o: %.f90 qmckl_f.o + \$(FC) \$(FFLAGS) -c \$*.f90 -o \$*.o + + +test_qmckl: test_qmckl.c libqmckl.so \$(TESTS) \$(TESTS_F) + \$(CC) \$(CFLAGS) -Wl,-rpath,$PWD -L. \ + ../munit/munit.c \$(TESTS) \$(TESTS_F) -lqmckl \$(LIBS) test_qmckl.c -o test_qmckl + +test: test_qmckl + ./test_qmckl + +.PHONY: test +EOF + + #+end_src + +* Script to build the final qmckl.h file + :PROPERTIES: + :header-args:bash: :tangle build_qmckl_h.sh :noweb yes :shebang #!/bin/bash :comments org + :END: + + #+begin_src bash :noweb yes +# <> + + #+end_src + + #+NAME: qmckl-header + #+begin_src text :noweb yes +------------------------------------------ + QMCkl - Quantum Monte Carlo kernel library + ------------------------------------------ + + Documentation : <> + Issues : <> + + <> + + + #+end_src + + All the produced header files are concatenated in the =qmckl.h= + file, located in the include directory. The =*_private.h= files + are excluded. + + Put =.h= files in the correct order: + + #+begin_src bash +HEADERS="" +for i in $(cat table_of_contents) +do + HEADERS+="${i%.org}.h " +done + #+end_src + + Generate C header file + + #+begin_src bash +OUTPUT="../include/qmckl.h" + +cat << EOF > ${OUTPUT} +/* + ,* <> + ,*/ + +#ifndef __QMCKL_H__ +#define __QMCKL_H__ + +#include +#include +EOF + +for i in ${HEADERS} +do + if [[ -f $i ]] ; then + cat $i >> ${OUTPUT} + fi +done + +cat << EOF >> ${OUTPUT} +#endif +EOF + #+end_src + + Generate Fortran interface file from all =qmckl_*_fh.f90= files + + #+begin_src bash +HEADERS="qmckl_*_fh.f90" + +OUTPUT="../include/qmckl_f.f90" +cat << EOF > ${OUTPUT} +! +! <> +! +module qmckl + use, intrinsic :: iso_c_binding +EOF + +for i in ${HEADERS} +do + cat $i >> ${OUTPUT} +done + +cat << EOF >> ${OUTPUT} +end module qmckl +EOF + #+end_src + +* Script to build the documentation +* Script to build the documentation diff --git a/tools/build_qmckl_h.sh b/tools/build_qmckl_h.sh new file mode 100755 index 0000000..941959f --- /dev/null +++ b/tools/build_qmckl_h.sh @@ -0,0 +1,164 @@ +#!/bin/bash +# Script to build the final qmckl.h file +# :PROPERTIES: +# :header-args:bash: :tangle build_qmckl_h.sh :noweb yes :shebang #!/bin/bash :comments both +# :END: + + +# [[file:Building.org::*Script to build the final qmckl.h file][Script to build the final qmckl.h file:1]] +# This file was created by tools/Building.org +# Script to build the final qmckl.h file:1 ends here + + + +# All the produced header files are concatenated in the =qmckl.h= +# file, located in the include directory. The =*_private.h= files +# are excluded. + +# Put =.h= files in the correct order: + + +# [[file:Building.org::*Script to build the final qmckl.h file][Script to build the final qmckl.h file:3]] +HEADERS="" +for i in $(cat table_of_contents) +do + HEADERS+="${i%.org}.h " +done +# Script to build the final qmckl.h file:3 ends here + + + +# Generate C header file + + +# [[file:Building.org::*Script to build the final qmckl.h file][Script to build the final qmckl.h file:4]] +OUTPUT="../include/qmckl.h" + +cat << EOF > ${OUTPUT} +/* + * ------------------------------------------ + * QMCkl - Quantum Monte Carlo kernel library + * ------------------------------------------ + * + * Documentation : https://trex-coe.github.io/qmckl + * Issues : https://github.com/trex-coe/qmckl/issues + * + * BSD 3-Clause License + * + * Copyright (c) 2020, TREX Center of Excellence + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * 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. + * + * + * + * + */ + +#ifndef __QMCKL_H__ +#define __QMCKL_H__ + +#include +#include +EOF + +for i in ${HEADERS} +do + if [[ -f $i ]] ; then + cat $i >> ${OUTPUT} + fi +done + +cat << EOF >> ${OUTPUT} +#endif +EOF +# Script to build the final qmckl.h file:4 ends here + + + +# Generate Fortran interface file from all =qmckl_*_fh.f90= files + + +# [[file:Building.org::*Script to build the final qmckl.h file][Script to build the final qmckl.h file:5]] +HEADERS="qmckl_*_fh.f90" + +OUTPUT="../include/qmckl_f.f90" +cat << EOF > ${OUTPUT} +! +! ------------------------------------------ +! QMCkl - Quantum Monte Carlo kernel library +! ------------------------------------------ +! +! Documentation : https://trex-coe.github.io/qmckl +! Issues : https://github.com/trex-coe/qmckl/issues +! +! BSD 3-Clause License +! +! Copyright (c) 2020, TREX Center of Excellence +! All rights reserved. +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions are met: +! +! 1. Redistributions of source code must retain the above copyright notice, this +! list of conditions and the following disclaimer. +! +! 2. Redistributions in binary form must reproduce the above copyright notice, +! this list of conditions and the following disclaimer in the documentation +! and/or other materials provided with the distribution. +! +! 3. Neither the name of the copyright holder nor the names of its +! contributors may be used to endorse or promote products derived from +! this software without specific prior written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +! 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. +! +! +! +! +! +module qmckl + use, intrinsic :: iso_c_binding +EOF + +for i in ${HEADERS} +do + cat $i >> ${OUTPUT} +done + +cat << EOF >> ${OUTPUT} +end module qmckl +EOF +# Script to build the final qmckl.h file:5 ends here diff --git a/docs/config.el b/tools/config_tangle.el similarity index 88% rename from docs/config.el rename to tools/config_tangle.el index 0a7f879..fc39218 100755 --- a/docs/config.el +++ b/tools/config_tangle.el @@ -96,3 +96,17 @@ with class 'color and highest min-color value." (or val 'unspecified))) (advice-add 'face-attribute :override #'my-face-attribute) + + +;; The following is required to compute the file names +(setq pwd (file-name-directory buffer-file-name)) +(setq name (file-name-nondirectory (substring buffer-file-name 0 -4))) +(setq f (concat pwd name "_f.f90")) +(setq fh (concat pwd name "_fh.f90")) +(setq c (concat pwd name ".c")) +(setq h (concat name ".h")) +(setq h_private (concat name "_private.h")) +(setq c_test (concat pwd "test_" name ".c")) +(setq f_test (concat pwd "test_" name "_f.f90")) + + diff --git a/tools/create_makefile.sh b/tools/create_makefile.sh index 3e81c7d..d7bd2f5 100755 --- a/tools/create_makefile.sh +++ b/tools/create_makefile.sh @@ -1,21 +1,32 @@ #!/bin/bash +# Script to generate auto-generated Makefile +# :PROPERTIES: +# :header-args: :tangle create_makefile.sh :noweb yes :shebang #!/bin/bash :comments org +# :END: + +# This script generates the Makefile that compiles the library. +# The ~OUTPUT~ variable contains the name of the generated Makefile,typically +# =Makefile.generated=. + + +# This file was created by tools/Building.org + -MERGED=merged.org -${QMCKL_ROOT}/tools/merge_org.sh $MERGED OUTPUT=Makefile.generated -# Tangle org files -emacs \ - $MERGED \ - --batch \ - -f org-babel-tangle \ - --kill - -rm $MERGED -# Create the list of *.o files to be created +# We start by tangling all the org-mode files. + + +${QMCKL_ROOT}/tools/tangle.sh *.org + + + +# Then we create the list of ~*.o~ files to be created, for library +# functions: + OBJECTS="" for i in $(ls qmckl_*.c) ; do @@ -23,27 +34,39 @@ for i in $(ls qmckl_*.c) ; do OBJECTS="${OBJECTS} ${FILE}.o" done >> $OUTPUT -for i in $(ls qmckl_*.f90) ; do +for i in $(ls qmckl_*_f.f90) ; do FILE=${i%.f90} OBJECTS="${OBJECTS} ${FILE}.o" done >> $OUTPUT + + +# for tests in C: + + TESTS="" for i in $(ls test_qmckl_*.c) ; do FILE=${i%.c}.o TESTS="${TESTS} ${FILE}" done >> $OUTPUT + + +# and for tests in Fortran: + + TESTS_F="" -for i in $(ls test_qmckl_*.f90) ; do +for i in $(ls test_qmckl_*_f.f90) ; do FILE=${i%.f90}.o TESTS_F="${TESTS_F} ${FILE}" done >> $OUTPUT -# Write the Makefile -cat << EOF > $OUTPUT +# Finally, we append the rules to the Makefile + + +cat << EOF > ${OUTPUT} CC=$CC CFLAGS=$CFLAGS -I../munit/ @@ -57,13 +80,18 @@ LIBS=$LIBS libqmckl.so: \$(OBJECT_FILES) \$(CC) -shared \$(OBJECT_FILES) -o libqmckl.so - + %.o: %.c \$(CC) \$(CFLAGS) -c \$*.c -o \$*.o + +qmckl_f.o: ../include/qmckl_f.f90 + \$(FC) \$(FFLAGS) -c ../include/qmckl_f.f90 -o qmckl_f.o + %.o: %.f90 qmckl_f.o \$(FC) \$(FFLAGS) -c \$*.f90 -o \$*.o + test_qmckl: test_qmckl.c libqmckl.so \$(TESTS) \$(TESTS_F) \$(CC) \$(CFLAGS) -Wl,-rpath,$PWD -L. \ ../munit/munit.c \$(TESTS) \$(TESTS_F) -lqmckl \$(LIBS) test_qmckl.c -o test_qmckl @@ -73,26 +101,3 @@ test: test_qmckl .PHONY: test EOF - -for i in $(ls qmckl_*.c) ; do - FILE=${i%.c} - echo "${FILE}.o: ${FILE}.c " *.h -done >> $OUTPUT - -for i in $(ls qmckl_*.f90) ; do - FILE=${i%.f90} - echo "${FILE}.o: ${FILE}.f90" -done >> $OUTPUT - -for i in $(ls test_qmckl_*.c) ; do - FILE=${i%.c} - echo "${FILE}.o: ${FILE}.c qmckl.h" -done >> $OUTPUT - - -for i in $(ls test_qmckl*.f90) ; do - FILE=${i%.f90} - echo "${FILE}.o: ${FILE}.f90" -done >> $OUTPUT - - diff --git a/tools/init.el b/tools/init.el index bc33d5e..fae4d20 100644 --- a/tools/init.el +++ b/tools/init.el @@ -28,17 +28,17 @@ `(("." . ,(concat user-emacs-directory "backups")))) (setq backup-by-copying t) -(require 'org) +(require 'org) (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.6)) (setq org-hide-leading-stars t) (setq org-alphabetical-lists t) -(setq org-src-fontify-natively t) -(setq org-src-tab-acts-natively t) +(setq org-src-fontify-natively t) +(setq org-src-tab-acts-natively t) (setq org-src-preserve-indentation t) -(setq org-hide-emphasis-markers nil) +(setq org-hide-emphasis-markers nil) (setq org-pretty-entities nil) -(setq org-confirm-babel-evaluate nil) ;; Do not ask for confirmation all the time!! +(setq org-confirm-babel-evaluate nil) ;; Do not ask for confirmation all the time!! (org-babel-do-load-languages 'org-babel-load-languages @@ -51,14 +51,14 @@ (makefile . t) )) -(add-hook 'org-babel-after-execute-hook 'org-display-inline-images) -'(indent-tabs-mode nil) +(add-hook 'org-babel-after-execute-hook 'org-display-inline-images) +'(indent-tabs-mode nil) (require 'evil) (setq evil-want-C-i-jump nil) (evil-mode 1) (global-font-lock-mode t) -(global-superword-mode 1) +(global-superword-mode 1) (setq line-number-mode 1) (setq column-number-mode 1) @@ -72,7 +72,7 @@ (custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. + ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(ansi-color-faces-vector [default default default italic underline success warning error]) diff --git a/tools/tangle.sh b/tools/tangle.sh new file mode 100755 index 0000000..0250ec4 --- /dev/null +++ b/tools/tangle.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Script to tangle the org-mode files +# :PROPERTIES: +# :header-args: :tangle tangle.sh :noweb yes :shebang #!/bin/bash :comments org +# :END: + + +# This file was created by tools/Building.org + + + +# This file needs to be run from the QMCKL =src= directory. + +# It tangles all the files in the directory. It uses the +# =config_tangle.el= file, which contains information required to +# compute the current file names using for example ~(eval c)~ to get +# the name of the produced C file. + +# The file is not tangled if the last modification date of the org +# file is less recent than one of the tangled files. + +function tangle() +{ + if [[ -f ${1%.org}.c && $1 -ot ${1%.org}.c ]] + then return + elif [[ -f ${1%.org}.f90 && $1 -ot ${1%.org}.f90 ]] + then return + fi + emacs --batch $1 --load=../tools/config_tangle.el -f org-babel-tangle +} + + +for i in $@ +do + echo "--- $i ----" + tangle $i +done