diff --git a/src/SeapodymCohort.cpp b/src/SeapodymCohort.cpp index e5506ce..72f767d 100755 --- a/src/SeapodymCohort.cpp +++ b/src/SeapodymCohort.cpp @@ -33,12 +33,12 @@ std::vector SeapodymCohort::GetCohortDensity() void SeapodymCohort::InitializeCohort(dvar_vector& x, DistDataCollector& dataCollector, const bool writeoutputfiles) { -double t_all = MPI_Wtime(); -double t_rs = 0.0; -double t_reset = MPI_Wtime(); - //Reset model parameters: - reset(x); -time_xreset += MPI_Wtime() - t_reset; + double t_all = MPI_Wtime(); + double t_rs = 0.0; + double t_reset = MPI_Wtime(); + //Reset model parameters: moved to worker init in main_cohort.cpp + //reset(x); + time_xreset += MPI_Wtime() - t_reset; //----------------------------------------------// // ALLOCATE AND INITIALIZE COHORT DENSITY // diff --git a/src/main_cohort.cpp b/src/main_cohort.cpp index 1c5920e..42f2824 100755 --- a/src/main_cohort.cpp +++ b/src/main_cohort.cpp @@ -17,6 +17,7 @@ #include "Tags.h" #include #include +#include "admodel.h" double time_ic_comm = 0.0, time_ic_flush = 0.0, time_ic_copy = 0.0, time_spawning = 0.0, time_getdata = 0.0, time_xreset = 0.0, time_init_cohort_spawning = 0.0, time_init_cohort_restart = 0.0, time_io_forcing = 0.0; long n_ic = 0; // count of spawning-path inits, for per-init averages @@ -56,7 +57,8 @@ SeapodymCohort xinit_prerun_wrapper(const char* parfile) { void taskFunction(int task_id, int stepBeg, int stepEnd, MPI_Comm comm, const std::shared_ptr& logger, DistDataCollector* dataCollector, - SeapodymCohort* cohort){ + SeapodymCohort* cohort, + const independent_variables& x){ static double last_task_end = -1.0; // per-worker process, persists across calls double t_in = MPI_Wtime(); @@ -68,11 +70,6 @@ void taskFunction(int task_id, int stepBeg, int stepEnd, MPI_Comm comm, logger->info("> task id {} for steps {} to {}", task_id, stepBeg, stepEnd); logger->info(" >> initialization of task id {}", task_id); - //initialize variables of optimization - const int nvar = cohort->nvarcalc(); - independent_variables x(1, nvar); - adstring_array x_names(1,nvar); - cohort->xinit(x, x_names); int cohort_id = task_id; cohort->restart(cohort_id); @@ -253,6 +250,14 @@ int main(int argc, char** argv) { SeapodymCohort cohort= xinit_prerun_wrapper(parfile.c_str()); + // Initialize optimization variables once; x is stable for all tasks + // (xinit fills x from fixed model parameters that don't change between tasks). + // x is captured by reference in taskFunc — lifetime matches the enclosing block. + const int nvar = cohort.nvarcalc(); + independent_variables x(1, nvar); + adstring_array x_names(1, nvar); + cohort.xinit(x, x_names); + cohort.setDataProvider(&dp); //MPI_Win_fence(0, dp.win()); @@ -261,6 +266,11 @@ int main(int argc, char** argv) { //MPI_Win_fence(0, dp.win()); double t_shm = MPI_Wtime(); cohort.setShmForcing(); // every node-local worker reads its timestep slice + + // Reset model parameters (applies boundp() transforms from optimisation space to + // physical parameter space) — done once here rather than per-task in InitializeCohort. + cohort.reset(dvar_vector(x)); + MPI_Barrier(dp.getShmComm()); // per-node publish-sync: all slabs visible before any read time_io_forcing += MPI_Wtime()-t_shm; @@ -272,7 +282,8 @@ int main(int argc, char** argv) { std::placeholders::_4, // MPI communicator so we can send messages to the manager at the end of each step logger, &dataCollect, - &cohort); + &cohort, + std::cref(x)); // x lives in this block, outlives taskFunc and worker.run() TaskStepWorker worker(MPI_COMM_WORLD, taskFunc, stepBegMap, stepEndMap);