Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features(demo): enable assertion removal and selective testing #233

Merged
merged 11 commits into from
Nov 28, 2024
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