Skip to content

Commit 7c6c04a

Browse files
Merge pull request #46 from jacobwilliams/40-quad-precision
add quad precision support
2 parents 411fd77 + d714c22 commit 7c6c04a

File tree

5 files changed

+93
-20
lines changed

5 files changed

+93
-20
lines changed

.github/workflows/CI.yml

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
os: [ubuntu-latest]
13-
gcc_v: [9,10,11,12] # gfortran versions to test
14-
python-version: [3.9]
13+
gcc_v: [12, 13] # gfortran versions to test
14+
python-version: [3.12]
1515
env:
1616
FC: gfortran-${{ matrix.gcc_v }}
1717
GCC_V: ${{ matrix.gcc_v }}
@@ -23,22 +23,22 @@ jobs:
2323
submodules: recursive
2424

2525
- name: Install Python
26-
if: contains( matrix.gcc_v, 10 )
27-
uses: actions/setup-python@v4 # Use pip to install latest CMake, & FORD/Jin2For, etc.
26+
if: contains( matrix.gcc_v, 12 )
27+
uses: actions/setup-python@v5.4.0 # Use pip to install latest CMake, & FORD/Jin2For, etc.
2828
with:
2929
python-version: ${{ matrix.python-version }}
3030

3131
- name: Setup Graphviz
32-
if: contains( matrix.gcc_v, 10 )
32+
if: contains( matrix.gcc_v, 12 )
3333
uses: ts-graphviz/setup-graphviz@v1
3434

3535
- name: Setup Fortran Package Manager
36-
uses: fortran-lang/setup-fpm@v5
36+
uses: fortran-lang/setup-fpm@v7
3737
with:
3838
github-token: ${{ secrets.GITHUB_TOKEN }}
3939

4040
- name: Install Python dependencies
41-
if: contains( matrix.gcc_v, 10 )
41+
if: contains( matrix.gcc_v, 12 )
4242
run: |
4343
python -m pip install --upgrade pip
4444
pip install ford numpy matplotlib
@@ -59,7 +59,7 @@ jobs:
5959
run: fpm test --profile debug --flag -coverage
6060

