From 44a6c798ec0a896aa755b7284d530780a709b442 Mon Sep 17 00:00:00 2001
From: Kyle Klenk <kyle.c.klenk@gmail.com>
Date: Sat, 27 Aug 2022 00:22:02 +0000
Subject: [PATCH] The GRU_actor seems to work

---
 build/includes/gru_actor/gru_actor.hpp        | 23 ++++++---
 .../gru_actor_subroutine_wrappers.hpp         |  2 +
 build/makefile                                |  2 +-
 build/source/actors/gru_actor/gru_actor.cpp   | 48 ++++++++++++++++++-
 build/source/actors/gru_actor/gru_actor.f90   | 11 +++++
 build/source/actors/hru_actor/hru_actor.cpp   |  2 +-
 build/source/actors/job_actor/job_actor.cpp   | 10 ++--
 7 files changed, 84 insertions(+), 14 deletions(-)

diff --git a/build/includes/gru_actor/gru_actor.hpp b/build/includes/gru_actor/gru_actor.hpp
index b0de960..a080475 100644
--- a/build/includes/gru_actor/gru_actor.hpp
+++ b/build/includes/gru_actor/gru_actor.hpp
@@ -12,19 +12,24 @@
 
 namespace caf{
 struct gru_state {
+    // GRU Initalization
+    int ref_gru;
+    int indx_gru;
+    std::string config_path;
     caf::actor file_access_actor;
+    int output_struc_size;
     caf::actor parent;
         
+    // HRU information
     std::vector<caf::actor> hru_list;
-
-    int indx_gru; // index for gru part of derived types in FORTRAN
-    int ref_gru; // The actual ID of the GRU we are
     int num_hrus;
+    int hrus_complete = 0;
 
+    // Global Data
     int nTimeDelay = 2000; // number of hours in the time delay histogram (default: ~1 season = 24*365/4)
-
     struct iLookVarType var_type_lookup;
     
+    // Data Structure local to the GRU
     int num_bpar_vars;                               // number of variables in the fortran structure for bpar_struct
     std::vector<double> bpar_struct;   
     std::vector<int> bpar_struct_var_type_list;  // The types to the variable at each element in bpar_struct
@@ -37,7 +42,11 @@ struct gru_state {
     std::vector<int> i_look_var_type_list; // The types to the variable at each element in bvar_struct
 };
 
-behavior gru_actor(stateful_actor<gru_state>* self, int refGRU, int indxGRU,
-    std::string configPath,
-    int outputStrucSize, caf::actor parent);
+behavior gru_actor(stateful_actor<gru_state>* self, 
+    int ref_gru, 
+    int indx_gru, 
+    std::string config_path, 
+    caf::actor file_access_actor, 
+    int output_struc_size, 
+    caf::actor parent);
 }
\ No newline at end of file
diff --git a/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp b/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp
index a078d41..49114c5 100644
--- a/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp
+++ b/build/includes/gru_actor/gru_actor_subroutine_wrappers.hpp
@@ -9,4 +9,6 @@ extern "C" {
     void fillVarTypeLists( int* num_bpar_vars, int* num_bvar_vars,
         void* bpar_struct_var_type_list, void* bvar_struct_var_type_list, int* err);
 
+    int getNumHRU(int* indx_gru);
+
 }
\ No newline at end of file
diff --git a/build/makefile b/build/makefile
index e2c5668..652faa7 100644
--- a/build/makefile
+++ b/build/makefile
@@ -338,7 +338,7 @@ compile_globals:
 	$(CC) $(FLAGS_ACTORS) -c $(GLOBAL) $(TIMEINFO) $(GLOBAL_INCLUDES)
 
 compile_gru_actor:
-	$(CC) $(FLAGS_ACTORS) -c $(GRU_ACTOR) $(GRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES)
+	$(CC) $(FLAGS_ACTORS) -c $(GRU_ACTOR) $(HRU_ACTOR_INCLUDES) $(GRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES)
 
 compile_hru_actor:
 	$(CC) $(FLAGS_ACTORS) -c $(HRU_ACTOR) $(HRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES)
diff --git a/build/source/actors/gru_actor/gru_actor.cpp b/build/source/actors/gru_actor/gru_actor.cpp
index d715db2..ef0e1ca 100644
--- a/build/source/actors/gru_actor/gru_actor.cpp
+++ b/build/source/actors/gru_actor/gru_actor.cpp
@@ -1,20 +1,64 @@
 #include "caf/all.hpp"
 #include "gru_actor.hpp"
 #include "global.hpp"
+#include "hru_actor.hpp"
 #include "message_atoms.hpp"
 #include <vector>
 #include "gru_actor_subroutine_wrappers.hpp"
 
 namespace caf {
 
-behavior gru_actor(stateful_actor<gru_state>* self, int refGRU, int indxGRU, 
-    std::string configPath, int outputStrucSize, caf::actor parent) {
+behavior gru_actor(stateful_actor<gru_state>* self, 
+    int ref_gru, int indx_gru, 
+    std::string config_path, caf::actor file_access_actor, int output_struc_size, 
+    caf::actor parent) {
 
     aout(self) << "GRU Actor Has Started\n";
     self->state.parent = parent;
+    self->state.ref_gru = ref_gru;
+    self->state.indx_gru = indx_gru;
+    self->state.config_path = config_path;
+    self->state.file_access_actor = file_access_actor;
+    self->state.output_struc_size = output_struc_size;
+    self->state.parent = parent;
+
+    self->state.num_hrus = getNumHRU(&self->state.indx_gru);
+
+    self->send(self, init_hru_v);
 
     return {
 
+        [=](init_hru) {
+            for (int i = 0; i < self->state.num_hrus; i++) {
+                auto hru = self->spawn(hru_actor,
+                        self->state.ref_gru, self->state.indx_gru, 
+                        self->state.config_path, self->state.file_access_actor,
+                        self->state.output_struc_size,
+                        self);
+                self->state.hru_list.push_back(hru);
+            }
+        },
+
+        [=](done_hru, int indx_gru, double total_duration, double init_duration, 
+            double forcing_duration, double run_physics_duration, double write_output_duration) {
+            aout(self) << "GRU Received HRU is Done\n";
+
+            self->state.hrus_complete++;
+            if (self->state.hrus_complete >= self->state.num_hrus) {
+                aout(self) << "All HRUs have finished";
+
+                self->send(self->state.parent,
+                    done_hru_v,
+                    indx_gru, 
+                    total_duration,
+                    init_duration, 
+                    forcing_duration,
+                    run_physics_duration,
+                    write_output_duration);
+            }
+        
+        },
+
         // What does a GRU need to assemble its data structure?
         [=](init_gru) {
             // Get the variable data length, we also need the type information
diff --git a/build/source/actors/gru_actor/gru_actor.f90 b/build/source/actors/gru_actor/gru_actor.f90
index ae867c1..e2f2a2f 100644
--- a/build/source/actors/gru_actor/gru_actor.f90
+++ b/build/source/actors/gru_actor/gru_actor.f90
@@ -9,6 +9,7 @@ implicit none
 ! public::run_gru
 public::getVarSizes
 public::fillvarTypeLists
+public::getNumHRU
 
 contains
 
@@ -196,7 +197,17 @@ end subroutine fillVarTypeLists
 
 ! end subroutine
 
+integer function getNumHRU(indx_gru) bind(C, name="getNumHRU")
+    USE globalData,only:gru_struc
+    implicit none
+    integer(c_int), intent(in)        :: indx_gru
+    integer(c_int)                    :: num_hru
+
+    num_hru = gru_struc(indx_gru)%hruCount
+
+    getNumHRU = num_hru
 
+end function
 
 
 end module gru_actor
diff --git a/build/source/actors/hru_actor/hru_actor.cpp b/build/source/actors/hru_actor/hru_actor.cpp
index 5ffd04c..2258720 100644
--- a/build/source/actors/hru_actor/hru_actor.cpp
+++ b/build/source/actors/hru_actor/hru_actor.cpp
@@ -56,7 +56,7 @@ behavior hru_actor(stateful_actor<hru_state>* self, int refGRU, int indxGRU,
 
     Initialize_HRU(self);
     self->state.hru_timing.updateEndPoint("total_duration");
-    self->send(self->state.parent, done_init_hru_v);
+    self->send(self, start_hru_v);
 
     return {
         // Starts the HRU and tells it to ask for data from the file_access_actor
diff --git a/build/source/actors/job_actor/job_actor.cpp b/build/source/actors/job_actor/job_actor.cpp
index b87a79d..57c7dff 100644
--- a/build/source/actors/job_actor/job_actor.cpp
+++ b/build/source/actors/job_actor/job_actor.cpp
@@ -257,9 +257,13 @@ void initalizeGRU(stateful_actor<job_state>* self) {
     for(int i = 0; i < self->state.num_gru; i++) {
         int start_gru = self->state.gru_list.size() + self->state.start_gru;
         int index_gru = self->state.gru_list.size() + 1; // Fortran reference starts at 1
-        auto gru = self->spawn(hru_actor, start_gru, index_gru, 
-            self->state.config_path, self->state.file_access_actor, 
-            self->state.output_struct_size, self);
+        auto gru = self->spawn(gru_actor, 
+                               start_gru, 
+                               index_gru, 
+                               self->state.config_path, 
+                               self->state.file_access_actor, 
+                               self->state.output_struct_size, 
+                               self);
         self->state.gru_list.push_back(new GRUinfo(start_gru, index_gru, gru, 
             self->state.dt_init_start_factor, self->state.max_run_attempts));
     }
-- 
GitLab