From 1db7e1d392a47f24e13c45fd889d7753c255a732 Mon Sep 17 00:00:00 2001 From: Kyle Klenk <kyle.c.klenk@gmail.com> Date: Wed, 24 Apr 2024 21:56:44 +0000 Subject: [PATCH] Got forcing file access under a single class within the file_access_actor --- build/CMakeLists.txt | 6 +- .../file_access_actor => }/ffile_info.f90 | 0 .../file_access_init.cpp | 0 .../file_access_utils.cpp | 0 .../file_access_actor/forcing_file_info.hpp | 10 +- build/includes/global/fileManager.hpp | 4 +- build/includes/summa_actor/summa_actor.hpp | 47 +----- .../summa_actor/summa_global_data.hpp | 17 +++ build/read_force.f90 | 27 ++++ .../file_access_actor/file_access_actor.cpp | 70 +-------- .../file_access_actor/file_access_actor.f90 | 81 +--------- .../file_access_actor/forcing_file_info.cpp | 25 +++- .../{read_force.f90 => forcing_file_info.f90} | 141 ++++++++++++++---- build/source/global/fileManager.cpp | 4 +- build/source/hru_actor/hru_read.f90 | 10 +- build/source/job_actor/job_actor.f90 | 29 ---- .../batch_distributer_actor.f90 | 8 +- .../fortran_global_state_actor.cpp | 78 ---------- .../system_initialization/summa_actor.cpp | 38 +++-- .../summa_global_data.cpp | 33 ++++ 20 files changed, 261 insertions(+), 367 deletions(-) rename build/{source/file_access_actor => }/ffile_info.f90 (100%) rename build/{source/file_access_actor => }/file_access_init.cpp (100%) rename build/{source/file_access_actor => }/file_access_utils.cpp (100%) create mode 100644 build/includes/summa_actor/summa_global_data.hpp create mode 100644 build/read_force.f90 rename build/source/file_access_actor/{read_force.f90 => forcing_file_info.f90} (68%) delete mode 100644 build/source/system_initialization/fortran_global_state_actor.cpp create mode 100644 build/source/system_initialization/summa_global_data.cpp diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 159d54c..14f9452 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -203,9 +203,10 @@ set(INTERFACE set(SYS_INIT_INTERFACE ${SYS_INIT_DIR}/batch_distributer_actor.f90) set(FILE_ACCESS_INTERFACE + ${FILE_ACCESS_DIR}/forcing_file_info.f90 ${FILE_ACCESS_DIR}/file_access_actor.f90 ${FILE_ACCESS_DIR}/output_structure.f90 - ${FILE_ACCESS_DIR}/read_force.f90 + # ${FILE_ACCESS_DIR}/read_force.f90 ${FILE_ACCESS_DIR}/fileAccess_writeOutput.f90) set(JOB_INTERFACE ${JOB_ACTOR_DIR}/job_actor.f90) @@ -229,7 +230,7 @@ set(SYS_INIT ${SYS_INIT_DIR}/batch_container.cpp ${SYS_INIT_DIR}/client.cpp ${SYS_INIT_DIR}/client_container.cpp - ${SYS_INIT_DIR}/fortran_global_state_actor.cpp + ${SYS_INIT_DIR}/summa_global_data.cpp ${SYS_INIT_DIR}/summa_actor.cpp ${SYS_INIT_DIR}/summa_backup_server.cpp ${SYS_INIT_DIR}/summa_client.cpp @@ -237,7 +238,6 @@ set(SYS_INIT set(FILE_ACCESS_ACTOR # ${ACTORS_DIR}/file_access_actor/file_access_utils.cpp ${ACTORS_DIR}/file_access_actor/file_access_actor.cpp - ${ACTORS_DIR}/file_access_actor/file_access_init.cpp ${ACTORS_DIR}/file_access_actor/forcing_file_info.cpp ${ACTORS_DIR}/file_access_actor/output_container.cpp) set(JOB_ACTOR diff --git a/build/source/file_access_actor/ffile_info.f90 b/build/ffile_info.f90 similarity index 100% rename from build/source/file_access_actor/ffile_info.f90 rename to build/ffile_info.f90 diff --git a/build/source/file_access_actor/file_access_init.cpp b/build/file_access_init.cpp similarity index 100% rename from build/source/file_access_actor/file_access_init.cpp rename to build/file_access_init.cpp diff --git a/build/source/file_access_actor/file_access_utils.cpp b/build/file_access_utils.cpp similarity index 100% rename from build/source/file_access_actor/file_access_utils.cpp rename to build/file_access_utils.cpp diff --git a/build/includes/file_access_actor/forcing_file_info.hpp b/build/includes/file_access_actor/forcing_file_info.hpp index bf8d751..8043ad8 100644 --- a/build/includes/file_access_actor/forcing_file_info.hpp +++ b/build/includes/file_access_actor/forcing_file_info.hpp @@ -5,8 +5,10 @@ #include <iostream> extern "C" { + // Create the fortran ffile_info and return the number of forcing_files + void ffile_info_fortran(int& num_grus, int& num_forcing_files, int& err, + void* message); // Creation and population of Fortran structures - void getNumForcingFiles_fortran(int* num_files); void getFileInfoSizes_fortran(int& iFile, int& var_ix_size, int& data_id_size, int& varName_size); void getFileInfoCopy_fortran(int& iFile, void* file_name, int& nVars, @@ -18,7 +20,7 @@ extern "C" { void read_forcingFile(int& iFile, int& start_gru, int& num_gru, int& err, void* message); - // Deallocate Fortran Structures + // Deallocate Fortran Structures associate with forcing files void freeForcingFiles_fortran(); } @@ -51,6 +53,8 @@ class forcingFileContainer { forcingFileContainer(); ~forcingFileContainer(); + int initForcingFiles(int num_gru); + int loadForcingFile(int file_ID, int start_gru, int num_gru); bool isFileLoaded(int file_ID); inline bool allFilesLoaded() { @@ -59,7 +63,7 @@ class forcingFileContainer { inline int getNumSteps(int iFile) {return forcing_files_[iFile-1].nTimeSteps;} private: - int files_loaded_; + int files_loaded_ = 0; }; diff --git a/build/includes/global/fileManager.hpp b/build/includes/global/fileManager.hpp index 2ae9faa..4b26ab0 100644 --- a/build/includes/global/fileManager.hpp +++ b/build/includes/global/fileManager.hpp @@ -1,7 +1,7 @@ #include <string> extern "C" { - void initFileManagerModule_fortran(char const* file_manager_path, + void setTimesDirsAndFiles_fortran(char const* file_manager_path, int* err, void* err_msg); } @@ -39,6 +39,6 @@ class fileManager { ~fileManager() {}; // Set the variables that are used by the summaFileManager (summaFileManager.f90) - std::string initFileManagerModule(); + std::string setTimesDirsAndFiles(); std::string toString(); }; \ No newline at end of file diff --git a/build/includes/summa_actor/summa_actor.hpp b/build/includes/summa_actor/summa_actor.hpp index b005923..4d14e11 100644 --- a/build/includes/summa_actor/summa_actor.hpp +++ b/build/includes/summa_actor/summa_actor.hpp @@ -11,50 +11,20 @@ #include <string> #include <vector> #include "message_atoms.hpp" - -extern "C" { - void defineGlobalData_fortran(int* err, void* err_msg); - - void deallocateGlobalData_fortran(int* err, void* err_msg); -} - -// This is a class that wraps around the data created in -// defineGlobalData() -class summaGlobalData { - public: - summaGlobalData(); - ~summaGlobalData(); - - int defineGlobalData(); - private: - bool global_data_ready; -}; +#include "summa_global_data.hpp" namespace caf { - - -struct job_timing_info { - std::vector<double> job_duration; - std::vector<double> job_read_duration; - std::vector<double> job_write_duration; -}; - struct summa_actor_state { - // Timing Information For Summa-Actor TimingInfo summa_actor_timing; - struct job_timing_info timing_info_for_jobs; - - // Program Parameters - int startGRU; // starting GRU for the simulation - int numGRU; // number of GRUs to compute - int fileGRU; // number of GRUs in the file - std::string configPath; // path to the fileManager.txt file - int numFailed = 0; // Number of jobs that have failed - caf::actor currentJob; // Reference to the current job actor + + int start_gru; // starting GRU for the simulation + int num_gru; // number of GRUs to compute + int file_gru; // number of GRUs in the file + int num_gru_failed = 0; // Number of GRUs that have failed + caf::actor current_job; // Reference to the current job actor caf::actor parent; - // Batches Batch_Container batch_container; int current_batch_id; @@ -77,9 +47,6 @@ behavior summa_actor(stateful_actor<summa_actor_state>* self, Job_Actor_Settings job_actor_settings, HRU_Actor_Settings hru_actor_settings, actor parent); -behavior fortran_global_state_actor(event_based_actor* self, actor parent); - - void spawnJob(stateful_actor<summa_actor_state>* self); } // namespace caf diff --git a/build/includes/summa_actor/summa_global_data.hpp b/build/includes/summa_actor/summa_global_data.hpp new file mode 100644 index 0000000..a99ddeb --- /dev/null +++ b/build/includes/summa_actor/summa_global_data.hpp @@ -0,0 +1,17 @@ +extern "C" { + void defineGlobalData_fortran(int* err, void* err_msg); + + void deallocateGlobalData_fortran(int* err, void* err_msg); +} + +// This is a class that wraps around the data created in +// defineGlobalData() +class summaGlobalData { + public: + summaGlobalData(); + ~summaGlobalData(); + + int defineGlobalData(); + private: + bool global_data_ready; +}; diff --git a/build/read_force.f90 b/build/read_force.f90 new file mode 100644 index 0000000..7b5864d --- /dev/null +++ b/build/read_force.f90 @@ -0,0 +1,27 @@ + +! This module contains all the functions that are used to +! access the forcing file and setup the forcing data +! for the HRUs to read from +module access_forcing_module + +USE, intrinsic :: iso_c_binding +USE nrtype + +USE data_types,only:ilength ! global data structure for forcing data +USE actor_data_types,only:file_info_array + +USE globalData,only:time_meta,forc_meta ! metadata structures + + + +implicit none +private +public::read_forcingFile + + +contains + + + + +end module access_forcing_module \ No newline at end of file diff --git a/build/source/file_access_actor/file_access_actor.cpp b/build/source/file_access_actor/file_access_actor.cpp index e086587..656ebf9 100644 --- a/build/source/file_access_actor/file_access_actor.cpp +++ b/build/source/file_access_actor/file_access_actor.cpp @@ -35,11 +35,16 @@ behavior file_access_actor( return { [=](init_file_access_actor, int file_gru) { + aout(self) << "File Access Actor: Intializing\n"; auto& fa_settings = self->state.file_access_actor_settings; int num_hru = self->state.num_gru; int err = 0; - aout(self) << "File Access Actor: Intializing\n"; + // Call ffile_info + self->state.forcing_files = std::make_unique<forcingFileContainer>(); + err = self->state.forcing_files->initForcingFiles(self->state.num_gru); + if (err != 0) return -1; + fileAccessActor_init_fortran( &self->state.num_steps, &fa_settings.num_timesteps_in_output_buffer, @@ -50,8 +55,6 @@ behavior file_access_actor( &err); if (err != 0) return -1; - // Forcing File Info - self->state.forcing_files = std::make_unique<forcingFileContainer>(); // Ensure output buffer size is less than the number of simulation timesteps if (self->state.num_steps < fa_settings.num_timesteps_in_output_buffer) { @@ -101,49 +104,18 @@ behavior file_access_actor( auto err = self->state.forcing_files->loadForcingFile(iFile, self->state.start_gru, self->state.num_gru); self->state.file_access_timing.updateEndPoint("read_duration"); - if (err != 0) { aout(self) << "ERROR: Reading Forcing" << std::endl; self->quit(); return; } - if (!self->state.forcing_files->allFilesLoaded()) { self->send(self, access_forcing_internal_v, iFile + 1); } - + self->send(refToRespondTo, new_forcing_file_v, self->state.forcing_files->getNumSteps(iFile), iFile); - - // if (currentFile <= self->state.numFiles) { - // // Note: C++ starts at 0 and Fortran starts at 1 - // if(!self->state.forcing_file_list[currentFile - 1].isFileLoaded()) { - // self->state.file_access_timing.updateStartPoint("read_duration"); - // int err = 0; - // // read_forcingFile(self->state.handle_forcing_file_info, ¤tFile, - // // &self->state.stepsInCurrentFile, &self->state.start_gru, - // // &self->state.num_gru, &err); - // // if (err != 0) { - // // aout(self) << "ERROR: Reading Forcing" << std::endl; - // // } - // self->state.filesLoaded += 1; - // self->state.forcing_file_list[currentFile - 1] - // .updateNumSteps(self->state.stepsInCurrentFile); - - // self->state.file_access_timing.updateEndPoint("read_duration"); - // // Check if all files have been loaded - // if(self->state.filesLoaded <= self->state.numFiles) { - // self->send(self, access_forcing_internal_v, currentFile + 1); - // } - // } - - // self->send(refToRespondTo, new_forcing_file_v, - // self->state.forcing_file_list[currentFile - 1].getNumSteps(), - // currentFile); - // } else { - // aout(self) << currentFile << " exceeds the number of forcing files\n"; - // } }, [=](access_forcing_internal, int iFile) { @@ -163,34 +135,6 @@ behavior file_access_actor( return; } self->send(self, access_forcing_internal_v, iFile + 1); - - - - // if (self->state.filesLoaded <= self->state.numFiles && - // currentFile <= self->state.numFiles) { - - // if (self->state.forcing_file_list[currentFile - 1].isFileLoaded()) { - // aout(self) << "Unexpected File Loaded!!\n"; - // } - - // self->state.file_access_timing.updateStartPoint("read_duration"); - // int err = 0; - // // read_forcingFile(self->state.handle_forcing_file_info, ¤tFile, - // // &self->state.stepsInCurrentFile, &self->state.start_gru, - // // &self->state.num_gru, &err); - // // if (err != 0) { - // // aout(self) << "ERROR: Reading Forcing" << std::endl; - // // } - - // self->state.filesLoaded += 1; - // self->state.forcing_file_list[currentFile - 1] - // .updateNumSteps(self->state.stepsInCurrentFile); - - // self->state.file_access_timing.updateEndPoint("read_duration"); - // self->send(self, access_forcing_internal_v, currentFile + 1); - // } else { - // aout(self) << "All Forcing Files Loaded \n"; - // } }, // Number of steps an HRU can compute before needing to write diff --git a/build/source/file_access_actor/file_access_actor.f90 b/build/source/file_access_actor/file_access_actor.f90 index 112a701..ab9c818 100644 --- a/build/source/file_access_actor/file_access_actor.f90 +++ b/build/source/file_access_actor/file_access_actor.f90 @@ -27,17 +27,13 @@ module file_access_actor ! Call the fortran routines that read data in and are associtated with the forcing structure subroutine fileAccessActor_init_fortran(& ! Variables for forcing - ! handle_forcFileInfo,& - ! num_forcing_files,& num_timesteps,& num_timesteps_output_buffer,& - ! Variables for output handle_output_ncid,& start_gru,& num_gru,& num_hru,& err) bind(C, name="fileAccessActor_init_fortran") - USE ffile_info_module,only:ffile_info ! module to read information on forcing datafile USE mDecisions_module,only:mDecisions ! module to read model decisions USE read_pinit_module,only:read_pinit ! module to read initial model parameter values USE module_sf_noahmplsm,only:read_mp_veg_parameters ! module to read NOAH vegetation tables @@ -95,8 +91,6 @@ subroutine fileAccessActor_init_fortran(& ! Variables for forcing implicit none - ! type(c_ptr), intent(in), value :: handle_forcFileInfo - ! integer(c_int),intent(out) :: num_forcing_files integer(c_int),intent(out) :: num_timesteps integer(c_int),intent(in) :: num_timesteps_output_buffer type(c_ptr),intent(in), value :: handle_output_ncid @@ -122,17 +116,8 @@ subroutine fileAccessActor_init_fortran(& ! Variables for forcing err=0; message="fileAccessActor_init_fortran/" - ! call c_f_pointer(handle_forcFileInfo, forcFileInfo) call c_f_pointer(handle_output_ncid, output_ncid) - ! ***************************************************************************** - ! *** read description of model forcing datafile used in each HRU - ! ***************************************************************************** - ! call ffile_info(num_gru, forcFileInfo, num_forcing_files, err, message) - call ffile_info(num_gru, err, message) - - if(err/=0)then; print*, trim(message); return; endif - ! ***************************************************************************** ! *** read model decisions ! ***************************************************************************** @@ -379,67 +364,9 @@ else if(err/=0)then; print*, message; return; endif end subroutine fileAccessActor_init_fortran -! TODO: Can be a function -subroutine getNumForcingFiles_fortran(num_forc_files) bind(C, name="getNumForcingFiles_fortran") - USE globalData,only:forcFileInfo - implicit none - integer(c_int),intent(out) :: num_forc_files - num_forc_files = size(forcFileInfo) -end subroutine getNumForcingFiles_fortran - -! Get the sizes fo the vector components that make up a forcingFile -subroutine getFileInfoSizes_fortran(iFile, var_ix_size, data_id_size, & - varName_size) bind(C, name="getFileInfoSizes_fortran") - USE globalData,only:forcFileInfo - implicit none - integer(c_int),intent(in) :: iFile - integer(c_int),intent(out) :: var_ix_size - integer(c_int),intent(out) :: data_id_size - integer(c_int),intent(out) :: varName_size - var_ix_size = size(forcFileInfo(iFile)%var_ix) - data_id_size = size(forcFileInfo(iFile)%data_id) - varName_size = size(forcFileInfo(iFile)%varName) -end subroutine - -! Get the file info for a specific file -subroutine getFileInfoCopy_fortran(iFile, filenmData, nVars, nTimeSteps, & - varName_size, var_ix_size, data_id_size, var_name_arr, var_ix_arr, & - data_id_arr, firstJulDay, convTime2Days) bind(C, name="getFileInfoCopy_fortran") - USE globalData,only:forcFileInfo - USE C_interface_module - implicit none - ! dummy variables - integer(c_int),intent(in) :: iFile - type(c_ptr),intent(out) :: filenmData - integer(c_int),intent(out) :: nVars - integer(c_int),intent(out) :: nTimeSteps - integer(c_int),intent(in) :: varName_size - integer(c_int),intent(in) :: var_ix_size - integer(c_int),intent(in) :: data_id_size - type(c_ptr),intent(out) :: var_name_arr(varName_size) - integer(c_int),intent(out) :: var_ix_arr(var_ix_size) - integer(c_int),intent(out) :: data_id_arr(data_id_size) - real(c_double),intent(out) :: firstJulDay - real(c_double),intent(out) :: convTime2Days - ! local variables - integer(i4b) :: i - - call f_c_string_ptr(trim(forcFileInfo(iFile)%filenmData), filenmData) - - nVars = forcFileInfo(iFile)%nVars - nTimeSteps = forcFileInfo(iFile)%nTimeSteps - - do i=1, varName_size - call f_c_string_ptr(trim(forcFileInfo(iFile)%varName(i)), var_name_arr(i)) - end do - var_ix_arr(:) = forcFileInfo(iFile)%var_ix(:) - data_id_arr(:) = forcFileInfo(iFile)%data_id(:) - firstJulDay = forcFileInfo(iFile)%firstJulDay - convTime2Days = forcFileInfo(iFile)%convTime2Days -end subroutine getFileInfoCopy_fortran subroutine defOutputFortran(handle_output_ncid, start_gru, num_gru, num_hru, & file_gru, use_extention, file_extention_c, err) bind(C, name="defOutputFortran") @@ -513,17 +440,11 @@ subroutine defOutputFortran(handle_output_ncid, start_gru, num_gru, num_hru, & end subroutine defOutputFortran -subroutine freeForcingFiles_fortran() bind(C, name="freeForcingFiles_fortran") - USE globalData,only:forcFileInfo - implicit none - if (allocated(forcFileInfo)) deallocate(forcFileInfo) -end subroutine freeForcingFiles_fortran + subroutine FileAccessActor_DeallocateStructures(handle_ncid) bind(C,name="FileAccessActor_DeallocateStructures") USE netcdf_util_module,only:nc_file_close USE globalData,only:structInfo ! information on the data structures - USE access_forcing_module,only:forcingDataStruct - USE access_forcing_module,only:vectime USE output_structure_module,only:outputTimeStep USE output_structure_module,only:outputStructure USE var_lookup,only:maxvarFreq ! maximum number of output files diff --git a/build/source/file_access_actor/forcing_file_info.cpp b/build/source/file_access_actor/forcing_file_info.cpp index 78d530b..c2e0d39 100644 --- a/build/source/file_access_actor/forcing_file_info.cpp +++ b/build/source/file_access_actor/forcing_file_info.cpp @@ -15,10 +15,25 @@ fileInfo::fileInfo() { forcingFileContainer::forcingFileContainer() { forcing_files_ = std::vector<fileInfo>(); +} + +forcingFileContainer::~forcingFileContainer() { + freeForcingFiles_fortran(); +} + +int forcingFileContainer::initForcingFiles(int num_gru) { + int num_files, err; + + // initalize the fortran side + std::unique_ptr<char[]> message(new char[256]); + ffile_info_fortran(num_gru, num_files, err, &message); + if (err != 0) { + std::cout << "Error initializing forcing files: " << message.get() << "\n"; + return -1; + } - int num_files; - getNumForcingFiles_fortran(&num_files); forcing_files_.resize(num_files); + for (int i = 1; i < num_files+1; i++) { int var_ix_size = 0; int data_id_size = 0; @@ -41,18 +56,14 @@ forcingFileContainer::forcingFileContainer() { forcing_files_[i-1].data_id.data(), forcing_files_[i-1].firstJulDay, forcing_files_[i-1].convTime2Days); - forcing_files_[i-1].filenmData = std::string(file_name.get()); forcing_files_[i-1].nVars = varName_size; for (int j = 0; j < varName_size; j++) { forcing_files_[i-1].varName[j] = std::string(var_name_arr[j].get()); } } -} - -forcingFileContainer::~forcingFileContainer() { - freeForcingFiles_fortran(); + return 0; } diff --git a/build/source/file_access_actor/read_force.f90 b/build/source/file_access_actor/forcing_file_info.f90 similarity index 68% rename from build/source/file_access_actor/read_force.f90 rename to build/source/file_access_actor/forcing_file_info.f90 index e080e77..ab80eb7 100644 --- a/build/source/file_access_actor/read_force.f90 +++ b/build/source/file_access_actor/forcing_file_info.f90 @@ -1,41 +1,114 @@ +module forcing_file_info + USE, intrinsic :: iso_c_binding + USE nrtype + USE globalData,only:integerMissing ! integer missing value + USE actor_data_types,only:var_forc ! global data structure for forcing data + USE data_types,only:dlength ! global data structure for forcing data + implicit none + public::ffile_info_fortran + public::getFileInfoSizes_fortran + public::getFileInfoCopy_fortran + public::read_forcingFile + public::openForcingFile + public::freeForcingFiles_fortran -! This module contains all the functions that are used to -! access the forcing file and setup the forcing data -! for the HRUs to read from -module access_forcing_module + ! Module Data Structures (global to hrus that import this module) + type(var_forc),allocatable,save,public :: forcingDataStruct(:) ! forcingDataStruct(:)%var(:)%dataFromFile(:,:) + type(dlength),allocatable,save,public :: vecTime(:) + contains +! Initalize the fortran data structure and return the number of forcing files +subroutine ffile_info_fortran(num_gru, num_forcing_files, err, message_r) & + bind(C, name="ffile_info_fortran") + USE ffile_info_module,only:ffile_info ! module to read information on forcing datafile + USE globalData,only:forcFileInfo ! Structure allocated by ffil info + USE C_interface_module,only:f_c_string_ptr ! convert fortran string to c string + implicit none + ! dummy variables + integer(c_int), intent(in) :: num_gru + integer(c_int), intent(out) :: num_forcing_files + integer(c_int), intent(out) :: err + type(c_ptr), intent(out) :: message_r + ! local variables + character(len=256) :: message="" + + call f_c_string_ptr(message, message_r) -USE, intrinsic :: iso_c_binding -USE nrtype + ! ***************************************************************************** + ! *** read description of model forcing datafile used in each HRU + ! ***************************************************************************** + call ffile_info(num_gru, err, message) + if(err/=0)then; call f_c_string_ptr(trim(message), message_r); return; endif -USE data_types,only:file_info -USE data_types,only:dlength ! global data structure for forcing data -USE data_types,only:ilength ! global data structure for forcing data -USE actor_data_types,only:file_info_array -USE actor_data_types,only:var_forc ! global data structure for forcing data -USE globalData,only:forcFileInfo ! forcing file info + num_forcing_files = size(forcFileInfo) +end subroutine ffile_info_fortran -USE globalData,only:gru_struc -USE globalData,only:time_meta,forc_meta ! metadata structures -USE globalData,only:integerMissing ! integer missing value -USE var_lookup,only:iLookTIME,iLookFORCE ! named variables to define structure elements -USE summaFileManager,only:FORCING_PATH ! path of the forcing data file -USE netcdf_util_module,only:nc_file_close ! close netcdf file +! Get the sizes fo the vector components that make up a forcingFile +subroutine getFileInfoSizes_fortran(iFile, var_ix_size, data_id_size, & + varName_size) bind(C, name="getFileInfoSizes_fortran") + USE globalData,only:forcFileInfo + implicit none + integer(c_int),intent(in) :: iFile + integer(c_int),intent(out) :: var_ix_size + integer(c_int),intent(out) :: data_id_size + integer(c_int),intent(out) :: varName_size + var_ix_size = size(forcFileInfo(iFile)%var_ix) + data_id_size = size(forcFileInfo(iFile)%data_id) + varName_size = size(forcFileInfo(iFile)%varName) +end subroutine getFileInfoSizes_fortran +! Get the file info for a specific file +subroutine getFileInfoCopy_fortran(iFile, filenmData, nVars, nTimeSteps, & + varName_size, var_ix_size, data_id_size, var_name_arr, var_ix_arr, & + data_id_arr, firstJulDay, convTime2Days) bind(C, name="getFileInfoCopy_fortran") + USE globalData,only:forcFileInfo + USE C_interface_module + implicit none + ! dummy variables + integer(c_int),intent(in) :: iFile + type(c_ptr),intent(out) :: filenmData + integer(c_int),intent(out) :: nVars + integer(c_int),intent(out) :: nTimeSteps + integer(c_int),intent(in) :: varName_size + integer(c_int),intent(in) :: var_ix_size + integer(c_int),intent(in) :: data_id_size + type(c_ptr),intent(out) :: var_name_arr(varName_size) + integer(c_int),intent(out) :: var_ix_arr(var_ix_size) + integer(c_int),intent(out) :: data_id_arr(data_id_size) + real(c_double),intent(out) :: firstJulDay + real(c_double),intent(out) :: convTime2Days + ! local variables + integer(i4b) :: i + + call f_c_string_ptr(trim(forcFileInfo(iFile)%filenmData), filenmData) + nVars = forcFileInfo(iFile)%nVars + nTimeSteps = forcFileInfo(iFile)%nTimeSteps + + do i=1, varName_size + call f_c_string_ptr(trim(forcFileInfo(iFile)%varName(i)), var_name_arr(i)) + end do + + var_ix_arr(:) = forcFileInfo(iFile)%var_ix(:) + data_id_arr(:) = forcFileInfo(iFile)%data_id(:) -implicit none -private -public::read_forcingFile + firstJulDay = forcFileInfo(iFile)%firstJulDay + convTime2Days = forcFileInfo(iFile)%convTime2Days -type(var_forc),allocatable,save,public :: forcingDataStruct(:) ! forcingDataStruct(:)%var(:)%dataFromFile(:,:) -type(dlength),allocatable,save,public :: vecTime(:) +end subroutine getFileInfoCopy_fortran -contains +! Read an entire forcing file into the global structures defined in this module subroutine read_forcingFile(iFile, startGRU, numGRU, err, message_r) & bind(C,name="read_forcingFile") USE netcdf USE netcdf_util_module,only:nc_file_open - USE C_interface_module,only:f_c_string_ptr + USE netcdf_util_module,only:nc_file_close ! close netcdf file + USE C_interface_module,only:f_c_string_ptr + USE globalData,only:forcFileInfo + USE globalData,only:gru_struc + USE globalData,only:forc_meta + USE var_lookup,only:iLookTIME,iLookFORCE ! named variables to define structure elements + USE summaFileManager,only:FORCING_PATH ! path of the forcing data file + implicit none integer(c_int),intent(in) :: iFile integer(c_int),intent(in) :: startGRU @@ -136,9 +209,7 @@ subroutine read_forcingFile(iFile, startGRU, numGRU, err, message_r) & end do call nc_file_close(ncid,err,message) - if(err/=0)then;message=trim(message)//trim(cmessage);call f_c_string_ptr(message,message_r);return;end if - - + if(err/=0)then;message=trim(message)//trim(cmessage);call f_c_string_ptr(message,message_r);return;end if end subroutine read_forcingFile ! ************************************************************************* @@ -147,10 +218,10 @@ end subroutine read_forcingFile subroutine openForcingFile(forc_file,iFile,infile,ncId,err,message) USE netcdf ! netcdf capability USE netcdf_util_module,only:nc_file_open ! open netcdf file + USE data_types,only:file_info USE time_utils_module,only:fracDay ! compute fractional day USE time_utils_module,only:extractTime ! extract time info from units string USE time_utils_module,only:compJulDay ! convert calendar date to julian day - !USE globalData,only:tmZoneOffsetFracDay ! time zone offset in fractional days USE globalData,only:ncTime ! time zone information from NetCDF file (timeOffset = longitude/15. - ncTimeOffset) USE globalData,only:utcTime ! all times in UTC (timeOffset = longitude/15. hours) USE globalData,only:localTime ! all times local (timeOffset = 0) @@ -223,6 +294,14 @@ subroutine openForcingFile(forc_file,iFile,infile,ncId,err,message) case default; message=trim(message)//'unable to identify time units'; err=20; return end select - end subroutine openForcingFile +end subroutine openForcingFile + +subroutine freeForcingFiles_fortran() bind(C, name="freeForcingFiles_fortran") + USE globalData,only:forcFileInfo + implicit none + if (allocated(forcFileInfo)) deallocate(forcFileInfo) + if (allocated(forcingDataStruct)) deallocate(forcingDataStruct) + if (allocated(vecTime)) deallocate(vecTime) +end subroutine freeForcingFiles_fortran -end module access_forcing_module \ No newline at end of file +end module forcing_file_info diff --git a/build/source/global/fileManager.cpp b/build/source/global/fileManager.cpp index d62efaa..06ba4e5 100644 --- a/build/source/global/fileManager.cpp +++ b/build/source/global/fileManager.cpp @@ -76,11 +76,11 @@ fileManager::fileManager(const std::string& file_manager_path) { } -std::string fileManager::initFileManagerModule() { +std::string fileManager::setTimesDirsAndFiles() { int err = 0; std::unique_ptr<char[]> err_msg(new char[1024]); // Calls summa_SetTimesDirsAndFiles() - initFileManagerModule_fortran(file_manager_path_.c_str(), &err, &err_msg); + setTimesDirsAndFiles_fortran(file_manager_path_.c_str(), &err, &err_msg); return std::string(err_msg.get()); } diff --git a/build/source/hru_actor/hru_read.f90 b/build/source/hru_actor/hru_read.f90 index 5ebd876..98b03a2 100644 --- a/build/source/hru_actor/hru_read.f90 +++ b/build/source/hru_actor/hru_read.f90 @@ -25,7 +25,7 @@ contains ! set the refTimeString and extract the time to set the tmZonOffsetFracDay subroutine setTimeZoneOffset(iFile, handle_hru_data, err) bind(C, name="setTimeZoneOffset") - USE access_forcing_module,only:forcingDataStruct ! forcing structure + USE forcing_file_info,only:forcingDataStruct ! forcing structure USE time_utils_module,only:extractTime ! extract time info from units string USE time_utils_module,only:fracDay ! compute fractional day USE summafilemanager,only:NC_TIME_ZONE @@ -73,8 +73,8 @@ subroutine HRU_readForcing(indxGRU, iStep, iRead, iFile, handle_hru_data, err) b USE globalData,only:dJulianStart ! julian day of start time of simulation USE globalData,only:refJulDay_data ! reference time for data files (fractional julian days) USE globalData,only:integerMissing ! integer missing value - USE access_forcing_module,only:vecTime - USE access_forcing_module,only:forcingDataStruct + USE forcing_file_info,only:vecTime + USE forcing_file_info,only:forcingDataStruct USE globalData,only:time_meta,forc_meta USE var_lookup,only:iLookTIME,iLookFORCE USE data_types,only:var_i,var_d @@ -235,8 +235,8 @@ end subroutine HRU_readForcing ! Find the first timestep within the forcing file subroutine getFirstTimestep(iFile, iRead, err) - USE access_forcing_module,only:forcingDataStruct ! forcing structure - USE access_forcing_module,only:vecTime ! time structure for forcing + USE forcing_file_info,only:forcingDataStruct ! forcing structure + USE forcing_file_info,only:vecTime ! time structure for forcing USE globalData,only:dJulianStart ! julian day of start time of simulation USE globalData,only:data_step ! length of the data step (s) USE globalData,only:refJulDay_data ! reference time for data files (fractional julian days) diff --git a/build/source/job_actor/job_actor.f90 b/build/source/job_actor/job_actor.f90 index e84cb06..598f1ee 100644 --- a/build/source/job_actor/job_actor.f90 +++ b/build/source/job_actor/job_actor.f90 @@ -117,24 +117,9 @@ end subroutine job_init_fortran subroutine deallocateJobActor(err) bind(C, name="deallocateJobActor") - USE globalData,only:structInfo ! information on the data structures - USE globalData,only:statForc_meta ! child metadata for stats - USE globalData,only:statProg_meta ! child metadata for stats - USE globalData,only:statDiag_meta ! child metadata for stats - USE globalData,only:statFlux_meta ! child metadata for stats - USE globalData,only:statIndx_meta ! child metadata for stats - USE globalData,only:statBvar_meta ! child metadata for stats - USE globalData,only:forcChild_map ! index of the child data structure: stats forc - USE globalData,only:progChild_map ! index of the child data structure: stats prog - USE globalData,only:diagChild_map ! index of the child data structure: stats diag - USE globalData,only:fluxChild_map ! index of the child data structure: stats flux - USE globalData,only:indxChild_map ! index of the child data structure: stats indx - USE globalData,only:bvarChild_map ! index of the child data structure: stats bvar USE globalData,only:gru_struc ! gru->hru mapping structure - USE globalData,only:averageFlux_meta USE globalData,only:index_map USE globalData,only:startTime,finshTime,refTime,oldTime - USE var_lookup,only:childFLUX_MEAN ! look-up values for timestep-average model fluxes implicit none integer(c_int), intent(out) :: err @@ -146,20 +131,6 @@ subroutine deallocateJobActor(err) bind(C, name="deallocateJobActor") deallocate(refTime%var); deallocate(oldTime%var); - if(allocated(averageFlux_meta)) then; deallocate(averageFlux_meta); endif - if(allocated(statForc_meta)) then; deallocate(statForc_meta); endif - if(allocated(statProg_meta)) then; deallocate(statProg_meta); endif - if(allocated(statDiag_meta)) then; deallocate(statDiag_meta); endif - if(allocated(statFlux_meta)) then; deallocate(statFlux_meta); endif - if(allocated(statIndx_meta)) then; deallocate(statIndx_meta); endif - if(allocated(statBvar_meta)) then; deallocate(statBvar_meta); endif - if(allocated(forcChild_map)) then; deallocate(forcChild_map); endif - if(allocated(progChild_map)) then; deallocate(progChild_map); endif - if(allocated(diagChild_map)) then; deallocate(diagChild_map); endif - if(allocated(fluxChild_map)) then; deallocate(fluxChild_map); endif - if(allocated(indxChild_map)) then; deallocate(indxChild_map); endif - if(allocated(bvarChild_map)) then; deallocate(bvarChild_map); endif - if(allocated(childFLUX_MEAN))then; deallocate(childFLUX_MEAN);endif if(allocated(gru_struc))then; deallocate(gru_struc);endif if(allocated(index_map))then; deallocate(index_map);endif end subroutine diff --git a/build/source/system_initialization/batch_distributer_actor.f90 b/build/source/system_initialization/batch_distributer_actor.f90 index 8d82ba9..cb62ad4 100644 --- a/build/source/system_initialization/batch_distributer_actor.f90 +++ b/build/source/system_initialization/batch_distributer_actor.f90 @@ -5,14 +5,14 @@ module batch_distributer USE globalData,only:realMissing ! missing double precision value implicit none - public::initFileManagerModule_fortran + public::SetTimesDirsAndFiles_fortran public::defineGlobalData_fortran public::deallocateGlobalData_fortran contains -subroutine initFileManagerModule_fortran(summaFileManagerIn_C,err,message_r) & - bind(C, name="initFileManagerModule_fortran") +subroutine setTimesDirsAndFiles_fortran(summaFileManagerIn_C,err,message_r) & + bind(C, name="setTimesDirsAndFiles_fortran") USE C_interface_module USE summaFileManager implicit none @@ -32,7 +32,7 @@ subroutine initFileManagerModule_fortran(summaFileManagerIn_C,err,message_r) & ! Initialize the file manager call summa_SetTimesDirsAndFiles(summaFileManagerIn, err, message) if (err /= 0) then; call f_c_string_ptr(trim(message), message_r); return; endif -end subroutine initFileManagerModule_fortran +end subroutine setTimesDirsAndFiles_fortran subroutine defineGlobalData_fortran(err, message_r) bind(C, name="defineGlobalData_fortran") diff --git a/build/source/system_initialization/fortran_global_state_actor.cpp b/build/source/system_initialization/fortran_global_state_actor.cpp deleted file mode 100644 index aa8a72e..0000000 --- a/build/source/system_initialization/fortran_global_state_actor.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "summa_actor.hpp" - - -summaGlobalData::summaGlobalData() { - global_data_ready = false; -} - -summaGlobalData::~summaGlobalData() { - if (global_data_ready) { - std::unique_ptr<char[]> err_msg(new char[1024]); - int err = 0; - deallocateGlobalData_fortran(&err, &err_msg); - if (err != 0) { - std::cout << "\n\nERROR: deallocateGlobalData_fortran() - " - << err_msg.get() << "\n\n"; - } - } -} - -int summaGlobalData::defineGlobalData() { - std::unique_ptr<char[]> err_msg(new char[1024]); - int err = 0; - defineGlobalData_fortran(&err, &err_msg); - if (err != 0) { - std::cout << "\n\nERROR: defineGlobalData_fortran() - " - << err_msg.get() << "\n\n"; - global_data_ready = false; - } else { - global_data_ready = true; - } - return err; -} - - - -// namespace caf { - -// // This actor's lifetime manages the global state of the fortran vars -// // Set by the function summa_defineGlobalData() -// behavior fortran_global_state_actor(event_based_actor* self, actor parent) { -// aout(self) << "Starting Global State Actor\n"; - -// self->attach_functor([=](const error& reason) { -// aout(self) << "Global State Actor Exited\n"; -// std::unique_ptr<char[]> err_msg(new char[1024]); -// int err = 0; -// deallocateGlobalData_fortran(&err, &err_msg); -// if (err != 0) { -// aout(self) << "\n\nERROR: deallocateGlobalData_fortran() - " -// << err_msg.get() << "\n\n"; -// } -// }); - - - - -// self->send(parent, global_data_ready_v); - -// return { -// // Needs a handler to persist, otherwise it gets cleaned up immediately -// [=](define_global_data) { -// std::unique_ptr<char[]> err_msg(new char[1024]); -// int err = 0; -// defineGlobalData_fortran(&err, &err_msg); -// if (err != 0) { -// aout(self) << "\n\nERROR: defineGlobalData_fortran() - " -// << err_msg.get() << "\n\n"; -// self->send(parent, err_v); -// self->quit(); -// return; -// } -// self->send(parent, global_data_ready_v); -// } -// }; -// } - - -// } // namespace caf \ No newline at end of file diff --git a/build/source/system_initialization/summa_actor.cpp b/build/source/system_initialization/summa_actor.cpp index 6e03fc6..2778d91 100644 --- a/build/source/system_initialization/summa_actor.cpp +++ b/build/source/system_initialization/summa_actor.cpp @@ -14,7 +14,7 @@ using json = nlohmann::json; namespace caf { behavior summa_actor(stateful_actor<summa_actor_state>* self, - int startGRU, int numGRU, + int start_gru, int num_gru, Summa_Actor_Settings summa_actor_settings, File_Access_Actor_Settings file_access_actor_settings, Job_Actor_Settings job_actor_settings, @@ -25,8 +25,8 @@ behavior summa_actor(stateful_actor<summa_actor_state>* self, self->state.summa_actor_timing.addTimePoint("total_duration"); self->state.summa_actor_timing.updateStartPoint("total_duration"); // Set Variables - self->state.startGRU = startGRU; - self->state.numGRU = numGRU; + self->state.start_gru = start_gru; + self->state.num_gru = num_gru; self->state.parent = parent; // Set Settings self->state.summa_actor_settings = summa_actor_settings; @@ -39,7 +39,7 @@ behavior summa_actor(stateful_actor<summa_actor_state>* self, file_manager = std::make_unique<fileManager>( job_actor_settings.file_manager_path); // Set the directoires for the fortran side - auto err_msg = file_manager->initFileManagerModule(); + auto err_msg = file_manager->setTimesDirsAndFiles(); if (!err_msg.empty()) { aout(self) << "\n\nERROR--File Manager: " << err_msg << "\n\n"; self->quit(); return {}; @@ -53,22 +53,22 @@ behavior summa_actor(stateful_actor<summa_actor_state>* self, self->quit(); return {}; } - self->state.fileGRU = getNumGRUInFile(file_manager->settings_path_, + self->state.file_gru = getNumGRUInFile(file_manager->settings_path_, file_manager->local_attributes_); - if (self->state.fileGRU == -1) + if (self->state.file_gru == -1) aout(self) << "***WARNING***: UNABLE TO VERIFY NUMBER OF GRUS" << " - Job Actor MAY CRASH\n" - << "Number of GRUs in File: " << self->state.fileGRU << "\n"; + << "Number of GRUs in File: " << self->state.file_gru << "\n"; - if (self->state.fileGRU > 0) { + if (self->state.file_gru > 0) { // Fix the number of GRUs if it exceeds the number of GRUs in the file - if (self->state.startGRU + self->state.numGRU > self->state.fileGRU) { - self->state.numGRU = self->state.fileGRU - self->state.startGRU + 1; + if (self->state.start_gru + self->state.num_gru > self->state.file_gru) { + self->state.num_gru = self->state.file_gru - self->state.start_gru + 1; } } // No else: if we cannot verify we try to run anyway - self->state.batch_container = Batch_Container(self->state.startGRU, - self->state.numGRU, + self->state.batch_container = Batch_Container(self->state.start_gru, + self->state.num_gru, self->state.summa_actor_settings.max_gru_per_job); aout(self) << "Starting SUMMA With " @@ -88,12 +88,12 @@ behavior summa_actor(stateful_actor<summa_actor_state>* self, self->state.current_batch_id = batch->getBatchID(); aout(self) << "Starting Batch " << self->state.current_batch_id + 1 << "\n"; auto batch_val = batch.value(); - self->state.currentJob = self->spawn(job_actor, batch->getStartHRU(), + self->state.current_job = self->spawn(job_actor, batch->getStartHRU(), batch->getNumHRU(), self->state.file_access_actor_settings, self->state.job_actor_settings, self->state.hru_actor_settings, self); return { - [=](done_job, int numFailed, double job_duration, double read_duration, + [=](done_job, int num_gru_failed, double job_duration, double read_duration, double write_duration) { self->state.batch_container.updateBatch_success( @@ -103,13 +103,11 @@ behavior summa_actor(stateful_actor<summa_actor_state>* self, aout(self) << "###########################################\n" << "Job Finished: " << self->state.batch_container.getTotalBatches() - - self->state.batch_container.getBatchesRemaining() + self->state.batch_container.getBatchesRemaining() << "/" << self->state.batch_container.getTotalBatches() << "\n" << "###########################################\n"; - self->state.numFailed += numFailed; - - + self->state.num_gru_failed += num_gru_failed; if (self->state.batch_container.hasUnsolvedBatches()) { spawnJob(self); @@ -131,7 +129,7 @@ behavior summa_actor(stateful_actor<summa_actor_state>* self, << "Total Duration = " << total_dur_hr << " Hours\n" << "Total Read Duration = " << read_dur_sec << "Seconds\n" << "Total Write Duration = " << write_dur_sec << "Seconds\n" - << "Num Failed = " << self->state.numFailed << "\n" + << "Num Failed = " << self->state.num_gru_failed << "\n" << "___________________Program Finished__________________\n"; self->send(self->state.parent, done_batch_v, total_dur_sec, @@ -155,7 +153,7 @@ void spawnJob(stateful_actor<summa_actor_state>* self) { self->state.current_batch_id = batch->getBatchID(); aout(self) << "Starting Batch " << self->state.current_batch_id + 1 << "\n"; auto batch_val = batch.value(); - self->state.currentJob = self->spawn(job_actor, batch->getStartHRU(), + self->state.current_job = self->spawn(job_actor, batch->getStartHRU(), batch->getNumHRU(), self->state.file_access_actor_settings, self->state.job_actor_settings, self->state.hru_actor_settings, self); diff --git a/build/source/system_initialization/summa_global_data.cpp b/build/source/system_initialization/summa_global_data.cpp new file mode 100644 index 0000000..84c0cb1 --- /dev/null +++ b/build/source/system_initialization/summa_global_data.cpp @@ -0,0 +1,33 @@ +#include "summa_global_data.hpp" +#include <memory> +#include <iostream> + +summaGlobalData::summaGlobalData() { + global_data_ready = false; +} + +summaGlobalData::~summaGlobalData() { + if (global_data_ready) { + std::unique_ptr<char[]> err_msg(new char[1024]); + int err = 0; + deallocateGlobalData_fortran(&err, &err_msg); + if (err != 0) { + std::cout << "\n\nERROR: deallocateGlobalData_fortran() - " + << err_msg.get() << "\n\n"; + } + } +} + +int summaGlobalData::defineGlobalData() { + std::unique_ptr<char[]> err_msg(new char[1024]); + int err = 0; + defineGlobalData_fortran(&err, &err_msg); + if (err != 0) { + std::cout << "\n\nERROR: defineGlobalData_fortran() - " + << err_msg.get() << "\n\n"; + global_data_ready = false; + } else { + global_data_ready = true; + } + return err; +} -- GitLab