6161
- name: Create coverage report
62-
if: contains( matrix.gcc_v, 10 )
62+
if: contains( matrix.gcc_v, 12 )
6363
run: |
6464
mkdir -p ${{ env.COV_DIR }}
6565
mv ./build/gfortran_*/*/* ${{ env.COV_DIR }}
@@ -70,18 +70,19 @@ jobs:
7070
COV_DIR: build/coverage
7171

7272
- name: Upload coverage report
73-
if: contains( matrix.gcc_v, 10 )
73+
if: contains( matrix.gcc_v, 12 )
7474
uses: codecov/codecov-action@v3
7575
with:
7676
files: build/coverage/coverage.info
7777

7878
- name: Build documentation
79-
if: contains( matrix.gcc_v, 10 )
79+
if: contains( matrix.gcc_v, 12 )
8080
run: ford ./ford.md
8181

8282
- name: Deploy Documentation
83-
if: contains( matrix.gcc_v, 10 ) && github.ref == 'refs/heads/master'
84-
uses: JamesIves/github-pages-deploy-action@v4.4.1
83+
if: contains( matrix.gcc_v, 12 ) && github.ref == 'refs/heads/master'
84+
uses: JamesIves/github-pages-deploy-action@v4.7.3
8585
with:
8686
branch: gh-pages # The branch the action should deploy to.
8787
folder: doc # The folder the action should deploy.
88+
single-commit: true

src/csv_kinds.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
module csv_kinds
66

7-
use iso_fortran_env, only: real64,real32,int32
7+
use iso_fortran_env, only: real128,real64,real32,int32
88

99
private
1010

11+
integer,parameter,public :: qp = real128 !! quad real kind
1112
integer,parameter,public :: wp = real64 !! default real kind
1213
integer,parameter,public :: sp = real32 !! additional real kind, single precision
1314
integer,parameter,public :: ip = int32 !! default integer kind

src/csv_module.F90

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ module csv_module
9191
csv_get_value,&
9292
get_real_sp_column,&
9393
get_real_wp_column,&
94+
get_real_qp_column,&
9495
get_integer_column,&
9596
get_logical_column,&
9697
get_character_column,&
@@ -99,6 +100,7 @@ module csv_module
99100
procedure :: csv_get_value
100101
procedure :: get_real_sp_column
101102
procedure :: get_real_wp_column
103+
procedure :: get_real_qp_column
102104
procedure :: get_integer_column
103105
procedure :: get_logical_column
104106
procedure :: get_character_column
@@ -441,15 +443,23 @@ subroutine add_cell(me,val,int_fmt,real_fmt,trim_str)
441443
if (present(real_fmt)) then
442444
rfmt = trim(adjustl(real_fmt))
443445
else
444-
rfmt = default_real_fmt
446+
rfmt = default_sp_fmt
445447
end if
446448
write(real_val,fmt=rfmt,iostat=istat) val
447449
write(me%iunit,fmt='(A)',advance='NO',iostat=istat) trim(adjustl(real_val))
448450
type is (real(wp))
449451
if (present(real_fmt)) then
450452
rfmt = trim(adjustl(real_fmt))
451453
else
452-
rfmt = default_real_fmt
454+
rfmt = default_wp_fmt
455+
end if
456+
write(real_val,fmt=rfmt,iostat=istat) val
457+
write(me%iunit,fmt='(A)',advance='NO',iostat=istat) trim(adjustl(real_val))
458+
type is (real(qp))
459+
if (present(real_fmt)) then
460+
rfmt = trim(adjustl(real_fmt))
461+
else
462+
rfmt = default_qp_fmt
453463
end if
454464
write(real_val,fmt=rfmt,iostat=istat) val
455465
write(me%iunit,fmt='(A)',advance='NO',iostat=istat) trim(adjustl(real_val))
@@ -756,6 +766,31 @@ pure elemental subroutine to_real_wp(str,val,status_ok)
756766
end subroutine to_real_wp
757767
!*****************************************************************************************
758768

769+
!*****************************************************************************************
770+
!>
771+
! Convert a string to a `real(qp)`
772+
773+
pure elemental subroutine to_real_qp(str,val,status_ok)
774+
775+
implicit none
776+
777+
character(len=*),intent(in) :: str
778+
real(qp),intent(out) :: val
779+
logical,intent(out) :: status_ok
780+
781+
integer :: istat !! read `iostat` error code
782+
783+
read(str,fmt=*,iostat=istat) val
784+
if (istat==0) then
785+
status_ok = .true.
786+
else
787+
status_ok = .false.
788+
val = zero
789+
end if
790+
791+
end subroutine to_real_qp
792+
!*****************************************************************************************
793+
759794
!*****************************************************************************************
760795
!>
761796
! Convert a string to a `integer(ip)`
@@ -924,6 +959,8 @@ subroutine csv_get_value(me,row,col,val,status_ok)
924959
call to_real_sp(me%csv_data(row,col)%str,val,status_ok)
925960
type is (real(wp))
926961
call to_real_wp(me%csv_data(row,col)%str,val,status_ok)
962+
type is (real(qp))
963+
call to_real_qp(me%csv_data(row,col)%str,val,status_ok)
927964
type is (logical)
928965
call to_logical(me%csv_data(row,col)%str,val,status_ok)
929966
type is (character(len=*))
@@ -1003,6 +1040,10 @@ subroutine get_column(me,icol,r,status_ok)
10031040
if (me%verbose) write(error_unit,'(A)') &
10041041
'Error converting string to real(real64): '//trim(me%csv_data(i,icol)%str)
10051042
r(i) = zero
1043+
type is (real(qp))
1044+
if (me%verbose) write(error_unit,'(A)') &
1045+
'Error converting string to real(real128): '//trim(me%csv_data(i,icol)%str)
1046+
r(i) = zero
10061047
type is (logical)
10071048
if (me%verbose) write(error_unit,'(A)') &
10081049
'Error converting string to logical: '//trim(me%csv_data(i,icol)%str)
@@ -1068,6 +1109,30 @@ subroutine get_real_wp_column(me,icol,r,status_ok)
10681109
end subroutine get_real_wp_column
10691110
!*****************************************************************************************
10701111

1112+
!*****************************************************************************************
1113+
!>
1114+
! Return a column from a CSV file as a `real(qp)` vector.
1115+
1116+
subroutine get_real_qp_column(me,icol,r,status_ok)
1117+
1118+
implicit none
1119+
1120+
class(csv_file),intent(inout) :: me
1121+
integer,intent(in) :: icol !! column number
1122+
real(qp),dimension(:),allocatable,intent(out) :: r
1123+
logical,intent(out) :: status_ok
1124+
1125+
if (allocated(me%csv_data)) then
1126+
allocate(r(me%n_rows)) ! size the output vector
1127+
call me%get_column(icol,r,status_ok)
1128+
else
1129+
if (me%verbose) write(error_unit,'(A,1X,I5)') 'Error: class has not been initialized'
1130+
status_ok = .false.
1131+
end if
1132+
1133+
end subroutine get_real_qp_column
1134+
!*****************************************************************************************
1135+
10711136
!*****************************************************************************************
10721137
!>
10731138
! Return a column from a CSV file as a `integer(ip)` vector.

src/csv_parameters.f90

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ module csv_parameters
88

99
private
1010

11-
integer(ip),parameter,public :: max_real_str_len = 27 !! maximum string length of a real number
12-
character(len=*),parameter,public :: default_real_fmt = '(E27.17E4)'
13-
!! default real number format statement (for writing real values to strings and files).
11+
integer(ip),parameter,public :: max_real_str_len = 256 !! maximum string length of a real number
12+
13+
character(len=*),parameter,public :: default_sp_fmt = '(E17.8E3)' !! default single number format statement
14+
character(len=*),parameter,public :: default_wp_fmt = '(E27.17E4)' !! default double number format statement
15+
character(len=*),parameter,public :: default_qp_fmt = '(E46.35E5)' !! default quad number format statement
1416

1517
integer(ip),parameter,public :: max_integer_str_len = 256 !! maximum string length of an integer.
1618
character(len=*),parameter,public :: default_int_fmt = '(I256)'
17-
!! default integer number format statement (for writing real values to strings and files).
19+
!! default integer number format statement (for writing integer values to strings and files).
1820

1921
end module csv_parameters
2022
!*******************************************************************************

test/csv_test.f90

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
program csv_test
88

99
use csv_module
10-
use iso_fortran_env, only: wp => real64, sp => real32
10+
use iso_fortran_env, only: wp => real64, sp => real32, qp => real128
1111

1212
implicit none
1313

@@ -29,6 +29,7 @@ subroutine csv_test_1()
2929
character(len=30),dimension(:,:),allocatable :: csv_data !! the data from the file as strings
3030
real(wp),dimension(:),allocatable :: x !! for getting a real(wp) vector from a csv file
3131
real(sp),dimension(:),allocatable :: y !! for getting a real(sp) vector from a csv file
32+
real(qp),dimension(:),allocatable :: z !! for getting a real(qp) vector from a csv file
3233
logical :: status_ok !! error flag
3334
integer,dimension(:),allocatable :: itypes !! array of variable types in the file
3435
integer :: ifile !! file counter
@@ -103,6 +104,9 @@ subroutine csv_test_1()
103104
call f%get(3,y,status_ok)
104105
write(*,'(F6.3,1x)',advance='NO') y
105106
write(*,*) ''
107+
108+
call f%get(3,z,status_ok) ! also try as quad precision
109+
106110
else
107111
write(*,*) ''
108112
write(*,*) 'name:'

0 commit comments

Comments
 (0)