From 527749d23f533c6987940ca831aae4d5f06ac39d Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sat, 23 Nov 2024 19:15:40 -0500
Subject: [PATCH 01/15] feat(neural_net): mk assert_consistency removable

This commit
1. Converts the assert_consistency generic binding to a generic
   interface,
2. Converts all invocations of assert_consistency to macros, and
3. Thereby facilitates the complete removal of the calls when the
   ASSERTIONS macro is zero or not present.
---
 src/fiats/neural_network_m.f90   |  7 +++--
 src/fiats/neural_network_s.F90   | 52 +++++++++++++++++---------------
 src/fiats/unmapped_network_s.f90 |  9 ++++--
 3 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/src/fiats/neural_network_m.f90 b/src/fiats/neural_network_m.f90
index 50bdd7654..1d51dad17 100644
--- a/src/fiats/neural_network_m.f90
+++ b/src/fiats/neural_network_m.f90
@@ -16,6 +16,7 @@ module neural_network_m
   public :: neural_network_t
   public :: unmapped_network_t
   public :: workspace_t
+  public :: assert_consistency
 
   type neural_network_t(k)
     !! Encapsulate the information needed to perform inference
@@ -39,8 +40,6 @@ module neural_network_m
     generic :: skip                     => default_real_skip,                    double_precision_skip
     generic :: activation_function_name => default_real_activation_name,         double_precision_activation_name
     generic :: learn                    => default_real_learn
-    generic :: assert_consistency       => default_real_consistency,             double_precision_consistency
-    procedure, private, non_overridable :: default_real_consistency,             double_precision_consistency
     procedure, private, non_overridable :: default_real_approximately_equal,     double_precision_approximately_equal
     procedure, private, non_overridable :: default_real_infer,                   double_precision_infer
     procedure, private, non_overridable :: default_real_learn
