void enkf_main_initialize_from_scratch_with_bool_vector(enkf_main_type * enkf_main , const stringlist_type * param_list ,const bool_vector_type * iens_mask , init_mode_type init_mode) { int num_cpu = 4; int ens_size = enkf_main_get_ensemble_size( enkf_main ); thread_pool_type * tp = thread_pool_alloc( num_cpu , true ); arg_pack_type ** arg_list = util_calloc( ens_size , sizeof * arg_list ); int i; int iens; for (iens = 0; iens < ens_size; iens++) { arg_list[iens] = arg_pack_alloc(); if (bool_vector_safe_iget(iens_mask , iens)) { arg_pack_append_ptr( arg_list[iens] , enkf_main ); arg_pack_append_const_ptr( arg_list[iens] , param_list ); arg_pack_append_int( arg_list[iens] , iens ); arg_pack_append_int( arg_list[iens] , init_mode ); thread_pool_add_job( tp , enkf_main_initialize_from_scratch_mt , arg_list[iens]); } } thread_pool_join( tp ); for (i = 0; i < ens_size; i++) { arg_pack_free( arg_list[i] ); } free( arg_list ); thread_pool_free( tp ); }
void enkf_tui_analysis_menu(void * arg) { enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); menu_type * menu = menu_alloc( "Analysis menu" , "Back" , "bB"); arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , enkf_main ); arg_pack_append_ptr( arg_pack , menu ); { enkf_tui_analysis_update_title(enkf_main, menu); if (enkf_main_have_obs(enkf_main)) { menu_add_item(menu, "Global scaling of uncertainty", "gG", enkf_tui_analysis_scale_observation_std__, enkf_main, NULL); menu_add_separator(menu); } menu_add_item(menu, "Select analysis module", "sS", enkf_tui_analysis_select_module__, arg_pack, NULL); menu_add_item(menu, "List available modules", "lL", enkf_tui_analysis_list_modules__, enkf_main, NULL); menu_add_item(menu, "Modify analysis module parameters", "mM", enkf_tui_analysis_update_module__, enkf_main, NULL); menu_add_item(menu, "Reload current module (external only)", "rR", enkf_tui_analysis_reload_module__, enkf_main, NULL); } menu_run(menu); menu_free(menu); arg_pack_free(arg_pack); }
void matrix_inplace_matmul_mt2(matrix_type * A, const matrix_type * B , thread_pool_type * thread_pool){ int num_threads = thread_pool_get_max_running( thread_pool ); arg_pack_type ** arglist = util_malloc( num_threads * sizeof * arglist ); int it; thread_pool_restart( thread_pool ); { int rows = matrix_get_rows( A ) / num_threads; int rows_mod = matrix_get_rows( A ) % num_threads; int row_offset = 0; for (it = 0; it < num_threads; it++) { int row_size; arglist[it] = arg_pack_alloc(); row_size = rows; if (it < rows_mod) row_size += 1; arg_pack_append_int(arglist[it] , row_offset ); arg_pack_append_int(arglist[it] , row_size ); arg_pack_append_ptr(arglist[it] , A ); arg_pack_append_const_ptr(arglist[it] , B ); thread_pool_add_job( thread_pool , matrix_inplace_matmul_mt__ , arglist[it]); row_offset += row_size; } } thread_pool_join( thread_pool ); for (it = 0; it < num_threads; it++) arg_pack_free( arglist[it] ); free( arglist ); }
void enkf_tui_ranking_menu(void * arg) { enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); { menu_type * menu = menu_alloc("Ranking of results" , "Back" , "bB"); menu_item_type * obs_item; { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , enkf_main ); menu_add_item(menu , "Create/update misfit table" , "cC" , enkf_tui_ranking_make_misfit_ensemble , arg_pack , arg_pack_free__); menu_add_separator( menu ); obs_item = menu_add_item(menu , "New observation based ranking" , "nN" , enkf_tui_ranking_create_obs , enkf_main , NULL); arg_pack_append_ptr( arg_pack , obs_item ); } menu_add_item(menu , "New data based ranking (Sort: increasing)" , "iI" , enkf_tui_ranking_create_data_increasing , enkf_main , NULL); menu_add_item(menu , "New data based ranking (Sort: decreasing)" , "dD" , enkf_tui_ranking_create_data_decreasing , enkf_main , NULL); menu_add_item(menu , "Show ranking" , "sS" , enkf_tui_ranking_display , enkf_main , NULL); { enkf_fs_type * fs = enkf_main_get_fs( enkf_main ); misfit_ensemble_type * misfit_ensemble = enkf_fs_get_misfit_ensemble( fs ); if (!misfit_ensemble_initialized( misfit_ensemble )) menu_item_disable( obs_item ); } menu_add_item(menu , "Help" , "hH" , enkf_tui_help_menu_rank , enkf_main , NULL); menu_run(menu); menu_free(menu); } }
int test_load_manually_to_new_case(enkf_main_type * enkf_main) { int result = 0; int iens = 0; int iter = 0; const char * casename = "new_case"; enkf_main_select_fs( enkf_main , casename ); enkf_fs_type * fs = enkf_main_get_fs( enkf_main ); run_arg_type * run_arg = run_arg_alloc_ENSEMBLE_EXPERIMENT(fs , iens , iter , "simulations/run0"); { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , enkf_main_iget_state(enkf_main, 0)); arg_pack_append_ptr( arg_pack , run_arg ); arg_pack_append_bool( arg_pack , true ); arg_pack_append_owned_ptr( arg_pack , stringlist_alloc_new() , stringlist_free__); arg_pack_append_bool( arg_pack, true ); arg_pack_append_ptr( arg_pack, &result ); enkf_state_load_from_forward_model_mt(arg_pack); arg_pack_free(arg_pack); } return result; }
static void job_queue_handle_EXIT( job_queue_type * queue , job_queue_node_type * node) { job_queue_change_node_status(queue , node , JOB_QUEUE_RUNNING_CALLBACK ); { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , queue ); arg_pack_append_int( arg_pack , job_queue_node_get_queue_index(node)); thread_pool_add_job( queue->work_pool , job_queue_run_EXIT_callback , arg_pack ); } }
void submit_jobs( job_queue_type * queue , int num_jobs , job_type ** jobs , thread_pool_type * tp) { for (int i=0; i < num_jobs; i++) { job_type * job = jobs[i]; arg_pack_type * arg = arg_pack_alloc(); arg_pack_append_ptr( arg , job ); arg_pack_append_ptr( arg , queue ); thread_pool_add_job(tp , submit_job__ , arg ); } }
void job_queue_start_manager_thread( job_queue_type * job_queue , pthread_t * queue_thread , int job_size , bool verbose) { arg_pack_type * queue_args = arg_pack_alloc(); /* This arg_pack will be freed() in the job_que_run_jobs__() */ arg_pack_append_ptr(queue_args , job_queue); arg_pack_append_int(queue_args , job_size); arg_pack_append_bool(queue_args , verbose); job_queue->running = true; pthread_create( queue_thread , NULL , job_queue_run_jobs__ , queue_args); }
static trans_func_type * trans_func_alloc_empty( const char * func_name ) { trans_func_type * trans_func = util_malloc( sizeof * trans_func ); trans_func->params = arg_pack_alloc(); trans_func->func = NULL; trans_func->validate = NULL; trans_func->name = util_alloc_string_copy( func_name ); trans_func->param_names = stringlist_alloc_new(); return trans_func; }
int main( int argc , char ** argv) { const char * ptr1 = "Pointer1"; const char * ptr2 = "Pointer2"; arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_const_ptr( arg_pack , ptr1 ); arg_pack_append_const_ptr( arg_pack , ptr2 ); test_assert_ptr_equal( ptr1 , arg_pack_iget_const_ptr( arg_pack , 0 )); test_assert_ptr_equal( ptr2 , arg_pack_iget_const_ptr( arg_pack , 1 )); exit(0); }
void ensemble_load_from_glob( ensemble_type * ensemble , const char * pattern , thread_pool_type * tp) { glob_t pglob; int i; glob( pattern , GLOB_NOSORT , NULL , &pglob ); for (i=0; i < pglob.gl_pathc; i++) { arg_pack_type * arg_pack = arg_pack_alloc( ); arg_pack_append_ptr( arg_pack , ensemble ); arg_pack_append_owned_ptr( arg_pack , util_alloc_string_copy( pglob.gl_pathv[i] ) , free ); thread_pool_add_job( tp , ensemble_add_case__ , arg_pack ); } globfree( &pglob ); }
void enkf_tui_fs_menu(void * arg) { enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); const char * menu_title = util_alloc_sprintf("Manage cases - current: %s", enkf_main_get_current_fs( enkf_main )); menu_type * menu = menu_alloc(menu_title , "Back" , "bB"); menu_add_item(menu , "List available cases" , "lL" , enkf_tui_fs_ls_case , enkf_main , NULL); { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr(arg_pack , enkf_main); arg_pack_append_ptr(arg_pack , menu); menu_add_item(menu , "Create and select new case" , "cC" , enkf_tui_fs_create_case, arg_pack , arg_pack_free__); } { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr(arg_pack , enkf_main); arg_pack_append_ptr(arg_pack , menu); menu_add_item(menu , "Select case" , "sS" , enkf_tui_fs_select_case, arg_pack , arg_pack_free__); } menu_add_separator(menu); menu_add_item(menu, "Initialize case from scratch" , "iI" , enkf_tui_init_menu , enkf_main , NULL); menu_add_item(menu, "Initialize case from existing case" , "aA" , enkf_tui_fs_initialize_case_from_copy , enkf_main , NULL); menu_add_item(menu, "Initialize case FOR PREDICTIONS from existing case", "pP" , enkf_tui_fs_initialize_case_for_predictions , enkf_main , NULL); menu_add_separator(menu); /* Are these two in use??? */ menu_add_item(menu, "Copy full ensemble to another case", "eE", enkf_tui_fs_copy_ensemble, enkf_main, NULL); menu_add_item(menu, "Copy ensemble of parameters to another case", "oO", enkf_tui_fs_copy_ensemble_of_parameters, enkf_main, NULL); menu_add_item(menu , "Help" , "hH" , enkf_tui_help_menu_cases , enkf_main , NULL); menu_run(menu); menu_free(menu); }
void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const stringlist_type * param_list , int iens1 , int iens2, init_mode_enum init_mode) { int num_cpu = 4; thread_pool_type * tp = thread_pool_alloc( num_cpu , true ); int ens_sub_size = (iens2 - iens1 + 1) / num_cpu; arg_pack_type ** arg_list = util_calloc( num_cpu , sizeof * arg_list ); int i; printf("Setting up ensemble members from %d to %d", iens1, iens2); if (init_mode == INIT_CONDITIONAL) { printf(" using conditional initialization (keep existing parameter values).\n"); } else if (init_mode == INIT_FORCE) { printf(" using forced initialization (initialize from scratch).\n"); } else if (init_mode == INIT_NONE) { printf(" not initializing at all.\n"); } fflush( stdout ); for (i = 0; i < num_cpu; i++) { arg_list[i] = arg_pack_alloc(); arg_pack_append_ptr( arg_list[i] , enkf_main ); arg_pack_append_const_ptr( arg_list[i] , param_list ); { int start_iens = i * ens_sub_size; int end_iens = start_iens + ens_sub_size; if (i == (num_cpu - 1)){ end_iens = iens2 + 1; /* Input is upper limit inclusive. */ if(ens_sub_size == 0) start_iens = iens1; /* Don't necessarily want to start from zero when ens_sub_size = 0*/ } arg_pack_append_int( arg_list[i] , start_iens ); arg_pack_append_int( arg_list[i] , end_iens ); } arg_pack_append_int( arg_list[i] , init_mode ); thread_pool_add_job( tp , enkf_main_initialize_from_scratch_mt , arg_list[i]); } thread_pool_join( tp ); for (i = 0; i < num_cpu; i++) arg_pack_free( arg_list[i] ); free( arg_list ); thread_pool_free( tp ); printf("Done setting up ensemble.\n"); }
void test_add_job() { job_list_type * list = job_list_alloc(); job_queue_node_type * node = job_queue_node_alloc_simple("name" , "/tmp" , "/bin/ls" , 0 , NULL); job_list_add_job( list , node ); test_assert_int_equal( job_list_get_size( list ) , 1 ); test_assert_int_equal( job_queue_node_get_queue_index(node) , 0 ); test_assert_ptr_equal( node , job_list_iget_job(list , 0)); { arg_pack_type * arg_pack = arg_pack_alloc( ); arg_pack_append_ptr( arg_pack , list ); arg_pack_append_ptr( arg_pack , node ); test_assert_util_abort("job_queue_node_set_queue_index", call_add_job, arg_pack ); arg_pack_free( arg_pack ); } test_assert_util_abort("job_list_iget_job", call_iget_job, list); job_list_reset( list ); test_assert_int_equal( 0 , job_list_get_size( list )); job_list_free( list ); }
int main(int argc , char ** argv) { install_SIGNALS(); if(argc > 1) { if(strcmp(argv[1], "-h") == 0) print_usage(__LINE__); } if(argc < 2) print_usage(__LINE__); else{ char ** input = &argv[1]; /* Skipping the name of the executable */ int input_length = argc - 1; int input_offset = 0; bool use_eclbase, fmt_file; const char * report_filen = "RUN_GRAVITY.out"; ecl_file_type ** restart_files; ecl_file_type * init_file; ecl_grid_type * ecl_grid; int model_phases; int file_phases; vector_type * grav_stations = vector_alloc_new(); /* Restart info */ restart_files = load_restart_info( (const char **) input , input_length , &input_offset , &use_eclbase , &fmt_file); /* INIT and GRID/EGRID files */ { char * grid_filename = NULL; char * init_filename = NULL; if (use_eclbase) { /* The first command line argument is interpreted as ECLBASE, and we search for grid and init files in cwd. */ init_filename = ecl_util_alloc_exfilename_anyfmt( NULL , input[0] , ECL_INIT_FILE , fmt_file , -1); grid_filename = ecl_util_alloc_exfilename_anyfmt( NULL , input[0] , ECL_EGRID_FILE , fmt_file , -1); if (grid_filename == NULL) grid_filename = ecl_util_alloc_exfilename_anyfmt( NULL , input[0] , ECL_GRID_FILE , fmt_file , -1); if ((init_filename == NULL) || (grid_filename == NULL)) /* Means we could not find them. */ util_exit("Could not find INIT or GRID|EGRID file \n"); } else { /* */ if ((input_length - input_offset) > 1) { init_filename = util_alloc_string_copy(input[input_offset]); grid_filename = util_alloc_string_copy(input[input_offset + 1]); input_offset += 2; } else print_usage(__LINE__); } init_file = ecl_file_open(init_filename ); ecl_grid = ecl_grid_alloc(grid_filename ); free( init_filename ); free( grid_filename ); } // Load the station_file if (input_length > input_offset) { char * station_file = input[input_offset]; if (util_file_exists(station_file)) load_stations( grav_stations , station_file); else util_exit("Can not find file:%s \n",station_file); } else print_usage(__LINE__); /** OK - now everything is loaded - check that all required keywords+++ are present. */ gravity_check_input(ecl_grid , init_file , restart_files[0] , restart_files[1] , &model_phases , &file_phases); /* OK - now it seems the provided files have all the information we need. Let us start using it. The main loop is run in parallell on four threads - most people have four cores these days. */ { int i; int num_threads = 4; thread_pool_type * tp = thread_pool_alloc( num_threads , true); arg_pack_type ** arg_list = util_calloc( num_threads , sizeof * arg_list); { int station_delta = vector_get_size( grav_stations ) / num_threads; for (i = 0; i < num_threads; i++) { int station1 = i * station_delta; int station2 = station1 + station_delta; if (i == num_threads) station2 = vector_get_size( grav_stations ); arg_list[i] = arg_pack_alloc( ); arg_pack_append_ptr( arg_list[i] , grav_stations ); arg_pack_append_ptr( arg_list[i] , ecl_grid); arg_pack_append_ptr( arg_list[i] , init_file ); arg_pack_append_ptr( arg_list[i] , restart_files); arg_pack_append_int( arg_list[i] , station1 ); arg_pack_append_int( arg_list[i] , station2 ); arg_pack_append_int( arg_list[i] , model_phases ); arg_pack_append_int( arg_list[i] , file_phases ); thread_pool_add_job( tp , gravity_response_mt , arg_list[i]); } } thread_pool_join( tp ); for (i = 0; i < num_threads; i++) arg_pack_free( arg_list[i] ); free( arg_list ); } { FILE * stream = util_fopen(report_filen , "w"); int station_nr; double total_chisq = 0; for(station_nr = 0; station_nr < vector_get_size( grav_stations ); station_nr++){ const grav_station_type * g_s = vector_iget_const(grav_stations, station_nr); fprintf(stream, "%f",g_s->grav_diff); printf ("DELTA_G %4s[%02d]: %12.6f %12.6f %12.6f %12.6f", g_s->name , station_nr, g_s->grav_diff, g_s->utm_x, g_s->utm_y, g_s->depth); if ( g_s->has_obs ) { double y = (g_s->grav_diff - g_s->obs_gdiff) / g_s->std_gdiff; double chi_sq = y * y; total_chisq += chi_sq; fprintf(stream , " %g",chi_sq); printf(" %g",chi_sq); } fprintf(stream , " \n"); printf("\n"); } if (total_chisq > 0) { printf("Total chisq misfit: %g \n", total_chisq); } fclose(stream); } vector_free( grav_stations ); ecl_grid_free(ecl_grid); ecl_file_close(restart_files[0]); ecl_file_close(restart_files[1]); free( restart_files ); ecl_file_close(init_file); } }
void test_runpath_list() { runpath_list_type * list = runpath_list_alloc(); test_assert_int_equal( runpath_list_size( list ) , 0 ); runpath_list_add( list , 3 , 0, "path" , "base"); runpath_list_add( list , 2 , 0, "path" , "base"); runpath_list_add( list , 1 , 0, "path" , "base"); runpath_list_add( list , 3 , 1, "path" , "base"); runpath_list_add( list , 2 , 1, "path" , "base"); runpath_list_add( list , 1 , 1, "path" , "base"); test_assert_int_equal( runpath_list_size( list ) , 6 ); test_assert_int_equal( runpath_list_iget_iens( list , 0 ) , 3 ); test_assert_int_equal( runpath_list_iget_iens( list , 2 ) , 1 ); test_assert_int_equal( runpath_list_iget_iter( list , 3 ) , 1 ); runpath_list_sort( list ); test_assert_int_equal( runpath_list_iget_iens( list , 0 ) , 1 ); test_assert_int_equal( runpath_list_iget_iens( list , 4 ) , 3 ); runpath_list_clear( list ); test_assert_int_equal( runpath_list_size( list ) , 0 ); test_assert_string_equal( runpath_list_get_line_fmt( list ) , RUNPATH_LIST_DEFAULT_LINE_FMT ); { const char * other_line = "%d %s %s"; runpath_list_set_line_fmt( list , other_line ); test_assert_string_equal( runpath_list_get_line_fmt( list ) , other_line ); } runpath_list_set_line_fmt( list , NULL ); test_assert_string_equal( runpath_list_get_line_fmt( list ) , RUNPATH_LIST_DEFAULT_LINE_FMT ); { const int block_size = 100; const int threads = 100; thread_pool_type * tp = thread_pool_alloc( threads , true ); int it; for (it = 0; it < threads; it++) { int iens_offset = it * block_size; arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , list ); arg_pack_append_int( arg_pack , iens_offset ); arg_pack_append_int( arg_pack , block_size ); thread_pool_add_job( tp , add_pathlist , arg_pack ); } thread_pool_join( tp ); test_assert_int_equal( runpath_list_size( list ) , block_size * threads ); runpath_list_sort( list ); { int iens; for (iens = 0; iens < block_size * threads; iens++) test_assert_int_equal( runpath_list_iget_iens( list , iens ) , iens ); } { test_work_area_type * work_area = test_work_area_alloc("enkf_runpath_list" ); const char *filename = "runpath_list.txt"; { FILE * stream = util_fopen( filename, "w"); runpath_list_fprintf( list , stream ); fclose( stream ); } { int file_iens; int file_iter; char file_path[256]; char file_base[256]; int iens; FILE * stream = util_fopen( filename, "r"); for (iens = 0; iens < threads * block_size; iens++) { int fscanf_return = fscanf( stream , "%d %s %s %d" , &file_iens , file_path , file_base, &file_iter); test_assert_int_equal(fscanf_return, 4 ); test_assert_int_equal( file_iens , iens ); test_assert_int_equal( file_iter , 0 ); } fclose( stream ); } test_work_area_free( work_area ); } } runpath_list_free( list ); }
void enkf_tui_run_manual_load__( void * arg ) { enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); enkf_fs_type * fs = enkf_main_get_fs( enkf_main ); const int last_report = -1; const int ens_size = enkf_main_get_ensemble_size( enkf_main ); int step1,step2; bool_vector_type * iactive = bool_vector_alloc( 0 , false ); run_mode_type run_mode = ENSEMBLE_EXPERIMENT; enkf_main_init_run(enkf_main , run_mode); /* This is ugly */ step1 = 0; step2 = last_report; /** Observe that for the summary data it will load all the available data anyway. */ { char * prompt = util_alloc_sprintf("Which realizations to load (Ex: 1,3-5) <Enter for all> [M to return to menu] : [ensemble size:%d] : " , ens_size); char * select_string; util_printf_prompt(prompt , PROMPT_LEN , '=' , "=> "); select_string = util_alloc_stdin_line(); enkf_tui_util_sscanf_active_list( iactive , select_string , ens_size ); util_safe_free( select_string ); free( prompt ); } if (bool_vector_count_equal( iactive , true )) { int iens; arg_pack_type ** arg_list = util_calloc( ens_size , sizeof * arg_list ); thread_pool_type * tp = thread_pool_alloc( 4 , true ); /* num_cpu - HARD coded. */ for (iens = 0; iens < ens_size; iens++) { arg_pack_type * arg_pack = arg_pack_alloc(); arg_list[iens] = arg_pack; if (bool_vector_iget(iactive , iens)) { enkf_state_type * enkf_state = enkf_main_iget_state( enkf_main , iens ); arg_pack_append_ptr( arg_pack , enkf_state); /* 0: */ arg_pack_append_ptr( arg_pack , fs ); /* 1: */ arg_pack_append_int( arg_pack , step1 ); /* 2: This will be the load start parameter for the run_info struct. */ arg_pack_append_int( arg_pack , step1 ); /* 3: Step1 */ arg_pack_append_int( arg_pack , step2 ); /* 4: Step2 For summary data it will load the whole goddamn thing anyway.*/ arg_pack_append_bool( arg_pack , true ); /* 5: Interactive */ arg_pack_append_owned_ptr( arg_pack , stringlist_alloc_new() , stringlist_free__); /* 6: List of interactive mode messages. */ thread_pool_add_job( tp , enkf_state_load_from_forward_model_mt , arg_pack); } } thread_pool_join( tp ); thread_pool_free( tp ); printf("\n"); { qc_module_type * qc_module = enkf_main_get_qc_module( enkf_main ); runpath_list_type * runpath_list = qc_module_get_runpath_list( qc_module ); for (iens = 0; iens < ens_size; iens++) { if (bool_vector_iget(iactive , iens)) { const enkf_state_type * state = enkf_main_iget_state( enkf_main , iens ); runpath_list_add( runpath_list , iens , enkf_state_get_run_path( state ) , enkf_state_get_eclbase( state )); } } qc_module_export_runpath_list( qc_module ); } for (iens = 0; iens < ens_size; iens++) { if (bool_vector_iget(iactive , iens)) { stringlist_type * msg_list = arg_pack_iget_ptr( arg_list[iens] , 6 ); if (stringlist_get_size( msg_list )) enkf_tui_display_load_msg( iens , msg_list ); } } for (iens = 0; iens < ens_size; iens++) arg_pack_free( arg_list[iens]); free( arg_list ); } bool_vector_free( iactive ); }