Skip to content

Commit

Permalink
Merge pull request #233 from BerkeleyLab/macro-assertions
Browse files Browse the repository at this point in the history
Features(demo): enable assertion removal and selective testing
  • Loading branch information
rouson authored Nov 28, 2024
2 parents f56fc7e + 36226ea commit a09d219
Show file tree
Hide file tree
Showing 13 changed files with 302 additions and 246 deletions.
40 changes: 21 additions & 19 deletions demo/app/tensor-statistics.f90 → demo/app/tensor-statistics.F90
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
! Copyright (c), The Regents of the University of California
! Terms of use are as specified in LICENSE.txt

#include "assert_macros.h"

module ubounds_m
!! This module serves only to support array bounds checking in the main program below
implicit none
Expand All @@ -25,29 +27,29 @@ elemental function equals(lhs, rhs) result(lhs_equals_rhs)
program tensor_statistics
!! This program
!! 1. Computes the ranges and histograms of input and output tensors saved by
!! the neural-net branch of the Berkeley Lab fork of [ICAR](https://berkeleylab.github/icar).
!! the neural-net branch of the Berkeley Lab fork of [ICAR](https://go.lbl.gov/icar).
!! 2. Saves the resulting statistics to text files with space-separated columns and column labels.

! External dependencies:
use julienne_m, only : command_line_t, file_t, string_t
use assert_m, only : assert, intrinsic_array_t
use assert_m
use ubounds_m, only : ubounds_t
use ieee_arithmetic, only : ieee_is_nan
use iso_fortran_env, only : int64, real64

! Internal dependencies:
use NetCDF_file_m, only: NetCDF_file_t
use histogram_m, only : histogram_t, to_file
use histogram_m, only: histogram_t, to_file
implicit none

character(len=*), parameter :: usage = &
new_line('a') // new_line('a') // &
'Usage: ' // new_line('a') // new_line('a') // &
'./build/run-fpm.sh run tensor-statistics -- \' // new_line('a') // &
' --base <string> --bins <integer> \' // new_line('a') // &
character(len=*), parameter :: usage = new_line('a') // new_line('a') // &
'Usage: ' // new_line('a') // new_line('a') // &
'./build/run-fpm.sh run tensor-statistics -- \' // new_line('a') // &
' --base <string> --bins <integer> \' // new_line('a') // &
' [--raw] [--start <integer>] [--end <integer>] [--stride <integer>]' // &
new_line('a') // new_line('a') // &
'where angular brackets denote user-provided values and square brackets denote optional arguments.' // new_line('a')
new_line('a') // new_line('a') // &
'where angular brackets denote user-provided values and square brackets denote optional arguments.' &
// new_line('a')

integer(int64) t_start, t_finish, clock_rate
integer num_bins, start_step, stride
Expand Down Expand Up @@ -85,7 +87,7 @@ subroutine get_command_line_arguments(base_name, num_bins, start_step, end_step,
type(command_line_t) command_line
character(len=:), allocatable :: stride_string, bins_string, start_string, end_string

base_name = command_line%flag_value("--base") ! gfortran 13 seg faults if this is an association
base_name = command_line%flag_value("--base")
bins_string = command_line%flag_value("--bins")
start_string = command_line%flag_value("--start")
end_string = command_line%flag_value("--end")
Expand Down Expand Up @@ -204,9 +206,9 @@ subroutine compute_histograms(base_name, raw)
lbounds = [lbounds, lbound(qv_out), lbound(qc_out), lbound(qr_out), lbound(qs_out)]
ubounds = [ubounds, ubounds_t(ubound(qv_out)), ubounds_t(ubound(qc_out)), &
ubounds_t(ubound(qr_out)), ubounds_t(ubound(qs_out))]
call assert(all(lbounds == 1), "main: default input/output lower bounds", intrinsic_array_t(lbounds))
call assert(all(ubounds == ubounds(1)), "main: matching input/output upper bounds")
call assert(all(abs(time_in(2:t_end) - time_out(1:t_end-1))<tolerance), "main: matching time stamps")
call_assert_diagnose(all(lbounds == 1), "main: default input/output lower bounds", intrinsic_array_t(lbounds))
call_assert_describe(all(ubounds == ubounds(1)), "main: matching input/output upper bounds")
call_assert_describe(all(abs(time_in(2:t_end) - time_out(1:t_end-1))<tolerance), "main: matching time stamps")
end associate

print *,"Calculating time derivatives"
Expand All @@ -227,11 +229,11 @@ subroutine compute_histograms(base_name, raw)
end do
end associate

call assert(.not. any(ieee_is_nan(dpt_dt)), ".not. any(ieee_is_nan(dpt_dt)")
call assert(.not. any(ieee_is_nan(dqv_dt)), ".not. any(ieee_is_nan(dqv_dt)")
call assert(.not. any(ieee_is_nan(dqc_dt)), ".not. any(ieee_is_nan(dqc_dt)")
call assert(.not. any(ieee_is_nan(dqr_dt)), ".not. any(ieee_is_nan(dqr_dt)")
call assert(.not. any(ieee_is_nan(dqs_dt)), ".not. any(ieee_is_nan(dqs_dt)")
call_assert(.not. any(ieee_is_nan(dpt_dt)))
call_assert(.not. any(ieee_is_nan(dqv_dt)))
call_assert(.not. any(ieee_is_nan(dqc_dt)))
call_assert(.not. any(ieee_is_nan(dqr_dt)))
call_assert(.not. any(ieee_is_nan(dqs_dt)))

print *,"Calculating output tensor histograms."
call system_clock(t_histo_start, clock_rate)
Expand Down
74 changes: 26 additions & 48 deletions demo/app/train-cloud-microphysics.F90
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
! Copyright (c), The Regents of the University of California
! Terms of use are as specified in LICENSE.txt

# include "assert_macros.h"

program train_cloud_microphysics
!! Train a neural network to represent the simplest cloud microphysics model from
!! the Intermediate Complexity Atmospheric Research Model (ICAR) at
!! https://github.com/BerkeleyLab/icar.
!! Train a neural network to represent a cloud microphysics model from
!! [ICAR](https://go.lbl.gov/icar))

!! Intrinic modules :
!! Intrinsic modules :
use iso_fortran_env, only : int64, real64

!! External dependencies:
use julienne_m, only : string_t, file_t, command_line_t, bin_t
use assert_m, only : assert, intrinsic_array_t
use assert_m
use fiats_m, only : &
neural_network_t, mini_batch_t, input_output_pair_t, tensor_t, trainable_network_t, tensor_map_t, training_configuration_t, &
shuffle
Expand All @@ -20,16 +22,18 @@ program train_cloud_microphysics
use NetCDF_file_m, only: NetCDF_file_t
use NetCDF_variable_m, only: NetCDF_variable_t, tensors
use occupancy_m, only : occupancy_t
use default_m, only: default_or_internal_read

implicit none

character(len=*), parameter :: usage = new_line('a') // new_line('a') // &
'Usage: ' // new_line('a') // new_line('a') // &
'./build/run-fpm.sh run train-cloud-microphysics -- \' // new_line('a') // &
' --base <string> --epochs <integer> \' // new_line('a') // &
character(len=*), parameter :: usage = new_line('') // new_line('') // &
'Usage: ' // new_line('') // new_line('') // &
'./build/run-fpm.sh run train-cloud-microphysics -- \' // new_line('') // &
' --base <string> --epochs <integer> \' // new_line('') // &
' [--start <integer>] [--end <integer>] [--stride <integer>] [--bins <integer>] [--report <integer>] [--tolerance <real>]'// &
new_line('a') // new_line('a') // &
'where angular brackets denote user-provided values and square brackets denote optional arguments.' // new_line('a') // &
'The presence of a file named "stop" halts execution gracefully.'
new_line('') // new_line('') // &
'where angular brackets denote user-provided values and square brackets denote optional arguments.' // new_line('') // &
'The presence of a file named "stop" halts execution gracefully.' // new_line('')

type command_line_arguments_t
integer num_epochs, start_step, stride, num_bins, report_step
Expand Down Expand Up @@ -108,7 +112,7 @@ function get_command_line_arguments() result(command_line_arguments)
integer, allocatable :: end_step
integer num_epochs, num_bins, start_step, stride, report_step

base_name = command_line%flag_value("--base") ! gfortran 13 seg faults if this is an association
base_name = command_line%flag_value("--base")
epochs_string = command_line%flag_value("--epochs")
start_string = command_line%flag_value("--start")
end_string = command_line%flag_value("--end")
Expand All @@ -123,11 +127,11 @@ function get_command_line_arguments() result(command_line_arguments)

read(epochs_string,*) num_epochs

stride = default_integer_or_read(1, stride_string)
start_step = default_integer_or_read(1, start_string)
report_step = default_integer_or_read(1, report_string)
num_bins = default_integer_or_read(3, bins_string)
cost_tolerance = default_real_or_read(5E-8, tolerance_string)
stride = default_or_internal_read(1, stride_string)
start_step = default_or_internal_read(1, start_string)
report_step = default_or_internal_read(1, report_string)
num_bins = default_or_internal_read(3, bins_string)
cost_tolerance = default_or_internal_read(5E-8, tolerance_string)

if (len(end_string)/=0) then
allocate(end_step)
Expand Down Expand Up @@ -183,7 +187,7 @@ subroutine read_train_write(training_configuration, args, plot_file)
end do

do v = 2, size(input_variable)
call assert(input_variable(v)%conformable_with(input_variable(1)), "train_cloud_microphysics: input variable conformance")
call_assert(input_variable(v)%conformable_with(input_variable(1)))
end do

print *,"- reading time"
Expand Down Expand Up @@ -212,13 +216,13 @@ subroutine read_train_write(training_configuration, args, plot_file)
end do

do v = 1, size(output_variable)
call assert(output_variable(v)%conformable_with(input_variable(1)), "train_cloud_microphysics: output variable conformance")
call_assert(output_variable(v)%conformable_with(input_variable(1)))
end do

print *,"- reading time"
call output_time%input("time", output_file, rank=1)

call assert(output_time%conformable_with(input_time), "train_cloud_microphysics: input/output time conformance")
call_assert(output_time%conformable_with(input_time))

end associate output_file
end associate output_file_name
Expand All @@ -234,7 +238,7 @@ subroutine read_train_write(training_configuration, args, plot_file)
associate(derivative_name => "d" // output_names(v)%string() // "/dt")
print *,"- " // derivative_name
derivative(v) = NetCDF_variable_t( (input_variable(v) - output_variable(v)) / dt, derivative_name)
call assert(.not. derivative(v)%any_nan(), "train_cloud_microhphysics: non NaN's")
call_assert(.not. derivative(v)%any_nan())
end associate derivative_name
end do
end associate dt
Expand Down Expand Up @@ -436,30 +440,4 @@ subroutine read_train_write(training_configuration, args, plot_file)

end subroutine read_train_write

pure function default_integer_or_read(default, string) result(set_value)
integer, intent(in) :: default
character(len=*), intent(in) :: string
integer set_value

if (len(string)==0) then
set_value = default
else
read(string,*) set_value
end if

end function

pure function default_real_or_read(default, string) result(set_value)
real, intent(in) :: default
character(len=*), intent(in) :: string
real set_value

if (len(string)==0) then
set_value = default
else
read(string,*) set_value
end if

end function

end program train_cloud_microphysics
2 changes: 1 addition & 1 deletion demo/fpm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ author = "(Please see fiats/fpm.toml.)"
maintainer = "(Please see fiats/fpm.toml.)"

[dependencies]
assert = {git = "https://github.com/sourceryinstitute/assert", tag = "1.7.0"}
assert = {git = "https://github.com/sourceryinstitute/assert", tag = "2.0.0"}
julienne = {git = "https://github.com/berkeleylab/julienne", tag = "1.5.3"}
fiats = {path = "../"}
netcdf-interfaces = {git = "https://github.com/LKedward/netcdf-interfaces.git", rev = "d2bbb71ac52b4e346b62572b1ca1620134481096"}
Loading

0 comments on commit a09d219

Please sign in to comment.