Skip to content

Commit 7ccf375

Browse files
author
Damian Rouson
authored
Merge pull request #1 from sourceryinstitute/fpm-build
Add fpm build system and fix non-buildable code
2 parents 0353a5f + 7ab6fbd commit 7ccf375

14 files changed

+854
-2
lines changed

README.md

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,76 @@
1-
# sourcery
2-
A grab bag of tricks
1+
Sourcery Library
2+
================
3+
4+
A grab bag of useful tricks in Fortran 2018.
5+
6+
`
7+
`://:`
8+
./::+ss+.
9+
-++ydmmmdho-
10+
-+ohmNNNmmmmdy:
11+
.+ohmNNmNNddddddy:
12+
`++hmNNNmmNm+-:sdmdy:
13+
/+sdmNNNmmNmy` :ymdo
14+
.++ydmNNNmdmNd+ ..
15+
/+ohmNNNNNddmmds.
16+
.++ydmNNNNNmddmmmy:
17+
/++ydmmNNNNNmddmmmy/`
18+
.++ohdmmNNNNNmdhdmmmh+.
19+
/++shdmmNNNNNNmdhdmmmho.
20+
`+/+shdmmNNNNNNmddhdmmmho-
21+
://+yhdmmNNNNNNNmddhdmmmho-
22+
+//+yhdmmmNNNNNNmddhhmmmmho:
23+
-+//oyhdmmmNNNNNNmmddhdmmmmho-
24+
////oyhdmmmNNNNNNNmddhhdmmmmho- ``..--------..``
25+
`o//+oyhdmmmmNNNNNNmddhhhhyyso:-+hyssssssyyyyyyyyso/-
26+
-+//+oyhddmmmNNNNNNNmdh+::::::::sddhhhhyyyyhhdddddhhhy-
27+
./oys+:/+oyhddmmmNNNNNNNdo::/+osssyhhhhhhhyhdmmmh+-.`
28+
-+shddmms/:/+oyhddmmmNNNNNdo::/sdhyyyyyhhhhhhdmmmy/`
29+
-+yhhhhddmd:/:/+oyhddmmmNmho/:::+ddhyoooossyyhs:`
30+
`:syssyyyhdmmh-.--:/osssso+:---:/odNmdhyso+++sy+.
31+
:osoooossyhhdmmy:------------:/ohmNNNNmmdhysss:
32+
.+oo+++++oosyyhddmmdyso++++osyhmNNNNNNNNNNmdh+.
33+
.+++++///+++oosyyhhhddmmmmmmmNNNNNNNNNNNNmds:
34+
:+++////////++oosssyyhddmmmmmmmNNNNNNNmmh/`
35+
.++/////////+++oooosyhhdddmmmmmmmNNmmh+-
36+
./////////++++ooossyhhddddmmmmmddy+-
37+
.://////++++oossyyhhhhdhhhhy+:`
38+
.--::////++oossyyyso+:-`
39+
```...-..``
40+
41+
Utility functions
42+
-----------------
43+
44+
* Array functions
45+
* Assertions
46+
* Emulated intrinsic functions
47+
* String functions
48+
49+
Classes
50+
-------
51+
* (Co-)Object pattern abstract parent
52+
53+
Prerequisites
54+
-------------
55+
The following are the versions or commits currently employed in
56+
developing and testing. Earlier versions or commits might work also.
57+
58+
* Compiler: [GNU Fortran] (gfortran) 10.2.0
59+
* Parallel runtime library: [OpenCoarrays] 2.9.0
60+
* Fortran package manager: [fpm] 105644
61+
62+
This library also uses the [vegetables] unit testing framework, which
63+
the [fpm] build system will install automatically.
64+
65+
Downloding, Building, and Testing
66+
---------------------------------
67+
68+
```zsh
69+
git clone [email protected]:sourceryinstitute/sourcery
70+
fpm test --compiler caf --runner cafrun
71+
```
72+
73+
[GNU Fortran]: https://gcc.gnu.org
74+
[OpenCoarrays]: https://github.com/sourceryinstitute/opencoarrays
75+
[fpm]: https://github.com/fortran-lang/fpm
76+
[vegetables]: https://gitlab.com/everythingfunctional/vegetables

fpm.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name = "sourcery"
2+
version = "1.0.0"
3+
license = "BSD"
4+
author = ["Damian Rouson"]
5+
maintainer = "[email protected]"
6+
copyright = "2020 Sourcery Institute"
7+
8+
[dev-dependencies]
9+
vegetables = {git = "https://gitlab.com/everythingfunctional/vegetables", tag = "v5.1.1"}
10+
11+
#[[test]]
12+
#name="inputOutput"
13+
#source-dir="tests/unit/input-output"
14+
#main="main.f90"
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
!
2+
! (c) 2019-2020 Guide Star Engineering, LLC
3+
! This Software was developed for the US Nuclear Regulatory Commission (US NRC) under contract
4+
! "Multi-Dimensional Physics Implementation into Fuel Analysis under Steady-state and Transients (FAST)",
5+
! contract # NRC-HQ-60-17-C-0007
6+
!
7+
submodule(array_functions_interface) array_functions_implementation
8+
use assertions_interface, only : assert, assertions
9+
implicit none
10+
contains
11+
12+
module procedure column_vectors
13+
integer i, j, k
14+
15+
associate( n => shape(vector_field) )
16+
if (assertions) call assert(size(n)==4, "3D vector field input")
17+
allocate( array_of_3D_column_vectors( n(4), product(n(1:3)) ) )
18+
do concurrent( i=1:n(1), j=1:n(2), k=1:n(3) )
19+
associate( id => (k-1)*PRODUCT(n(1:2)) + (j-1)*n(1) + i )
20+
array_of_3D_column_vectors(:,id) = vector_field(i,j,k,:)
21+
end associate
22+
end do
23+
end associate
24+
25+
end procedure
26+
27+
module procedure concatenate_columns
28+
!! Using reshape rather than manipulating array elements directly frees the compiler to decide the particular order of array
29+
!! element references that best exploits the given platform. Alternatively, do concurrent could instead free the compiler
30+
!! to order element accesses however is best. Trade-off: reshape requires the creation of temporary array results but reshape
31+
!! is likely to have more mature compiler support than do concurrent. If this code turns out to be a critical performance
32+
!! bottleneck, try replacing this implementation with element-by-element copying using do concurrent.
33+
associate(rows=>size(a,1))
34+
associate(cols=>size(a,2)+size(b,2))
35+
associate(a_unrolled=>reshape(a,[size(a)]))
36+
associate(b_unrolled=>reshape(b,[size(b)]))
37+
if (assertions) call assert( rows==size(b,1), "array_functions: compatible shapes")
38+
concatenated = reshape( [a_unrolled, b_unrolled ],[rows, cols] )
39+
end associate; end associate; end associate; end associate
40+
end procedure
41+
42+
module procedure concatenate_rows
43+
!! For simplicity, this implementation invokes concatenate_columns at the cost of transpose creating additional temporaries.
44+
!! If this code turns out to be a critical performance bottleneck, try replacing this implementation with element-by-element
45+
!! copying using do concurrent.
46+
concatenated = transpose( concatenate_columns(transpose(a),transpose(b)) )
47+
end procedure
48+
49+
end submodule

src/array_functions_interface.f90

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
!
2+
! (c) 2019-2020 Guide Star Engineering, LLC
3+
! This Software was developed for the US Nuclear Regulatory Commission (US NRC) under contract
4+
! "Multi-Dimensional Physics Implementation into Fuel Analysis under Steady-state and Transients (FAST)",
5+
! contract # NRC-HQ-60-17-C-0007
6+
!
7+
module array_functions_interface
8+
!! author: Damian Rouson
9+
!! date: 04/25/2019
10+
!!
11+
!! Functionally pure array utilities
12+
implicit none
13+
14+
private
15+
public :: operator(.catColumns.)
16+
public :: operator(.catRows.)
17+
public :: operator(.columnVectors.)
18+
!! Because the Fortran standard requires that operator dummy arguments have the intent(in) attribute
19+
!! exposing only the operator and not the function names communicates more information in the
20+
!! public interface and in code using this interface.
21+
22+
interface operator(.columnVectors.)
23+
module procedure column_vectors
24+
end interface
25+
26+
interface operator(.catColumns.)
27+
module procedure concatenate_columns
28+
end interface
29+
30+
interface operator(.catRows.)
31+
module procedure concatenate_rows
32+
end interface
33+
34+
interface
35+
36+
pure module function column_vectors(vector_field) RESULT(array_of_3D_column_vectors)
37+
!! Result is array of 3D column vectors of dimension (space_dim,nx*ny*nz) reshaped from vector-field argument
38+
!! of dimension (nx,ny,nz,space_dim)
39+
implicit none
40+
real, dimension(:,:,:,:), intent(in) :: vector_field
41+
real, dimension(:,:), allocatable :: array_of_3D_column_vectors
42+
end function
43+
44+
pure module function concatenate_columns(a, b) RESULT(concatenated)
45+
!! Result contains the concatenation of the columns of argument a with the columns of argument b
46+
implicit none
47+
real, dimension(:,:), intent(in) :: a, b
48+
real, dimension(:,:), allocatable :: concatenated
49+
end function
50+
51+
pure module function concatenate_rows(a, b) RESULT(concatenated)
52+
!! Result contains the concatenation of the rows of argument a with the rows of argument b
53+
implicit none
54+
real, dimension(:,:), intent(in) :: a, b
55+
real, dimension(:,:), allocatable :: concatenated
56+
end function
57+
58+
end interface
59+
60+
end module

src/assertions_implementation.F90

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
!
2+
! (c) 2019-2020 Guide Star Engineering, LLC
3+
! This Software was developed for the US Nuclear Regulatory Commission (US NRC) under contract
4+
! "Multi-Dimensional Physics Implementation into Fuel Analysis under Steady-state and Transients (FAST)",
5+
! contract # NRC-HQ-60-17-C-0007
6+
!
7+
submodule(assertions_interface) assertions_implementation
8+
implicit none
9+
10+
contains
11+
12+
module procedure assert
13+
use iso_fortran_env, only : error_unit
14+
use string_functions_interface, only : string
15+
16+
character(len=:), allocatable :: header, trailer
17+
integer, parameter :: max_this_image_digits=9
18+
19+
if (assertions) then
20+
21+
if (.not. assertion) then
22+
23+
associate(assertion_failed_on => 'Assertion "' // description // '" failed on image')
24+
header = repeat(" ", ncopies = len(assertion_failed_on) + max_this_image_digits)
25+
write(header, *) assertion_failed_on, this_image()
26+
end associate
27+
28+
if (.not. present(diagnostic_data)) then
29+
30+
trailer = ""
31+
32+
else
33+
34+
block
35+
character(len=*), parameter :: lede = "with diagnostic data"
36+
37+
select type(diagnostic_data)
38+
type is(character(len=*))
39+
trailer = lede // diagnostic_data
40+
type is(integer)
41+
trailer = lede // string(diagnostic_data)
42+
class default
43+
trailer = lede // 'of unsupported type'
44+
end select
45+
end block
46+
47+
end if
48+
49+
error stop header // trailer
50+
51+
end if
52+
53+
end if
54+
55+
end procedure
56+
57+
end submodule

src/assertions_interface.F90

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
!
2+
! (c) 2019-2020 Guide Star Engineering, LLC
3+
! This Software was developed for the US Nuclear Regulatory Commission (US NRC) under contract
4+
! "Multi-Dimensional Physics Implementation into Fuel Analysis under Steady-state and Transients (FAST)",
5+
! contract # NRC-HQ-60-17-C-0007
6+
!
7+
#ifndef USE_ASSERTIONS
8+
# define USE_ASSERTIONS .true.
9+
#endif
10+
module assertions_interface
11+
!! summary: Utility for runtime checking of logical assertions.
12+
!! usage: error-terminate if the assertion fails:
13+
!!
14+
!! use assertions_interface, only : assert
15+
!! call assert( 2 > 1, "2 > 1")
16+
!!
17+
!! Turn off assertions in production code by setting USE_ASSERTIONS to .false. via the preprocessor:
18+
!!
19+
!! caf -cpp -DUSE_ASSERTIONS=.false. -c assertions_interface.f90
20+
!!
21+
!! Doing so may eliminate any associated runtime overhead by enabling optimizing compilers to ignore
22+
!! the assertion procedure body during a dead-code-removal phase of optimization.
23+
implicit none
24+
private
25+
public :: assert, assertions, max_errmsg_len
26+
27+
logical, parameter :: assertions=USE_ASSERTIONS
28+
integer, parameter :: max_errmsg_len = len( &
29+
"warning (183): FASTMEM allocation is requested but the libmemkind library is not linked in, so using the default allocator.")
30+
!! longest Intel compiler error message (see https://intel.ly/35x84yr).
31+
32+
interface
33+
34+
elemental module subroutine assert(assertion, description, diagnostic_data)
35+
!! If assertion is .false., error-terminate with optional, variable stop code containing diagnostic_data
36+
implicit none
37+
logical, intent(in) :: assertion
38+
!! Most assertions will be expressions, e.g., call assert( i>0, "positive i")
39+
character(len=*), intent(in) :: description
40+
!! Brief statement of what is being asserted
41+
class(*), intent(in), optional :: diagnostic_data
42+
!! Optional error stop code, which may be of intrinsic type or object class
43+
end subroutine
44+
45+
end interface
46+
47+
end module

src/co_object_implementation.f90

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
!
2+
! (c) 2019-2020 Guide Star Engineering, LLC
3+
! This Software was developed for the US Nuclear Regulatory Commission (US NRC) under contract
4+
! "Multi-Dimensional Physics Implementation into Fuel Analysis under Steady-state and Transients (FAST)",
5+
! contract # NRC-HQ-60-17-C-0007
6+
!
7+
submodule(co_object_interface) co_object_implementation
8+
implicit none
9+
10+
contains
11+
12+
module procedure mark_as_defined
13+
this%defined=.true.
14+
end procedure
15+
16+
module procedure user_defined
17+
is_defined = this%defined
18+
end procedure
19+
20+
end submodule

src/co_object_interface.f90

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
!
2+
! (c) 2019-2020 Guide Star Engineering, LLC
3+
! This Software was developed for the US Nuclear Regulatory Commission (US NRC) under contract
4+
! "Multi-Dimensional Physics Implementation into Fuel Analysis under Steady-state and Transients (FAST)",
5+
! contract # NRC-HQ-60-17-C-0007
6+
!
7+
module co_object_interface
8+
implicit none
9+
10+
private
11+
public :: co_object
12+
13+
! Define an abstract parent type to ensure basic functionality expected to be provided by all non-abstract types.
14+
! Each non-abstract type provides the functionality by extending this type and implementing its deferred binding(s). This
15+
! type resembles java's Object class in the sense that it is intended to be the ultimate ancester of every other type.
16+
type, abstract :: co_object
17+
private
18+
logical :: defined=.false.
19+
!! Default initialization indicates not yet user-defined
20+
logical, allocatable :: facilitate_type_extension[:]
21+
contains
22+
procedure :: mark_as_defined
23+
procedure :: user_defined
24+
end type
25+
26+
interface
27+
28+
pure module subroutine mark_as_defined(this)
29+
!! Mark the co_object as user-defined
30+
implicit none
31+
class(co_object), intent(inout) :: this
32+
end subroutine
33+
34+
pure module function user_defined(this) result(is_defined)
35+
!! Return a boolean result indicating whether this co_object has been initialized since its declaration
36+
implicit none
37+
class(co_object), intent(in) :: this
38+
logical :: is_defined
39+
end function
40+
41+
end interface
42+
43+
end module co_object_interface

0 commit comments

Comments
 (0)