1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-06-01 02:45:43 +02:00

Separated org-mode files

This commit is contained in:
Anthony Scemama 2021-03-09 01:16:23 +01:00
parent 8153b84c7b
commit 342c337677
19 changed files with 1720 additions and 1019 deletions

7
docs/theme.setup Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <<<C>>> codes when
QMCkl functions are used:
The =qmckl.h= header file has to be included in <<<C>>> 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 <<<Fortran>>> 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 <<<Fortran>>> 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 <stdlib.h>
#include <stdint.h>
<<type-exit-code>>
#+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.

View File

@ -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_<<filename()>>() {
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

File diff suppressed because it is too large Load Diff

View File

@ -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_<<filename()>>() {
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

View File

@ -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 <math.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#+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 <stdint.h>
#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_<<filename()>>() {
#+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 <<<exit code>>>, defined as
#+NAME: type-exit-code
#+BEGIN_SRC C :comments org :tangle qmckl.h
All the functions return with an <<<exit code>>>, 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

View File

@ -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 Unions 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 -*-

View File

@ -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 <assert.h>
#+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 <stdint.h>
#include <stdlib.h>
#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_<<filename()>>() {
#+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

View File

@ -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

View File

@ -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

View File

@ -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"
<<headers>>
@ -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

406
tools/Building.org Normal file
View File

@ -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
# <<header()>>
#+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
# <<header()>>
<<check_src>>
#+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
# <<header()>>
<<check_src>>
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
# <<header()>>
#+end_src
#+NAME: qmckl-header
#+begin_src text :noweb yes
------------------------------------------
QMCkl - Quantum Monte Carlo kernel library
------------------------------------------
Documentation : <<url-web()>>
Issues : <<url-issues()>>
<<license()>>
#+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}
/*
,* <<qmckl-header>>
,*/
#ifndef __QMCKL_H__
#define __QMCKL_H__
#include <stdlib.h>
#include <stdint.h>
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}
!
! <<qmckl-header>>
!
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

164
tools/build_qmckl_h.sh Executable file
View File

@ -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 <stdlib.h>
#include <stdint.h>
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

View File

@ -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"))

View File

@ -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

View File

@ -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])

37
tools/tangle.sh Executable file
View File

@ -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