Skip to content

Commit 681f341

Browse files
committed
2 parents 6ade40a + 1f40ece commit 681f341

File tree

7 files changed

+1100
-362
lines changed

7 files changed

+1100
-362
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ python:
55
- 3.5
66
- 3.6
77
before_install:
8-
- if [[ $TRAVIS_PYTHON_VERSION == "2.7" ]] || [[ $TRAVIS_PYTHON_VERSION == "3.5" ]];
9-
then export DO_COVERAGE=1; fi
8+
- if [[ $TRAVIS_PYTHON_VERSION == "3.5" ]]; then export DO_COVERAGE=1; fi
109
- if [[ "$TRAVIS_EVENT_TYPE" = "cron" ]]; then unset DO_COVERAGE; fi
1110
install:
1211
- pip install -U -r requirements.txt

fortran_tests/after/example.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,11 @@ program example_prog
226226
j=6, k=test_function(1, 2*(3*(1 + 1)), str_function(")a!(b['(;=dfe"), &
227227
9) + &
228228
test_function(1, 2, 3, 4)), 9, 10) &
229-
! test_function(1,2,3,4)),9,10) &
230-
! +13*str_function('') + str_function('"')
229+
! test_function(1,2,3,4)),9,10) &
230+
! +13*str_function('') + str_function('"')
231231
+ 13*str_function('') + str_function('"')
232232
end & ! comment
233-
! comment
233+
! comment
234234
do
235235
endif
236236