@@ -298,6 +297,10 @@ pure module subroutine default_real_learn(self, mini_batches_arr, cost, adam, le
       type(workspace_t), intent(inout) :: workspace
     end subroutine
 
+  end interface
+
+  interface assert_consistency
+
     pure module subroutine default_real_consistency(self)
       implicit none
       class(neural_network_t), intent(in) :: self
diff --git a/src/fiats/neural_network_s.F90 b/src/fiats/neural_network_s.F90
index 6f3334c80..ef292f4dd 100644
--- a/src/fiats/neural_network_s.F90
+++ b/src/fiats/neural_network_s.F90
@@ -1,7 +1,11 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+#include "compound_assertions.h"
+
 submodule(neural_network_m) neural_network_s
-  use assert_m, only : assert, intrinsic_array_t
+  use assert_m
   use double_precision_string_m, only : double_precision_string_t
   use kind_parameters_m, only : double_precision
   use layer_m, only : layer_t
@@ -34,7 +38,7 @@
     real, allocatable :: a(:,:)
     integer l
 
-    call self%assert_consistency()
+    call_assert_consistency(self)
 
     associate(w => self%weights_, b => self%biases_, n => self%nodes_, output_layer => ubound(self%nodes_,1))
 
@@ -80,7 +84,7 @@
     double precision, allocatable :: a(:,:)
     integer l
 
-    call self%assert_consistency()
+    call_assert_consistency(self)
 
     associate(w => self%weights_, b => self%biases_, n => self%nodes_, output_layer => ubound(self%nodes_,1))
 
@@ -198,7 +202,7 @@
 
     neural_network%activation_ = activation_t(metadata(4)%string())
 
-    call neural_network%assert_consistency()
+    call_assert_consistency(neural_network)
 
   end procedure default_real_construct_from_components
 
@@ -237,7 +241,7 @@
       neural_network%activation_ = activation_t(function_name%string())
     end associate
 
-    call neural_network%assert_consistency()
+    call_assert_consistency(neural_network)
 
   end procedure double_precision_construct_from_components
 
@@ -252,7 +256,7 @@
     proto_neuron = neuron_t([0.],1.)
 #endif
 
-    call self%assert_consistency()
+    call_assert_consistency(self)
 
     associate( &
        num_hidden_layers => self%num_hidden_layers() &
@@ -368,7 +372,7 @@
     proto_neuron = neuron_t([0D0],1D0)
 #endif
 
-    call self%assert_consistency()
+    call_assert_consistency(self)
 
     associate( &
        num_hidden_layers => self%num_hidden_layers() &
@@ -571,7 +575,7 @@
       end associate
     end associate read_metadata
 
-    call neural_network%assert_consistency()
+    call_assert_consistency(neural_network)
 
   end procedure default_real_from_json
 
@@ -671,13 +675,13 @@
       end associate
     end associate read_metadata
 
-    call neural_network%assert_consistency()
+    call_assert_consistency(neural_network)
 
   end procedure double_precision_from_json
 
   module procedure default_real_assert_conformable_with
 
-    call self%assert_consistency()
+    call_assert_consistency(self)
 
     associate(equal_shapes => [ &
       shape(self%weights_) == shape(neural_network%weights_), &
@@ -693,7 +697,7 @@
 
   module procedure double_precision_assert_conformable_with
 
-    call self%assert_consistency()
+    call_assert_consistency(self)
 
     associate(equal_shapes => [ &
       shape(self%weights_) == shape(neural_network%weights_), &
@@ -713,8 +717,8 @@
 
     nodes_eq = all(lhs%nodes_ == rhs%nodes_)
 
-    call lhs%assert_consistency()
-    call rhs%assert_consistency()
+    call_assert_consistency(lhs)
+    call_assert_consistency(rhs)
     call lhs%assert_conformable_with(rhs)
 
     block
@@ -754,8 +758,8 @@
 
     nodes_eq = all(lhs%nodes_ == rhs%nodes_)
 
-    call lhs%assert_consistency()
-    call rhs%assert_consistency()
+    call_assert_consistency(lhs)
+    call_assert_consistency(rhs)
     call lhs%assert_conformable_with(rhs)
 
     block
@@ -790,18 +794,18 @@
   end procedure
 
   module procedure default_real_num_outputs
-    call self%assert_consistency()
+    call_assert_consistency(self)
     output_count = self%nodes_(ubound(self%nodes_,1))
   end procedure
 
   module procedure double_precision_num_outputs
-    call self%assert_consistency()
+    call_assert_consistency(self)
     output_count = self%nodes_(ubound(self%nodes_,1))
   end procedure
 
   module procedure default_real_num_hidden_layers
     integer, parameter :: num_non_hidden_layers = 2
-    call self%assert_consistency()
+    call_assert_consistency(self)
     associate(num_layers => size(self%nodes_))
       hidden_layer_count =  num_layers - num_non_hidden_layers
     end associate
@@ -809,29 +813,29 @@
 
   module procedure double_precision_num_hidden_layers
     integer, parameter :: num_non_hidden_layers = 2
-    call self%assert_consistency()
+    call_assert_consistency(self)
     associate(num_layers => size(self%nodes_))
       hidden_layer_count =  num_layers - num_non_hidden_layers
     end associate
   end procedure
 
   module procedure default_real_num_inputs
-    call self%assert_consistency()
+    call_assert_consistency(self)
     input_count = self%nodes_(lbound(self%nodes_,1))
   end procedure
 
   module procedure double_precision_num_inputs
-    call self%assert_consistency()
+    call_assert_consistency(self)
     input_count = self%nodes_(lbound(self%nodes_,1))
   end procedure
 
   module procedure default_real_nodes_per_layer
-    call self%assert_consistency()
+    call_assert_consistency(self)
     node_count = self%nodes_
   end procedure
 
   module procedure double_precision_nodes_per_layer
-    call self%assert_consistency()
+    call_assert_consistency(self)
     node_count = self%nodes_
   end procedure
 
@@ -863,7 +867,7 @@
     integer l, batch, mini_batch_size, pair
     type(tensor_t), allocatable :: inputs(:), expected_outputs(:)
 
-    call self%assert_consistency()
+    call_assert_consistency(self)
     call assert(workspace%fully_allocated(), "neural_network_s(default_real_learn): workspace%fully_allocated()")
 
     associate(output_layer => ubound(self%nodes_,1))
diff --git a/src/fiats/unmapped_network_s.f90 b/src/fiats/unmapped_network_s.f90
index 4a2cf6e43..82b7ca5e2 100644
--- a/src/fiats/unmapped_network_s.f90
+++ b/src/fiats/unmapped_network_s.f90
@@ -1,6 +1,11 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+#include "compound_assertions.h"
+
 submodule(neural_network_m) unmapped_network_s
+  use assert_m
   implicit none
 
   integer, parameter :: input_layer = 0 
@@ -18,7 +23,7 @@
 
     associate(neural_network => self%neural_network_)
 
-      call neural_network%assert_consistency()
+      call_assert_consistency(neural_network)
 
       associate( &
         w => neural_network%weights_ &
@@ -55,7 +60,7 @@
 
     associate(neural_network => self%neural_network_)
 
-      call neural_network%assert_consistency()
+      call_assert_consistency(neural_network)
 
       associate( &
         w => neural_network%weights_ &

From 8d672cdcf11c9d872c698049ce86385273be6ce0 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 00:38:21 -0500
Subject: [PATCH 02/15] feat(neural_net): mk assert_conformable removable

---
 src/fiats/neural_network_m.f90 | 14 --------------
 src/fiats/neural_network_s.F90 | 28 ++++++++++++++++++++++------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/fiats/neural_network_m.f90 b/src/fiats/neural_network_m.f90
index 1d51dad17..0b78067dd 100644
--- a/src/fiats/neural_network_m.f90
+++ b/src/fiats/neural_network_m.f90
@@ -36,7 +36,6 @@ module neural_network_m
     generic :: num_inputs               => default_real_num_inputs,              double_precision_num_inputs
     generic :: num_outputs              => default_real_num_outputs,             double_precision_num_outputs
     generic :: nodes_per_layer          => default_real_nodes_per_layer,         double_precision_nodes_per_layer
-    generic :: assert_conformable_with  => default_real_assert_conformable_with, double_precision_assert_conformable_with
     generic :: skip                     => default_real_skip,                    double_precision_skip
     generic :: activation_function_name => default_real_activation_name,         double_precision_activation_name
     generic :: learn                    => default_real_learn
@@ -50,7 +49,6 @@ module neural_network_m
     procedure, private, non_overridable :: default_real_num_inputs,              double_precision_num_inputs
     procedure, private, non_overridable :: default_real_num_outputs,             double_precision_num_outputs
     procedure, private, non_overridable :: default_real_nodes_per_layer,         double_precision_nodes_per_layer
-    procedure, private, non_overridable :: default_real_assert_conformable_with, double_precision_assert_conformable_with
     procedure, private, non_overridable :: default_real_skip,                    double_precision_skip
     procedure, private, non_overridable :: default_real_activation_name,         double_precision_activation_name
   end type
@@ -189,18 +187,6 @@ impure elemental module function double_precision_to_json(self) result(json_file
       type(file_t) json_file
     end function
 
-    elemental module subroutine default_real_assert_conformable_with(self, neural_network)
-      implicit none
-      class(neural_network_t), intent(in) :: self
-      type(neural_network_t), intent(in) :: neural_network
-    end subroutine
-
-    elemental module subroutine double_precision_assert_conformable_with(self, neural_network)
-      implicit none
-      class(neural_network_t(double_precision)), intent(in) :: self
-      type(neural_network_t(double_precision)), intent(in) :: neural_network
-    end subroutine
-
     elemental module function default_real_infer(self, inputs) result(outputs)
       implicit none
       class(neural_network_t), intent(in) :: self
diff --git a/src/fiats/neural_network_s.F90 b/src/fiats/neural_network_s.F90
index ef292f4dd..1fec846e7 100644
--- a/src/fiats/neural_network_s.F90
+++ b/src/fiats/neural_network_s.F90
@@ -15,6 +15,22 @@
   character(len=*), parameter :: minimum_acceptable_tag = "0.15.0" ! git tag capable of reading the current json file format
   integer, parameter :: input_layer = 0 
 
+  interface assert_conformable
+   
+    elemental module subroutine default_real_assert_conformable_with(self, neural_network)
+      implicit none
+      class(neural_network_t), intent(in) :: self
+      type(neural_network_t), intent(in) :: neural_network
+    end subroutine
+
+    elemental module subroutine double_precision_assert_conformable_with(self, neural_network)
+      implicit none
+      class(neural_network_t(double_precision)), intent(in) :: self
+      type(neural_network_t(double_precision)), intent(in) :: neural_network
+    end subroutine
+
+  end interface
+
 contains
 
   module procedure default_real_map_to_input_range
@@ -688,10 +704,10 @@
       shape(self%biases_) == shape(neural_network%biases_), &
       shape(self%nodes_) == shape(neural_network%nodes_)  &
      ])
-      call assert(all(equal_shapes), "assert_conformable_with: all(equal_shapes)", intrinsic_array_t(equal_shapes))
+      call assert(all(equal_shapes), "assert_conformable: all(equal_shapes)", intrinsic_array_t(equal_shapes))
     end associate
 
-    call assert(self%activation_ == neural_network%activation_, "assert_conformable_with: activation_")
+    call assert(self%activation_ == neural_network%activation_, "assert_conformable: activation_")
     
   end procedure
 
@@ -704,10 +720,10 @@
       shape(self%biases_) == shape(neural_network%biases_), &
       shape(self%nodes_) == shape(neural_network%nodes_)  &
      ])
-      call assert(all(equal_shapes), "assert_conformable_with: all(equal_shapes)", intrinsic_array_t(equal_shapes))
+      call assert(all(equal_shapes), "assert_conformable: all(equal_shapes)", intrinsic_array_t(equal_shapes))
     end associate
 
-    call assert(self%activation_ == neural_network%activation_, "assert_conformable_with: activation_")
+    call assert(self%activation_ == neural_network%activation_, "assert_conformable: activation_")
     
   end procedure
 
@@ -719,7 +735,7 @@
 
     call_assert_consistency(lhs)
     call_assert_consistency(rhs)
-    call lhs%assert_conformable_with(rhs)
+    call_assert_conformable(lhs, rhs)
 
     block
       integer l
@@ -760,7 +776,7 @@
 
     call_assert_consistency(lhs)
     call_assert_consistency(rhs)
-    call lhs%assert_conformable_with(rhs)
+    call_assert_conformable(lhs, rhs)
 
     block
       integer l

From 7a08e160ef78ec89cb074a00c85e7839b7e32c55 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 08:24:47 -0500
Subject: [PATCH 03/15] chore(training_config): rm unused `use` statement

---
 src/fiats/training_configuration_s.F90 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/fiats/training_configuration_s.F90 b/src/fiats/training_configuration_s.F90
index f72e1a659..8df7ef088 100644
--- a/src/fiats/training_configuration_s.F90
+++ b/src/fiats/training_configuration_s.F90
@@ -1,7 +1,6 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(training_configuration_m) training_configuration_s
-  use assert_m, only : assert
   use double_precision_string_m, only : double_precision_string_t
   use activation_m, only : activation_t, gelu, relu, sigmoid, swish
   implicit none

From a6a5765fd0964330f1818ddcdb27bce2d6998e67 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 08:29:58 -0500
Subject: [PATCH 04/15] chore: rm `only` in `use assert_m` statements

This follows the advice in the following Assert library example:

https://github.com/BerkeleyLab/assert/blob/1c6062079ad7f9752e53404bd85fae77576f657e/example/invoke-via-macro.F90#L6
---
 src/fiats/activation_s.f90            | 2 +-
 src/fiats/hyperparameters_s.f90       | 2 +-
 src/fiats/layer_s.f90                 | 2 +-
 src/fiats/metadata_s.f90              | 2 +-
 src/fiats/network_configuration_s.F90 | 2 +-
 src/fiats/neuron_s.f90                | 2 +-
 src/fiats/tensor_map_s.f90            | 2 +-
 src/fiats/tensor_names_s.f90          | 2 +-
 src/fiats/workspace_s.f90             | 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/fiats/activation_s.f90 b/src/fiats/activation_s.f90
index 876417de9..0c11b4e0a 100644
--- a/src/fiats/activation_s.f90
+++ b/src/fiats/activation_s.f90
@@ -1,5 +1,5 @@
 submodule(activation_m) activation_s
-  use assert_m, only : assert
+  use assert_m
   implicit none
 
   real            , parameter :: pi    = 3.141592653589793
diff --git a/src/fiats/hyperparameters_s.f90 b/src/fiats/hyperparameters_s.f90
index e6df53996..160594b27 100644
--- a/src/fiats/hyperparameters_s.f90
+++ b/src/fiats/hyperparameters_s.f90
@@ -1,7 +1,7 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(hyperparameters_m) hyperparameters_s
-  use assert_m, only : assert
+  use assert_m
   implicit none
 
   character(len=*), parameter :: mini_batches_key  = "mini-batches"
diff --git a/src/fiats/layer_s.f90 b/src/fiats/layer_s.f90
index 589740b36..3c3ec6220 100644
--- a/src/fiats/layer_s.f90
+++ b/src/fiats/layer_s.f90
@@ -1,7 +1,7 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(layer_m) layer_s
-  use assert_m, only : assert
+  use assert_m
   implicit none
 
 contains
diff --git a/src/fiats/metadata_s.f90 b/src/fiats/metadata_s.f90
index ca521d0ff..438ca799f 100644
--- a/src/fiats/metadata_s.f90
+++ b/src/fiats/metadata_s.f90
@@ -1,7 +1,7 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(metadata_m) metadata_s
-  use assert_m, only : assert
+  use assert_m
   implicit none
 
 contains
diff --git a/src/fiats/network_configuration_s.F90 b/src/fiats/network_configuration_s.F90
index 750ca0cc2..6e099ca3e 100644
--- a/src/fiats/network_configuration_s.F90
+++ b/src/fiats/network_configuration_s.F90
@@ -1,7 +1,7 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(network_configuration_m) network_configuration_s
-  use assert_m, only : assert
+  use assert_m
   use julienne_formats_m, only : csv
   implicit none
 
diff --git a/src/fiats/neuron_s.f90 b/src/fiats/neuron_s.f90
index 1226f1bf3..60c41a71d 100644
--- a/src/fiats/neuron_s.f90
+++ b/src/fiats/neuron_s.f90
@@ -1,7 +1,7 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(neuron_m) neuron_s
-  use assert_m, only : assert
+  use assert_m
   use julienne_formats_m, only : separated_values
   implicit none
 
diff --git a/src/fiats/tensor_map_s.f90 b/src/fiats/tensor_map_s.f90
index 4651078f2..cf6c13692 100644
--- a/src/fiats/tensor_map_s.f90
+++ b/src/fiats/tensor_map_s.f90
@@ -1,7 +1,7 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(tensor_map_m) tensor_map_s
-  use assert_m, only : assert
+  use assert_m
   use julienne_m, only : separated_values
   use kind_parameters_m, only : default_real
   implicit none
diff --git a/src/fiats/tensor_names_s.f90 b/src/fiats/tensor_names_s.f90
index defb9cead..4a9894f59 100644
--- a/src/fiats/tensor_names_s.f90
+++ b/src/fiats/tensor_names_s.f90
@@ -1,7 +1,7 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
 submodule(tensor_names_m) tensor_names_s
-  use assert_m, only : assert
+  use assert_m
   use julienne_m, only : operator(.csv.), operator(.cat.)
   implicit none
 
diff --git a/src/fiats/workspace_s.f90 b/src/fiats/workspace_s.f90
index f3e1209d6..4d47e7e90 100644
--- a/src/fiats/workspace_s.f90
+++ b/src/fiats/workspace_s.f90
@@ -1,5 +1,5 @@
 submodule(neural_network_m) workspace_s
-  use assert_m, only : assert
+  use assert_m
   implicit none
 
   integer, parameter :: input_layer = 0

From cd9fac20819be186a78a6ad4faac56b4133ecbb3 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 09:17:09 -0500
Subject: [PATCH 05/15] chore(workspace_s): invoke `assert` via macro

---
 src/fiats/{workspace_s.f90 => workspace_s.F90} | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
 rename src/fiats/{workspace_s.f90 => workspace_s.F90} (97%)

diff --git a/src/fiats/workspace_s.f90 b/src/fiats/workspace_s.F90
similarity index 97%
rename from src/fiats/workspace_s.f90
rename to src/fiats/workspace_s.F90
index 4d47e7e90..1a3ef71d1 100644
--- a/src/fiats/workspace_s.f90
+++ b/src/fiats/workspace_s.F90
@@ -1,3 +1,5 @@
+#include "assert_macros.h"
+
 submodule(neural_network_m) workspace_s
   use assert_m
   implicit none
@@ -30,7 +32,7 @@
       allocate(workspace%a(maxval(neural_network%nodes_), input_layer:output_layer)) ! Activations
     end associate
 
-    call assert(workspace%fully_allocated(), "workspace_s(defalt_real_workspace): workspace allocated")
+    call_assert(workspace%fully_allocated())
 
   end procedure
 

From d282bfecb9528fefed90c5befc7ffb89e69b69b9 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 09:22:52 -0500
Subject: [PATCH 06/15] chore(hyperparameters_s):invoke `assert` via macro

---
 src/fiats/hyperparameters_s.f90 | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/fiats/hyperparameters_s.f90 b/src/fiats/hyperparameters_s.f90
index 160594b27..277b06890 100644
--- a/src/fiats/hyperparameters_s.f90
+++ b/src/fiats/hyperparameters_s.f90
@@ -1,5 +1,8 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+
 submodule(hyperparameters_m) hyperparameters_s
   use assert_m
   implicit none
@@ -26,8 +29,7 @@
 
     real, parameter :: tolerance = 1.E-08
 
-    call assert(allocated(lhs%optimizer_) .and. allocated(rhs%optimizer_), &
-      "hyperparameters_s(default_real_equals): allocated optimizers")
+    call_assert(allocated(lhs%optimizer_) .and. allocated(rhs%optimizer_))
 
     lhs_equals_rhs = &
       lhs%mini_batches_ == rhs%mini_batches_ .and. &
@@ -40,8 +42,7 @@
 
     double precision, parameter :: tolerance = 1.D-15
 
-    call assert(allocated(lhs%optimizer_) .and. allocated(rhs%optimizer_), &
-      "hyperparameters_s(double_precisionequals): allocated optimizers")
+    call_assert(allocated(lhs%optimizer_) .and. allocated(rhs%optimizer_))
 
     lhs_equals_rhs = &
       lhs%mini_batches_ == rhs%mini_batches_ .and. &
@@ -66,7 +67,7 @@
       end if
     end do
 
-    call assert(hyperparameters_key_found, "hyperparameters_s(default_real_from_json): hyperparameters_found")
+    call_assert(hyperparameters_key_found)
   end procedure
 
   module procedure double_precision_from_json
@@ -85,7 +86,7 @@
       end if
     end do
 
-    call assert(hyperparameters_key_found, "hyperparameters_s(double_precision_from_json): hyperparameters_found")
+    call_assert(hyperparameters_key_found)
   end procedure
 
   module procedure default_real_to_json

From 9d6495f31d9cb9a7182a462f4a23f4acb28aed46 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 09:42:31 -0500
Subject: [PATCH 07/15] chore(layer_s): mk some `assert` calls macros

---
 src/fiats/layer_s.f90 | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/fiats/layer_s.f90 b/src/fiats/layer_s.f90
index 3c3ec6220..5ae8867b1 100644
--- a/src/fiats/layer_s.f90
+++ b/src/fiats/layer_s.f90
@@ -1,5 +1,8 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+
 submodule(layer_m) layer_s
   use assert_m
   implicit none
@@ -77,7 +80,7 @@
       num_hidden_layers =>  hidden_layers%count_layers(), &
       num_output_layers => output_layer%count_layers() &
     )   
-      call assert(num_output_layers==1, "neural_network_s(default_real_neural_network): 1 output layer", num_output_layers)
+      call_assert(num_output_layers==1)
 
       associate(nodes => [num_inputs, neurons_per_hidden_layer, num_outputs])
         associate(n_max => maxval(nodes))
@@ -149,7 +152,7 @@
       num_hidden_layers =>  hidden_layers%count_layers(), &
       num_output_layers => output_layer%count_layers() &
     )   
-      call assert(num_output_layers==1, "neural_network_s(double_precision_neural_network): 1 output layer", num_output_layers)
+      call_assert(num_output_layers==1)
 
       associate(nodes => [num_inputs, neurons_per_hidden_layer, num_outputs])
         associate(n_max => maxval(nodes))

From fcd6c4c294f92ca25e42e3d440187b08685a653d Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 09:45:23 -0500
Subject: [PATCH 08/15] chore(metadata_s): mk some `assert` calls macros

---
 src/fiats/metadata_s.f90 | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/fiats/metadata_s.f90 b/src/fiats/metadata_s.f90
index 438ca799f..c3cd83134 100644
--- a/src/fiats/metadata_s.f90
+++ b/src/fiats/metadata_s.f90
@@ -1,5 +1,8 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+
 submodule(metadata_m) metadata_s
   use assert_m
   implicit none
@@ -25,7 +28,7 @@
   module procedure from_json
     integer l
 
-    call assert(lines(1)%get_json_key() == "metadata", "metadata_s(from_json): metadata found")
+    call_assert(lines(1)%get_json_key() == "metadata")
 
     do l = 2, size(lines)-1
       associate(key => lines(l)%get_json_key())
@@ -52,7 +55,7 @@
   module procedure double_precision_from_json
     integer l
 
-    call assert(lines(1)%get_json_key() == "metadata", "metadata_s(double_precision_from_json): metadata found")
+    call_assert(lines(1)%get_json_key() == "metadata")
 
     do l = 2, size(lines)-1
       associate(key => lines(l)%get_json_key())

From dc00272d1fa33a05f1063cd15e980cb2cadc5b4f Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 09:49:18 -0500
Subject: [PATCH 09/15] chore(net_config_s): mk some `assert` calls macros

---
 src/fiats/network_configuration_s.F90 | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/fiats/network_configuration_s.F90 b/src/fiats/network_configuration_s.F90
index 6e099ca3e..867f9989d 100644
--- a/src/fiats/network_configuration_s.F90
+++ b/src/fiats/network_configuration_s.F90
@@ -1,5 +1,8 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+
 submodule(network_configuration_m) network_configuration_s
   use assert_m
   use julienne_formats_m, only : csv
@@ -19,8 +22,7 @@
 
   module procedure equals
 
-    call assert(allocated(lhs%activation_name_) .and. allocated(rhs%activation_name_), &
-     "network_configuration_s(equals): allocated({lhs,rhs}%activation_name_)")
+    call_assert(allocated(lhs%activation_name_) .and. allocated(rhs%activation_name_))
 
     lhs_equals_rhs = &
       lhs%skip_connections_ .eqv. rhs%skip_connections_ .and. &
@@ -45,7 +47,7 @@
       end if
     end do
 
-    call assert(network_configuration_key_found, "network_configuration_s(from_json): network_configuration_found")
+    call_assert(network_configuration_key_found)
   end procedure
 
   module procedure from_double_precision_string_json
@@ -64,8 +66,7 @@
       end if
     end do
 
-    call assert(network_configuration_key_found, &
-      "network_configuration_s(from_double_precision_string_json): network_configuration_found")
+    call_assert(network_configuration_key_found)
   end procedure
 
   module procedure to_json

From 5894e049e90533f53f54e158b1085835e0f28220 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 09:51:02 -0500
Subject: [PATCH 10/15] chore(neuron_s): mk some `assert` calls macros

---
 src/fiats/{neuron_s.f90 => neuron_s.F90} | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
 rename src/fiats/{neuron_s.f90 => neuron_s.F90} (97%)

diff --git a/src/fiats/neuron_s.f90 b/src/fiats/neuron_s.F90
similarity index 97%
rename from src/fiats/neuron_s.f90
rename to src/fiats/neuron_s.F90
index 60c41a71d..7f4c4f708 100644
--- a/src/fiats/neuron_s.f90
+++ b/src/fiats/neuron_s.F90
@@ -1,5 +1,8 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+
 submodule(neuron_m) neuron_s
   use assert_m
   use julienne_formats_m, only : separated_values
@@ -12,7 +15,7 @@
     character(len=*), parameter :: indent = repeat(" ",ncopies=12)
     character(len=:), allocatable :: csv_format, weights_string, bias_string
 
-    call assert(allocated(self%weights_), "neuron_s(to_json): allocated weights_")
+    call_assert(allocated(self%weights_))
 
     csv_format = separated_values(separator=",", mold=[real::])
     allocate(character(len=size(self%weights_)*(characters_per_value+1)-1)::weights_string)
@@ -32,7 +35,7 @@
     character(len=*), parameter :: indent = repeat(" ",ncopies=12)
     character(len=:), allocatable :: csv_format, weights_string, bias_string
 
-    call assert(allocated(self%weights_), "neuron_s(to_json): allocated weights_")
+    call_assert(allocated(self%weights_))
 
     csv_format = separated_values(separator=",", mold=[double precision::])
     allocate(character(len=size(self%weights_)*(characters_per_value+1)-1)::weights_string)

From 8e1fe627fd734f4e559544c88076a81552ed9454 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 10:01:09 -0500
Subject: [PATCH 11/15] chore(tensor_map_s): mk all `assert` calls macros

---
 src/fiats/tensor_map_s.f90 | 53 +++++++++++++++-----------------------
 1 file changed, 21 insertions(+), 32 deletions(-)

diff --git a/src/fiats/tensor_map_s.f90 b/src/fiats/tensor_map_s.f90
index cf6c13692..106b28773 100644
--- a/src/fiats/tensor_map_s.f90
+++ b/src/fiats/tensor_map_s.f90
@@ -1,5 +1,8 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+
 submodule(tensor_map_m) tensor_map_s
   use assert_m
   use julienne_m, only : separated_values
@@ -9,7 +12,7 @@
 contains
 
   module procedure construct_default_real
-    call assert(size(minima)==size(maxima),"tensor_map_s(construct_default_real): size(minima)==size(maxima)")
+    call_assert(size(minima)==size(maxima))
     tensor_map%layer_ = layer
     tensor_map%intercept_ = minima
     tensor_map%slope_ = maxima - minima
@@ -32,7 +35,7 @@
   end procedure
 
   module procedure construct_double_precision
-    call assert(size(minima)==size(maxima),"tensor_map_s(construct_double_precision): size(minima)==size(maxima)")
+    call_assert(size(minima)==size(maxima))
     tensor_map%layer_ = layer
     tensor_map%intercept_ = minima
     tensor_map%slope_ = maxima - minima
@@ -54,7 +57,7 @@
       end if
     end do 
 
-    call assert(tensor_map_key_found, "tensor_map_s(from_json): 'tensor_map' key found")
+    call_assert(tensor_map_key_found)
   end procedure
 
   module procedure double_precision_from_json
@@ -73,22 +76,17 @@
       end if
     end do
 
-    call assert(tensor_map_key_found, "tensor_map_s(from_json): 'tensor_map' key found")
+    call_assert(tensor_map_key_found)
   end procedure
 
   module procedure default_real_equals
     real, parameter :: tolerance = 1.E-08
 
-    call assert(allocated(lhs%layer_) .and. allocated(rhs%layer_), &
-      "tensor_map_s(default_real_equals): allocated layer_ components")
-    call assert(allocated(lhs%intercept_) .and. allocated(rhs%intercept_), &
-      "tensor_map_s(default_real_equals): allocated intercept_ components)")
-    call assert(allocated(lhs%slope_) .and.  allocated(rhs%slope_), &
-      "tensor_map_s(default_real_equals): allocated slope_ components)")
-    call assert(size(lhs%intercept_) == size(rhs%intercept_), &
-       "tensor_map_s(default_real_equals): size(lhs%intercept_) == size(rhs%intercept_)")
-    call assert(size(lhs%slope_) == size(rhs%slope_), &
-       "tensor_map_s(default_real_equals): size(lhs%slope_) == size(rhs%slope_)")
+    call_assert(allocated(lhs%layer_    ) .and. allocated(rhs%layer_    ))
+    call_assert(allocated(lhs%intercept_) .and. allocated(rhs%intercept_))
+    call_assert(allocated(lhs%slope_    ) .and. allocated(rhs%slope_    ))
+    call_assert(size(lhs%intercept_) == size(rhs%intercept_))
+    call_assert(size(lhs%slope_    ) == size(rhs%slope_    ))
 
     lhs_equals_rhs = &
       lhs%layer_ == rhs%layer_ .and. &
@@ -99,16 +97,11 @@
   module procedure double_precision_equals
     double precision, parameter :: tolerance = 1.D-015
 
-    call assert(allocated(lhs%layer_) .and. allocated(rhs%layer_), &
-      "tensor_map_s(double_precision_equals): allocated layer_ components")
-    call assert(allocated(lhs%intercept_) .and. allocated(rhs%intercept_), &
-      "tensor_map_s(double_precision_equals): allocated intercept_ components)")
-    call assert(allocated(lhs%slope_) .and.  allocated(rhs%slope_), &
-      "tensor_map_s(double_precision_equals): allocated slope_ components)")
-    call assert(size(lhs%intercept_) == size(rhs%intercept_), &
-      "tensor_map_s(double_precision_equals): size(lhs%intercept_) == size(rhs%intercept_)")
-    call assert(size(lhs%slope_) == size(rhs%slope_), &
-      "tensor_map_s(double_precision_equals): size(lhs%slope_) == size(rhs%slope_)")
+    call_assert(allocated(lhs%layer_    ) .and. allocated(rhs%layer_    ))
+    call_assert(allocated(lhs%intercept_) .and. allocated(rhs%intercept_))
+    call_assert(allocated(lhs%slope_    ) .and. allocated(rhs%slope_    ))
+    call_assert(size(lhs%intercept_) == size(rhs%intercept_))
+    call_assert(size(lhs%slope_    ) == size(rhs%slope_    ))
 
     lhs_equals_rhs = &
       lhs%layer_ == rhs%layer_ .and. &
@@ -121,10 +114,8 @@
     character(len=*), parameter :: indent = repeat(" ",ncopies=4)
     character(len=:), allocatable :: csv_format, intercept_string, slope_string
 
-    call assert(allocated(self%layer_), &
-      "tensor_map_s(default_real_to_json): allocated layer_")
-    call assert(allocated(self%intercept_) .and. allocated(self%slope_), &
-      "tensor_map_s(default_real_to_json): allocated intercept_/slope_")
+    call_assert(allocated(self%layer_))
+    call_assert(allocated(self%intercept_) .and. allocated(self%slope_))
 
     csv_format = separated_values(separator=",", mold=[real(default_real)::])
     allocate(character(len=size(self%intercept_)*(characters_per_value+1)-1)::intercept_string)
@@ -150,10 +141,8 @@
     character(len=*), parameter :: indent = repeat(" ",ncopies=4)
     character(len=:), allocatable :: csv_format, intercept_string, slope_string
 
-    call assert(allocated(self%layer_), &
-      "tensor_map_s(default_real_to_json): allocated layer_")
-    call assert(allocated(self%intercept_) .and. allocated(self%slope_), &
-      "tensor_map_s(default_real_to_json): allocated intercept_/slope_")
+    call_assert(allocated(self%layer_))
+    call_assert(allocated(self%intercept_) .and. allocated(self%slope_))
 
     csv_format = separated_values(separator=",", mold=[double precision::])
     allocate(character(len=size(self%intercept_)*(characters_per_value+1)-1)::intercept_string)

From bf958d445cf052dca17ce44d6fdd802d7a0fa440 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 10:31:41 -0500
Subject: [PATCH 12/15] chore(tensor_names): mk all `assert` calls macros

---
 src/fiats/{tensor_names_s.f90 => tensor_names_s.F90} | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
 rename src/fiats/{tensor_names_s.f90 => tensor_names_s.F90} (86%)

diff --git a/src/fiats/tensor_names_s.f90 b/src/fiats/tensor_names_s.F90
similarity index 86%
rename from src/fiats/tensor_names_s.f90
rename to src/fiats/tensor_names_s.F90
index 4a9894f59..befae1ca9 100644
--- a/src/fiats/tensor_names_s.f90
+++ b/src/fiats/tensor_names_s.F90
@@ -1,5 +1,8 @@
 ! Copyright (c), The Regents of the University of California
 ! Terms of use are as specified in LICENSE.txt
+
+#include "assert_macros.h"
+
 submodule(tensor_names_m) tensor_names_s
   use assert_m
   use julienne_m, only : operator(.csv.), operator(.cat.)
@@ -16,8 +19,7 @@
   end procedure 
 
   module procedure equals
-    call assert( all([allocated(lhs%inputs_), allocated(rhs%inputs_), allocated(lhs%outputs_), allocated(rhs%outputs_)]) &
-      ,"tensor_names_s(equals): all components allocated")
+    call_assert( all([allocated(lhs%inputs_), allocated(rhs%inputs_), allocated(lhs%outputs_), allocated(rhs%outputs_)]))
     lhs_equals_rhs = all(lhs%inputs_ == rhs%inputs_) .and. all(lhs%outputs_ == rhs%outputs_)
   end procedure 
 
@@ -36,7 +38,7 @@
       end if
     end do
 
-    call assert(tensor_names_key_found, "tensor_names_s(from_json): tensor_names_found")
+    call assert(tensor_names_key_found)
   end procedure
 
   module procedure to_json

From 68da71f7587446bfec4b246363c5e03c40343808 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 10:40:42 -0500
Subject: [PATCH 13/15] chore: add missing copyright statements

---
 src/fiats/activation_m.f90        | 3 +++
 src/fiats/activation_s.f90        | 3 +++
 src/fiats/trainable_network_m.f90 | 3 +++
 src/fiats/trainable_network_s.f90 | 3 +++
 src/fiats/workspace_s.F90         | 3 +++
 5 files changed, 15 insertions(+)

diff --git a/src/fiats/activation_m.f90 b/src/fiats/activation_m.f90
index 9450a069c..8e5948386 100644
--- a/src/fiats/activation_m.f90
+++ b/src/fiats/activation_m.f90
@@ -1,3 +1,6 @@
+! Copyright (c), The Regents of the University of California
+! Terms of use are as specified in LICENSE.txt
+
 module activation_m
   use iso_c_binding, only :  c_int
   use julienne_m, only : string_t
diff --git a/src/fiats/activation_s.f90 b/src/fiats/activation_s.f90
index 0c11b4e0a..c9fddad58 100644
--- a/src/fiats/activation_s.f90
+++ b/src/fiats/activation_s.f90
@@ -1,3 +1,6 @@
+! Copyright (c), The Regents of the University of California
+! Terms of use are as specified in LICENSE.txt
+
 submodule(activation_m) activation_s
   use assert_m
   implicit none
diff --git a/src/fiats/trainable_network_m.f90 b/src/fiats/trainable_network_m.f90
index a085168fa..c7420f76a 100644
--- a/src/fiats/trainable_network_m.f90
+++ b/src/fiats/trainable_network_m.f90
@@ -1,3 +1,6 @@
+! Copyright (c), The Regents of the University of California
+! Terms of use are as specified in LICENSE.txt
+
 module trainable_network_m
   use neural_network_m, only : neural_network_t, workspace_t
   use input_output_pair_m, only : input_output_pair_t
diff --git a/src/fiats/trainable_network_s.f90 b/src/fiats/trainable_network_s.f90
index 12c025661..7c2f8a909 100644
--- a/src/fiats/trainable_network_s.f90
+++ b/src/fiats/trainable_network_s.f90
@@ -1,3 +1,6 @@
+! Copyright (c), The Regents of the University of California
+! Terms of use are as specified in LICENSE.txt
+
 submodule(trainable_network_m) trainable_network_s
   implicit none 
 
diff --git a/src/fiats/workspace_s.F90 b/src/fiats/workspace_s.F90
index 1a3ef71d1..290b33957 100644
--- a/src/fiats/workspace_s.F90
+++ b/src/fiats/workspace_s.F90
@@ -1,3 +1,6 @@
+! Copyright (c), The Regents of the University of California
+! Terms of use are as specified in LICENSE.txt
+
 #include "assert_macros.h"
 
 submodule(neural_network_m) workspace_s

From f17daefbad97e432183061c021c5bac0174e6800 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 10:49:13 -0500
Subject: [PATCH 14/15] fix(tensor_name_s): switch `assert` call to macro

---
 src/fiats/tensor_names_s.F90 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/fiats/tensor_names_s.F90 b/src/fiats/tensor_names_s.F90
index befae1ca9..c132e2d9d 100644
--- a/src/fiats/tensor_names_s.F90
+++ b/src/fiats/tensor_names_s.F90
@@ -19,7 +19,7 @@
   end procedure 
 
   module procedure equals
-    call_assert( all([allocated(lhs%inputs_), allocated(rhs%inputs_), allocated(lhs%outputs_), allocated(rhs%outputs_)]))
+    call_assert(all([allocated(lhs%inputs_), allocated(rhs%inputs_), allocated(lhs%outputs_), allocated(rhs%outputs_)]))
     lhs_equals_rhs = all(lhs%inputs_ == rhs%inputs_) .and. all(lhs%outputs_ == rhs%outputs_)
   end procedure 
 
@@ -38,7 +38,7 @@
       end if
     end do
 
-    call assert(tensor_names_key_found)
+    call_assert(tensor_names_key_found)
   end procedure
 
   module procedure to_json

From ef258a8c5886dcf2fb81c018b5c45fc8c7958931 Mon Sep 17 00:00:00 2001
From: Damian Rouson <rouson@lbl.gov>
Date: Sun, 24 Nov 2024 11:05:03 -0500
Subject: [PATCH 15/15] fix: add include/compound_assertions.h

---
 include/compound_assertions.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 include/compound_assertions.h

diff --git a/include/compound_assertions.h b/include/compound_assertions.h
new file mode 100644
index 000000000..69ddc2d81
--- /dev/null
+++ b/include/compound_assertions.h
@@ -0,0 +1,23 @@
+! Copyright (c), The Regents of the University of California
+! Terms of use are as specified in LICENSE.txt
+
+! This file provides preprocessor-based macros to call procedures that exist
+! solely to make calls to 'assert' and that therefore will be eliminated completely
+! whenever the ASSERTIONS macro is defined to a value other than 0.
+
+! Enable repeated includes to toggle assertions based on current settings:
+#undef call_assert_consistency
+#undef call_assert_conformable
+
+#ifndef ASSERTIONS
+! Assertions are off by default
+#define ASSERTIONS 0
+#endif
+
+#if ASSERTIONS
+# define call_assert_consistency(obj) call assert_consistency(obj)
+# define call_assert_conformable(lhs,rhs) call assert_conformable(lhs,rhs)
+#else
+# define call_assert_consistency(obj)
+# define call_assert_conformable(lhs,rhs)
+#endif
