From 023abf59a76901df4c2f5c60692cafad3152919b Mon Sep 17 00:00:00 2001 From: Andrea Brambilla Date: Wed, 13 Mar 2019 14:13:51 +0100 Subject: [PATCH] Re-internalize data using an instance of run_context Used to support re-internalization in the everest project --- lib/enkf/enkf_main.cpp | 113 +++++++++++------- lib/enkf/ert_run_context.cpp | 4 + lib/enkf/tests/enkf_ert_run_context.cpp | 24 ++-- lib/include/ert/enkf/enkf_main.hpp | 2 + lib/include/ert/enkf/ert_run_context.hpp | 1 + python/res/enkf/enkf_main.py | 5 + .../enkf/test_enkf_load_results_manually.py | 31 +++++ 7 files changed, 128 insertions(+), 52 deletions(-) diff --git a/lib/enkf/enkf_main.cpp b/lib/enkf/enkf_main.cpp index 3bfcc58ed1..76e9bd9824 100644 --- a/lib/enkf/enkf_main.cpp +++ b/lib/enkf/enkf_main.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #define HAVE_THREAD_POOL 1 #include @@ -2284,60 +2285,86 @@ int enkf_main_load_from_forward_model(enkf_main_type * enkf_main, int iter , boo int enkf_main_load_from_forward_model_with_fs(enkf_main_type * enkf_main, int iter , bool_vector_type * iactive, stringlist_type ** realizations_msg_list, enkf_fs_type * fs) { printf("Loading from forward model\n"); - const int ens_size = enkf_main_get_ensemble_size( enkf_main ); - int result[ens_size]; model_config_type * model_config = enkf_main_get_model_config(enkf_main); - ert_run_context_type * run_context = ert_run_context_alloc_ENSEMBLE_EXPERIMENT( fs, iactive, model_config_get_runpath_fmt( model_config ), model_config_get_jobname_fmt( model_config ), enkf_main_get_data_kw(enkf_main), iter ); - arg_pack_type ** arg_list = (arg_pack_type **) util_calloc( ens_size , sizeof * arg_list ); // CXX_CAST_ERROR - thread_pool_type * tp = thread_pool_alloc( 4 , true ); /* num_cpu - HARD coded. */ - - for (int iens = 0; iens < ens_size; ++iens) { - printf("\tloading %d (realization %d/%d) ", iens, (1+iens), ens_size); - result[iens] = 0; - arg_pack_type * arg_pack = arg_pack_alloc(); - arg_list[iens] = arg_pack; - - if (bool_vector_iget(iactive, iens)) { - printf("... "); - enkf_state_type * enkf_state = enkf_main_iget_state( enkf_main , iens ); - arg_pack_append_ptr( arg_pack , enkf_state); /* 0: enkf_state*/ - arg_pack_append_ptr( arg_pack , ert_run_context_iget_arg( run_context , iens )); /* 1: run_arg */ - arg_pack_append_ptr(arg_pack, realizations_msg_list[iens]); /* 2: List of interactive mode messages. */ - arg_pack_append_bool( arg_pack, true ); /* 3: Manual load */ - arg_pack_append_ptr(arg_pack, &result[iens]); /* 4: Result */ - thread_pool_add_job( tp , enkf_state_load_from_forward_model_mt , arg_pack); - } - printf("done\n"); - } - - thread_pool_join( tp ); - thread_pool_free( tp ); - printf("\n"); - - int loaded = 0; - for (int iens = 0; iens < ens_size; ++iens) { - if (bool_vector_iget(iactive, iens)) { - if (result[iens] & LOAD_FAILURE) - fprintf(stderr, "** Warning: Function %s: Realization %d load failure\n", __func__, iens); - else if (result[iens] & REPORT_STEP_INCOMPATIBLE) - fprintf(stderr, "** Warning: Function %s: Realization %d report step incompatible\n", __func__, iens); - else - loaded++; - } - arg_pack_free(arg_list[iens]); - } - free( arg_list ); - ert_run_context_free( run_context ); + int loaded = enkf_main_load_from_run_context(enkf_main, run_context, realizations_msg_list, fs); + ert_run_context_free(run_context); return loaded; } +int enkf_main_load_from_run_context_from_gui(enkf_main_type* enkf_main, ert_run_context_type* run_context, enkf_fs_type* fs) { + auto const ens_size = enkf_main_get_ensemble_size(enkf_main); + stringlist_type ** realizations_msg_list = (stringlist_type **) util_calloc(ens_size, sizeof *realizations_msg_list); // CXX_CAST_ERROR + for(int iens = 0; iens < ens_size; ++iens) + realizations_msg_list[iens] = stringlist_alloc_new(); + + int loaded = enkf_main_load_from_run_context(enkf_main, run_context, realizations_msg_list, fs); + + for(int iens = 0; iens < ens_size; ++iens) + stringlist_free(realizations_msg_list[iens]); + free(realizations_msg_list); + return loaded; +} + +int enkf_main_load_from_run_context( + enkf_main_type * enkf_main, + ert_run_context_type * run_context, + stringlist_type ** realizations_msg_list, + enkf_fs_type * fs) { + printf("Loading from run context\n"); + auto const ens_size = enkf_main_get_ensemble_size( enkf_main ); + auto const * iactive = ert_run_context_get_iactive(run_context); + + int result[ens_size]; + arg_pack_type ** arg_list = (arg_pack_type **) util_calloc( ens_size , sizeof * arg_list ); // CXX_CAST_ERROR + thread_pool_type * tp = thread_pool_alloc( std::thread::hardware_concurrency() , true ); + + for (int iens = 0; iens < ens_size; ++iens) { + printf("\tloading %d (realization %d/%d) ", iens, (1+iens), ens_size); + result[iens] = 0; + arg_pack_type * arg_pack = arg_pack_alloc(); + arg_list[iens] = arg_pack; + + if (bool_vector_iget(iactive, iens)) { + printf("... "); + enkf_state_type * enkf_state = enkf_main_iget_state( enkf_main , iens ); + arg_pack_append_ptr( arg_pack , enkf_state); /* 0: enkf_state*/ + arg_pack_append_ptr( arg_pack , ert_run_context_iget_arg( run_context , iens )); /* 1: run_arg */ + arg_pack_append_ptr(arg_pack, realizations_msg_list[iens]); /* 2: List of interactive mode messages. */ + arg_pack_append_bool( arg_pack, true ); /* 3: Manual load */ + arg_pack_append_ptr(arg_pack, &result[iens]); /* 4: Result */ + thread_pool_add_job( tp , enkf_state_load_from_forward_model_mt , arg_pack); + } + printf("done\n"); + } + + thread_pool_join( tp ); + thread_pool_free( tp ); + printf("\n"); + + int loaded = 0; + for (int iens = 0; iens < ens_size; ++iens) { + if (bool_vector_iget(iactive, iens)) { + if (result[iens] & LOAD_FAILURE) + fprintf(stderr, "** Warning: Function %s: Realization %d load failure\n", __func__, iens); + else if (result[iens] & REPORT_STEP_INCOMPATIBLE) + fprintf(stderr, "** Warning: Function %s: Realization %d report step incompatible\n", __func__, iens); + else + loaded++; + } + arg_pack_free(arg_list[iens]); + } + free( arg_list ); + return loaded; +} + + bool enkf_main_export_field(const enkf_main_type * enkf_main, const char * kw, const char * path, diff --git a/lib/enkf/ert_run_context.cpp b/lib/enkf/ert_run_context.cpp index 28908b12e9..b9c822c197 100644 --- a/lib/enkf/ert_run_context.cpp +++ b/lib/enkf/ert_run_context.cpp @@ -437,3 +437,7 @@ int ert_run_context_get_active_size(const ert_run_context_type * context){ bool_vector_type * ert_run_context_alloc_iactive(const ert_run_context_type * context) { return bool_vector_alloc_copy(context->iactive); } + +bool_vector_type const * ert_run_context_get_iactive(const ert_run_context_type * context) { + return context->iactive; +} diff --git a/lib/enkf/tests/enkf_ert_run_context.cpp b/lib/enkf/tests/enkf_ert_run_context.cpp index 5f013237d2..0e45a9d908 100644 --- a/lib/enkf/tests/enkf_ert_run_context.cpp +++ b/lib/enkf/tests/enkf_ert_run_context.cpp @@ -114,18 +114,24 @@ void test_iactive_update() { ert_run_context_deactivate_realization( context , 9 ); test_assert_not_NULL( ert_run_context_get_id( context )); + test_assert_int_equal( ert_run_context_get_active_size(context), 7); + + auto check_iactive = [](bool_vector_type const* iactive) { + test_assert_int_equal( bool_vector_count_equal( iactive , true ) , 7 ); + test_assert_false( bool_vector_iget( iactive , 0 )); + test_assert_false( bool_vector_iget( iactive , 5 )); + test_assert_false( bool_vector_iget( iactive , 9 )); + }; + + check_iactive(ert_run_context_get_iactive(context)); + + bool_vector_type * iactive2 = ert_run_context_alloc_iactive(context); + check_iactive(iactive2); + bool_vector_free( iactive2 ); + path_fmt_free( runpath_fmt ); subst_list_free( subst_list ); bool_vector_free(iactive); - { - bool_vector_type * iactive = ert_run_context_alloc_iactive(context); - test_assert_int_equal( bool_vector_count_equal( iactive , true ) , 7 ); - test_assert_int_equal( ert_run_context_get_active_size(context), 7); - test_assert_false( bool_vector_iget( iactive , 0 )); - test_assert_false( bool_vector_iget( iactive , 5 )); - test_assert_false( bool_vector_iget( iactive , 9 )); - bool_vector_free( iactive ); - } ert_run_context_free( context ); } diff --git a/lib/include/ert/enkf/enkf_main.hpp b/lib/include/ert/enkf/enkf_main.hpp index 1f9080f6b0..b3f8b923f4 100644 --- a/lib/include/ert/enkf/enkf_main.hpp +++ b/lib/include/ert/enkf/enkf_main.hpp @@ -209,6 +209,8 @@ extern "C" { int enkf_main_load_from_forward_model_with_fs(enkf_main_type * enkf_main, int iter , bool_vector_type * iactive, stringlist_type ** realizations_msg_list, enkf_fs_type * fs); int enkf_main_load_from_forward_model(enkf_main_type * enkf_main, int iter , bool_vector_type * iactive, stringlist_type ** realizations_msg_list); int enkf_main_load_from_forward_model_from_gui(enkf_main_type * enkf_main, int iter , bool_vector_type * iactive, enkf_fs_type * fs); + int enkf_main_load_from_run_context(enkf_main_type* enkf_main, ert_run_context_type* run_context, stringlist_type** realizations_msg_list, enkf_fs_type* fs); + int enkf_main_load_from_run_context_from_gui(enkf_main_type* enkf_main, ert_run_context_type* run_context, enkf_fs_type* fs); void enkf_main_rank_on_observations(enkf_main_type * enkf_main, const char * ranking_key, diff --git a/lib/include/ert/enkf/ert_run_context.hpp b/lib/include/ert/enkf/ert_run_context.hpp index 4f4d6f6b0f..e3e6b8c2c4 100644 --- a/lib/include/ert/enkf/ert_run_context.hpp +++ b/lib/include/ert/enkf/ert_run_context.hpp @@ -85,6 +85,7 @@ typedef struct ert_run_context_struct ert_run_context_type; int ert_run_context_get_size( const ert_run_context_type * context ); run_mode_type ert_run_context_get_mode( const ert_run_context_type * context ); bool_vector_type * ert_run_context_alloc_iactive(const ert_run_context_type * context); + bool_vector_type const * ert_run_context_get_iactive(const ert_run_context_type * context); int ert_run_context_get_iter( const ert_run_context_type * context ); int ert_run_context_get_active_size(const ert_run_context_type * context); int ert_run_context_get_step1( const ert_run_context_type * context ); diff --git a/python/res/enkf/enkf_main.py b/python/res/enkf/enkf_main.py index 0a43991ff4..70deeaf7cf 100644 --- a/python/res/enkf/enkf_main.py +++ b/python/res/enkf/enkf_main.py @@ -195,6 +195,7 @@ class _RealEnKFMain(BaseCClass): _export_field = ResPrototype("bool enkf_main_export_field(enkf_main, char*, char*, bool_vector, enkf_field_file_format_enum, int)") _export_field_with_fs = ResPrototype("bool enkf_main_export_field_with_fs(enkf_main, char*, char*, bool_vector, enkf_field_file_format_enum, int, enkf_fs_manager)") _load_from_forward_model = ResPrototype("int enkf_main_load_from_forward_model_from_gui(enkf_main, int, bool_vector, enkf_fs)") + _load_from_run_context = ResPrototype("int enkf_main_load_from_run_context_from_gui(enkf_main, ert_run_context, enkf_fs)") _create_run_path = ResPrototype("void enkf_main_create_run_path(enkf_main , ert_run_context)") _icreate_run_path = ResPrototype("void enkf_main_icreate_run_path(enkf_main , run_arg, enkf_init_mode_enum)") _submit_simulation = ResPrototype("void enkf_main_isubmit_job(enkf_main , run_arg, job_queue)") @@ -406,6 +407,10 @@ def exportField(self, keyword, path, iactive, file_type, report_step, state, enk def loadFromForwardModel(self, realization, iteration, fs): """Returns the number of loaded realizations""" return self._load_from_forward_model(iteration, realization, fs) + + def loadFromRunContext(self, run_context, fs): + """Returns the number of loaded realizations""" + return self._load_from_run_context(run_context, fs) def initRun(self, run_context): self._init_run(run_context) diff --git a/python/tests/res/enkf/test_enkf_load_results_manually.py b/python/tests/res/enkf/test_enkf_load_results_manually.py index b618222e79..70f82be5d7 100755 --- a/python/tests/res/enkf/test_enkf_load_results_manually.py +++ b/python/tests/res/enkf/test_enkf_load_results_manually.py @@ -37,3 +37,34 @@ def test_load_results_manually(self): self.assertEqual(24, loaded) self.assertEqual(25, len(expected)) self.assertEqual(25, len(realisations)) + + def test_load_results_from_run_context(self): + with ErtTestContext("manual_load_test", self.config_file) as test_context: + ert = test_context.getErt() + load_into_case = "A1" + load_from_case = "default" + + load_into = ert.getEnkfFsManager().getFileSystem(load_into_case) + load_from = ert.getEnkfFsManager().getFileSystem(load_from_case) + + ert.getEnkfFsManager().switchFileSystem(load_from) + realisations = BoolVector(default_value=True, initial_size=25) + realisations[7] = False + iteration = 0 + + run_context = ert.getRunContextENSEMPLE_EXPERIMENT(load_into, + realisations) + + loaded = ert.loadFromRunContext(run_context, load_into) + + load_into_case_state_map = load_into.getStateMap() + load_into_states = [state for state in load_into_case_state_map] + + expected = [RealizationStateEnum.STATE_HAS_DATA] * 25 + expected[7] = RealizationStateEnum.STATE_UNDEFINED + + self.assertListEqual(load_into_states, expected) + self.assertEqual(24, loaded) + self.assertEqual(25, len(expected)) + self.assertEqual(25, len(realisations)) +