fortran_tests/after/test_fypp.f90

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
#:if DEBUG > 0
2+
print *, "Some debug information"
3+
#:endif
4+
5+
#:set LOGLEVEL = 2
6+
print *, "LOGLEVEL: ${LOGLEVEL}$"
7+
8+
#:del LOGLEVEL
9+
10+
#:def assertTrue(cond)
11+
#:if DEBUG > 0
12+
if (.not. ${cond}$) then
13+
print *, "Assert failed in file ${_FILE_}$, line ${_LINE_}$"
14+
error stop
15+
end if
16+
#:endif
17+
#:enddef assertTrue
18+
19+
! Invoked via direct call (argument needs no quotation)
20+
@:assertTrue(size(myArray) > 0)
21+
22+
! Invoked as Python expression (argument needs quotation)
23+
$:assertTrue('size(myArray) > 0')
24+
25+
program test
26+
#:if defined('WITH_MPI')
27+
use mpi
28+
#:elif defined('WITH_OPENMP')
29+
use openmp
30+
#:else
31+
use serial
32+
#:endif
33+
end program
34+
35+
interface myfunc
36+
#:for dtype in ['real', 'dreal', 'complex', 'dcomplex']
37+
module procedure myfunc_${dtype}$
38+
#:endfor
39+
end interface myfunc
40+
41+
logical, parameter :: hasMpi = #{if defined('MPI')}# .true. #{else}# .false. #{endif}#
42+
43+
character(*), parameter :: comp_date = "${time.strftime('%Y-%m-%d')}$"
44+
45+
#:include "macrodefs.fypp"
46+
47+
#:if var1 > var2 &
48+
& or var2> var4
49+
print *, "Doing something here"
50+
#:endif
51+
52+
#! Callable needs only string argument
53+
#:def debug_code(code)
54+
#:if DEBUG > 0
55+
$:code
56+
#:endif
57+
#:enddef debug_code
58+
59+
#! Pass code block as first positional argument
60+
#:call debug_code
61+
if (size(array) > 100) then
62+
print *, "DEBUG: spuriously large array"
63+
end if
64+
#:endcall debug_code
65+
66+
#! Callable needs also non-string argument types
67+
#:def repeat_code(code, repeat)
68+
#:for ind in range(repeat)
69+
$:code
70+
#:endfor
71+
#:enddef repeat_code
72+
73+
#! Pass code block as positional argument and 3 as keyword argument "repeat"
74+
#:call repeat_code(repeat=3)
75+
this will be repeated 3 times
76+
#:endcall repeat_code
77+
78+
#! This will not show up in the output
79+
#! Also the newline characters at the end of the lines will be suppressed
80+
81+
#! Definitions are read, but no output (e.g. newlines) will be produced
82+
#:mute
83+
#:include "macrodefs.fypp"
84+
#:endmute
85+
86+
#:if DEBUGLEVEL < 0
87+
#:stop 'Negative debug level not allowed!'
88+
#:endif
89+
90+
#:def mymacro(RANK)
91+
#! Macro only works for RANK 1 and above
92+
#:assert RANK > 0
93+
#:enddef mymacro
94+
95+
program test
96+
#:if defined('MPI')
97+
use mpi
98+
#:endif
99+
end program
100+
101+
#{if 1 > 2}#Some code#{endif}#
102+
103+
@:mymacro(a<b)
104+
105+
print *, @{mymacro(a <b)}@
106+
107+
#:if defined('DEBUG') #! The Python function defined() expects a string argument
108+
#:for dtype in ['real(dp)', 'integer', 'logical'] #! dtype runs over strings
109+
110+
print *, "This is line nr. ${_LINE_}$ in file '${_FILE_}$'"
111+
112+
print *, "Rendering started ${_DATE_}$ ${_TIME_}$"
113+
114+
$:setvar('i', 1, 'j', 2)
115+
print *, "VAR I: ${i}$, VAR J: ${j}$"
116+
117+
$:delvar('i', 'j')
118+
119+
#{set X = 2}#print *, ${X}$
120+
121+
#:set real_kinds = ['sp', 'dp']
122+
123+
interface sin2
124+
#:for rkind in real_kinds
125+
module procedure sin2_${rkind}$
126+
#:endfor
127+
end interface sin2
128+
129+
#:for rkind in real_kinds
130+
function sin2_${rkind}$ (xx) result(res)
131+
real(${rkind}$), intent(in) :: xx
132+
real(${rkind}$) :: res
133+
134+
res = sin(xx)*sin(xx)
135+
136+
end function sin2_${rkind}$
137+
#:endfor
138+
139+
#:set kinds = ['sp', 'dp']
140+
#:set names = ['real', 'dreal']
141+
#! create kinds_names as [('sp', 'real'), ('dp', 'dreal')]
142+
#:set kinds_names = list(zip(kinds, names))
143+
144+
#! Acces by indexing
145+
interface sin2
146+
#:for kind_name in kinds_names
147+
module procedure sin2_${kind_name[1]}$
148+
#:endfor
149+
end interface sin2
150+
151+
#! Unpacking in the loop header
152+
#:for kind, name in kinds_names
153+
function sin2_${name}$ (xx) result(res)
154+
real(${kind}$), intent(in) :: xx
155+
real(${kind}$) :: res
156+
157+
res = sin(xx)*sin(xx)
158+
159+
end function sin2_${name}$
160+
#:endfor
161+
162+
#:def assertTrue(cond)
163+
#:if DEBUG > 0
164+
if (.not. (${cond}$)) then
165+
print *, "Assert failed!"
166+
error stop
167+
end if
168+
#:endif
169+
#:enddef
170+
171+
#:def macro(X, *VARARGS)
172+
X = ${X}$, VARARGS = #{for ARG in VARARGS}#${ARG}$#{endfor}#
173+
#:enddef macro
174+
175+
$:macro(1,2, 3) #! Returns "X=1, VARARGS=23"
176+
177+
! Rather ugly
178+
print *, #{call choose_code}# a(:) #{nextarg}# size(a) #{endcall}#
179+
180+
! This form is more readable
181+
print *, ${choose_code('a(:)', 'size(a)')}$
182+
183+
! Alternatively, you may use a direct call (see next section)
184+
print *, @{choose_code(a(:), size(a))}@
185+
186+
@:assertEqual(size(coords, dim=2), &
187+
& size( atomtypes))
188+
189+
#! Using choose_code() macro defined in previous section
190+
print *, @{choose_code(a(:),size(a))}@
191+
192+
#:if a > b &
193+
& or b > c &
194+
& or c>d
195+
$:somePythonFunction( param1, &
196+
&param2)
197+
198+
#:mute
199+
200+
#! Enable debug feature if the preprocessor variable DEBUG has been defined
201+
#:set DEBUG = defined('DEBUG')
202+
203+
#! Stops the code, if the condition passed to it is not fulfilled
204+
#! Only included in debug mode.
205+
#:def ensure(cond, msg=None)
206+
#:if DEBUG
207+
if (.not. (${cond}$)) then
208+
write (*, *) 'Run-time check failed'
209+
write (*, *) 'Condition: ${cond.replace("'", "''")}$'
210+
#:if msg is not None
211+
write (*, *) 'Message: ', ${msg}$
212+
#:endif
213+
write (*, *) 'File: ${_FILE_}$'
214+
write (*, *) 'Line: ', ${_LINE_}$
215+
stop
216+
end if
217+
#:endif
218+
#:enddef ensure
219+
220+
#! Includes code if in debug mode.
221+
#:def debug_code(code)
222+
#:if DEBUG
223+
$:code
224+
#:endif
225+
#:enddef debug_code
226+
227+
#:endmute
228+
229+
#:include 'checks.fypp'
230+
231+
module testmod
232+
implicit none
233+
234+
contains
235+
236+
subroutine someFunction(ind, uplo)
237+
integer, intent(in) :: ind
238+
character, intent(in) :: uplo
239+
240+
@:ensure(ind > 0, msg="Index must be positive")
241+
@:ensure(uplo == 'U' .or. uplo == 'L')
242+
243+
! Do something useful here
244+
245+
#:call debug_code
246+
print *, 'We are in debug mode'
247+
print *, 'The value of ind is', ind
248+
#:endcall debug_code
249+
250+
end subroutine someFunction
251+
252+
end module testmod
253+
254+
#:def ranksuffix(RANK)
255+
$:'' if RANK == 0 else '(' + ':' + ',:' * (RANK - 1) + ')'
256+
#:enddef ranksuffix
257+
258+
#:set PRECISIONS = ['sp', 'dp']
259+
#:set RANKS = range(0, 8)
260+
261+
module errorcalc
262+
implicit none
263+
264+
integer, parameter :: sp = kind(1.0)
265+
integer, parameter :: dp = kind(1.0d0)
266+
267+
interface maxRelError
268+
#:for PREC in PRECISIONS
269+
#:for RANK in RANKS
270+
module procedure maxRelError_${RANK}$_${PREC}$
271+
#:endfor
272+
#:endfor
273+
end interface maxRelError
274+
275+
contains
276+
277+
#:for PREC in PRECISIONS
278+
#:for RANK in RANKS
279+
280+
function maxRelError_${RANK}$_${PREC}$ (obtained, reference) result(res)
281+
real(${PREC}$), intent(in) :: obtained${ranksuffix(RANK)}$
282+
real(${PREC}$), intent(in) :: reference${ranksuffix(RANK)}$
283+
real(${PREC}$) :: res
284+
285+
#:if RANK == 0
286+
res = abs((obtained - reference)/reference)
287+
#:else
288+
res = maxval(abs((obtained - reference)/reference))
289+
#:endif
290+
291+
end function maxRelError_${RANK}$_${PREC}$
292+
293+
#:endfor
294+
#:endfor
295+
296+
end module errorcalc
297+
298+
#:def maxRelError_template(RANK, PREC)
299+
function maxRelError_${RANK}$_${PREC}$ (obtained, reference) result(res)
300+
real(${PREC}$), intent(in) :: obtained${ranksuffix(RANK)}$
301+
real(${PREC}$), intent(in) :: reference${ranksuffix(RANK)}$
302+
real(${PREC}$) :: res
303+
304+
#:if RANK == 0
305+
res = abs((obtained - reference)/reference)
306+
#:else
307+
res = maxval(abs((obtained - reference)/reference))
308+
#:endif
309+
310+
end function maxRelError_${RANK}$_${PREC}$
311+
#:enddef maxRelError_template
312+
313+
#:for PREC in PRECISIONS
314+
#:for RANK in RANKS
315+
$:maxRelError_template(RANK, PREC)
316+
#:endfor
317+
#:endfor
318+
319+
end module errorcalc
320+

0 commit comments

Comments
 (0)