mirror of
https://github.com/TREX-CoE/qmckl.git
synced 2024-12-22 12:23:56 +01:00
Worked on Makefiles
This commit is contained in:
parent
32d633bfb6
commit
4236b33a4f
3
src/.gitignore
vendored
3
src/.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
*.o
|
||||
*.c
|
||||
*.h
|
||||
*~
|
||||
*.so
|
||||
Makefile.generated
|
||||
|
28
src/Makefile
28
src/Makefile
@ -1,30 +1,24 @@
|
||||
CC=gcc
|
||||
CFLAGS=-fexceptions -Wall -Werror -Wpedantic -Wextra
|
||||
CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra
|
||||
|
||||
FC=gfortran
|
||||
FFLAGS=-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
|
||||
|
||||
|
||||
ORG_SOURCE_FILES=qmckl_context.org
|
||||
OBJECT_FILES=$(patsubst %.org,%.o,$(ORG_SOURCE_FILES))
|
||||
export CC CFLAGS FC FFLAGS
|
||||
|
||||
.PHONY: clean
|
||||
ORG_SOURCE_FILES=$(wildcard qmckl*.org)
|
||||
OBJECT_FILES=$(filter-out $(EXCLUDED_OBJECTS), $(patsubst %.org,%.o,$(ORG_SOURCE_FILES)))
|
||||
|
||||
all: $(OBJECT_FILES)
|
||||
.PHONY: clean
|
||||
.SECONDARY: # Needed to keep the produced C and Fortran files
|
||||
|
||||
%.c %.h: %.org
|
||||
emacs --quick --no-init-file --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "$^")'
|
||||
|
||||
%.c %.h %_f.f90: %.org
|
||||
emacs --quick --no-init-file --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "$^")'
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
%.o: %.f90
|
||||
$(FC) $(FFLAGS) -c $*.f90 -o $*.o
|
||||
libqmckl.so: Makefile.generated
|
||||
$(MAKE) -f Makefile.generated
|
||||
|
||||
clean:
|
||||
rm -f qmckl_*.f90 qmckl_*.c qmckl_*.o qmckl_*.h
|
||||
rm -f qmckl_*.f90 qmckl_*.c qmckl_*.o qmckl_*.h Makefile.generated libqmckl.so
|
||||
|
||||
Makefile.generated: $(ORG_SOURCE_FILES) Makefile create_makefile.sh
|
||||
./create_makefile.sh $(ORG_SOURCE_FILES)
|
||||
|
||||
|
@ -8,27 +8,31 @@
|
||||
comments and LaTex formulas close to the code. There exists multiple
|
||||
possibilities to convert org-mode files into different formats such as
|
||||
HTML or pdf.
|
||||
For a tutorial on literate programming with org-mode, follow
|
||||
For a tutorial on literate programming with org-mode, follow
|
||||
[[http://www.howardism.org/Technical/Emacs/literate-programming-tutorial.html][this link]].
|
||||
|
||||
The code is extracted from the org files using Emacs as a command-line
|
||||
tool in the =Makefile=, and then the produced files are compiled.
|
||||
|
||||
If the name of the file is =xxx.org=, the name of the produced C
|
||||
files should be =xxx.c= and =xxx.h= and the name of the produced
|
||||
Fortran files should be =xxx.f90=
|
||||
|
||||
*** Source code editing
|
||||
|
||||
Any text editor can be used to edit org-mode files. For a better
|
||||
user experience Emacs is recommended.
|
||||
For users hating Emacs, it is good to know that Emacs can behave
|
||||
like Vim when switched into ``Evil'' mode. There also exists
|
||||
[[https://www.spacemacs.org][Spacemacs]] which is particularly well adapted to Vim users.
|
||||
[[https://www.spacemacs.org][Spacemacs]] which helps the transition for Vim users.
|
||||
|
||||
For users with a preference for Jupyter notebooks, the following
|
||||
script can convert jupyter notebooks to org-mode files:
|
||||
|
||||
#+BEGIN_SRC sh tangle: nb_to_org.sh
|
||||
#!/bin/bash
|
||||
# $ nb_to_org.sh notebook.ipynb
|
||||
# produces the org-mode file notebook.org
|
||||
# $ nb_to_org.sh notebook.ipynb
|
||||
# produces the org-mode file notebook.org
|
||||
|
||||
set -e
|
||||
|
||||
@ -45,7 +49,7 @@ rm ${nb}.md
|
||||
The Fortran source files should provide a C interface using
|
||||
iso-c-binding. The name of the Fortran source files should end
|
||||
with =_f.f90= to be properly handled by the Makefile.
|
||||
|
||||
|
||||
** Documentation
|
||||
|
||||
- [[qmckl_context.org][Context]]
|
||||
|
69
src/create_makefile.sh
Executable file
69
src/create_makefile.sh
Executable file
@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
OUTPUT=Makefile.generated
|
||||
|
||||
# Tangle org files
|
||||
|
||||
emacsclient -a "" \
|
||||
--socket-name=org_to_code \
|
||||
--eval "(require 'org)"
|
||||
|
||||
for INPUT in $@ ; do
|
||||
emacsclient \
|
||||
--no-wait \
|
||||
--socket-name=org_to_code \
|
||||
--eval "(org-babel-tangle-file \"$INPUT\")"
|
||||
done
|
||||
|
||||
emacsclient \
|
||||
--no-wait \
|
||||
--socket-name=org_to_code \
|
||||
--eval '(kill-emacs)'
|
||||
|
||||
|
||||
|
||||
# Create the list of *.o files to be created
|
||||
|
||||
OBJECTS=""
|
||||
for i in $(ls qmckl_*.c) ; do
|
||||
FILE=${i%.c}
|
||||
OBJECTS="${OBJECTS} ${FILE}.o"
|
||||
done >> $OUTPUT
|
||||
|
||||
for i in $(ls qmckl_*.f90) ; do
|
||||
FILE=${i%.f90}
|
||||
OBJECTS="${OBJECTS} ${FILE}.o"
|
||||
done >> $OUTPUT
|
||||
|
||||
|
||||
# Write the Makefile
|
||||
|
||||
cat << EOF > $OUTPUT
|
||||
CC=$CC
|
||||
CFLAGS=$CFLAGS
|
||||
|
||||
FC=$FC
|
||||
FFLAGS=$FFLAGS
|
||||
OBJECT_FILES=$OBJECTS
|
||||
|
||||
libqmckl.so: \$(OBJECT_FILES)
|
||||
\$(CC) -shared \$(OBJECT_FILES) -o libqmckl.so
|
||||
|
||||
%.o: %.c
|
||||
\$(CC) \$(CFLAGS) -c \$*.c -o \$*.o
|
||||
|
||||
%.o: %.f90
|
||||
\$(FC) \$(FFLAGS) -c \$*.f90 -o \$*.o
|
||||
|
||||
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
|
||||
|
38
src/org_to_code.sh
Executable file
38
src/org_to_code.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ -z $1 ]] ; then
|
||||
echo "Usage: $0 <FILE.org>"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ -z $6 ]] ; then
|
||||
# Few file to tangle
|
||||
|
||||
for INPUT in $@ ; do
|
||||
emacs \
|
||||
--quick \
|
||||
--no-init-file \
|
||||
--batch \
|
||||
--eval "(require 'org)" \
|
||||
--eval "(org-babel-tangle-file \"$INPUT\")"
|
||||
done
|
||||
|
||||
else
|
||||
# Multiple files to tangle, so we use the emacs server to speed up thing
|
||||
|
||||
emacsclient -a "" \
|
||||
--socket-name=org_to_code \
|
||||
--eval "(require 'org)"
|
||||
|
||||
for INPUT in $@ ; do
|
||||
emacsclient \
|
||||
--no-wait \
|
||||
--socket-name=org_to_code \
|
||||
--eval "(org-babel-tangle-file \"$INPUT\")"
|
||||
done
|
||||
|
||||
emacsclient \
|
||||
--no-wait \
|
||||
--socket-name=org_to_code \
|
||||
--eval '(kill-emacs)'
|
||||
fi
|
47
src/qmckl.org
Normal file
47
src/qmckl.org
Normal file
@ -0,0 +1,47 @@
|
||||
# -*- mode: org -*-
|
||||
# vim: syntax=c
|
||||
#+TITLE: QMCkl C header
|
||||
|
||||
This file is included in all other C header files, and produces the
|
||||
=qmckl.h= header file.
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl.h
|
||||
#ifndef QMCKL_H
|
||||
#define QMCKL_H
|
||||
#+END_SRC
|
||||
|
||||
* Constants
|
||||
|
||||
** Success/failure
|
||||
|
||||
These are the codes returned by the functions to indicate success
|
||||
or failure. All such functions should have as a return type =qmckl_exit_code=.
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl.h
|
||||
#define QMCKL_SUCCESS 0
|
||||
#define QMCKL_FAILURE 1
|
||||
|
||||
typedef int qmckl_exit_code;
|
||||
#+END_SRC
|
||||
|
||||
|
||||
** Precision-related constants
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl.h
|
||||
#define QMCKL_DEFAULT_PRECISION 53
|
||||
#define QMCKL_DEFAULT_RANGE 2
|
||||
#+END_SRC
|
||||
|
||||
* Header files
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl.h
|
||||
#include "qmckl_context.h"
|
||||
#+END_SRC
|
||||
|
||||
* End of header
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl.h
|
||||
#endif
|
||||
#+END_SRC
|
||||
|
||||
|
@ -1,10 +1,15 @@
|
||||
# -*- mode: org -*-
|
||||
|
||||
# vim: syntax=c
|
||||
#+TITLE: Context
|
||||
|
||||
This file is written in C because it is more natural to express the context in
|
||||
C than in Fortran.
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.h
|
||||
#ifndef QMCKL_CONTEXT_H
|
||||
#define QMCKL_CONTEXT_H
|
||||
#include "qmckl.h"
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||
#include <stdlib.h> /* malloc */
|
||||
@ -17,19 +22,15 @@ C than in Fortran.
|
||||
is stored in the following data structure, which can't be seen
|
||||
outside of the library.
|
||||
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.h
|
||||
#define QMCKL_DEFAULT_PRECISION 53
|
||||
#define QMCKL_DEFAULT_RANGE 2
|
||||
|
||||
/* 64-bit integer */
|
||||
typedef long long int qmckl_context ;
|
||||
#+END_SRC
|
||||
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||
typedef struct qmckl_context_struct_ {
|
||||
struct qmckl_context_struct_ * prev;
|
||||
typedef struct qmckl_context_struct {
|
||||
struct qmckl_context_struct * prev;
|
||||
int precision;
|
||||
int range;
|
||||
} qmckl_context_struct;
|
||||
@ -121,8 +122,53 @@ int qmckl_context_destroy(qmckl_context context) {
|
||||
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=.
|
||||
|
||||
** =qmckl_context_update_precision=
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.h
|
||||
qmckl_exit_code qmckl_context_update_precision(const qmckl_context context, int precision);
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||
qmckl_exit_code qmckl_context_update_precision(const qmckl_context context, int precision) {
|
||||
qmckl_context_struct* ctx;
|
||||
|
||||
if (precision < 2) return QMCKL_FAILURE;
|
||||
if (precision > 53) return QMCKL_FAILURE;
|
||||
|
||||
ctx = (qmckl_context_struct*) context;
|
||||
if (ctx == NULL) return QMCKL_FAILURE;
|
||||
|
||||
ctx->precision = precision;
|
||||
return QMCKL_SUCCESS;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** =qmckl_context_update_range=
|
||||
#+BEGIN_SRC C :tangle qmckl_context.h
|
||||
qmckl_exit_code qmckl_context_update_range(const qmckl_context context, int range);
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||
qmckl_exit_code qmckl_context_update_range(const qmckl_context context, int range) {
|
||||
qmckl_context_struct* ctx;
|
||||
|
||||
if (range < 2) return QMCKL_FAILURE;
|
||||
if (range > 11) return QMCKL_FAILURE;
|
||||
|
||||
ctx = (qmckl_context_struct*) context;
|
||||
if (ctx == NULL) return QMCKL_FAILURE;
|
||||
|
||||
ctx->range = range;
|
||||
return QMCKL_SUCCESS;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
|
||||
|
||||
** =qmckl_context_set_precision=
|
||||
|
||||
@ -131,15 +177,15 @@ qmckl_context qmckl_context_set_precision(const qmckl_context context, int preci
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||
qmckl_context qmckl_context_set_precision(const qmckl_context context, int precision) {
|
||||
qmckl_context_struct* ctx;
|
||||
qmckl_context qmckl_context_set_precision(const qmckl_context context, const int precision) {
|
||||
qmckl_context new_context;
|
||||
|
||||
if (precision < 2) return (qmckl_context) 0;
|
||||
if (precision > 53) return (qmckl_context) 0;
|
||||
new_context = qmckl_context_copy(context);
|
||||
if (new_context == 0) return 0;
|
||||
|
||||
ctx = (qmckl_context_struct*) qmckl_context_copy(context);
|
||||
ctx->precision = precision;
|
||||
return (qmckl_context) ctx;
|
||||
if (qmckl_context_update_precision(context, precision) == QMCKL_FAILURE) return 0;
|
||||
|
||||
return new_context;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
@ -150,14 +196,14 @@ qmckl_context qmckl_context_set_range(const qmckl_context context, int range);
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||
qmckl_context qmckl_context_set_range(const qmckl_context context, int range) {
|
||||
qmckl_context_struct* ctx;
|
||||
qmckl_context new_context;
|
||||
|
||||
if (range < 2) return (qmckl_context) 0;
|
||||
if (range > 11) return (qmckl_context) 0;
|
||||
new_context = qmckl_context_copy(context);
|
||||
if (new_context == 0) return 0;
|
||||
|
||||
ctx = (qmckl_context_struct*) qmckl_context_copy(context);
|
||||
ctx->range = range;
|
||||
return (qmckl_context) ctx;
|
||||
if (qmckl_context_update_range(context, range) == QMCKL_FAILURE) return 0;
|
||||
|
||||
return new_context;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
@ -191,3 +237,11 @@ int qmckl_context_get_range(const qmckl_context context) {
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
|
||||
|
||||
* End of header
|
||||
|
||||
#+BEGIN_SRC C :tangle qmckl_context.h
|
||||
#endif
|
||||
#+END_SRC
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user