diff --git a/cadCAD/__init__.py b/cadCAD/__init__.py index 6b35512e..55572d6c 100644 --- a/cadCAD/__init__.py +++ b/cadCAD/__init__.py @@ -2,6 +2,8 @@ name = "cadCAD" configs = [] +global experiment_count +# experiment_count = 0 if os.name == 'nt': dill.settings['recurse'] = True diff --git a/cadCAD/configuration/__init__.py b/cadCAD/configuration/__init__.py index a48890b1..7b61cd88 100644 --- a/cadCAD/configuration/__init__.py +++ b/cadCAD/configuration/__init__.py @@ -1,7 +1,7 @@ from pprint import pprint from typing import Dict, Callable, List, Tuple from pandas.core.frame import DataFrame -from functools import reduce +from collections import deque from copy import deepcopy import pandas as pd # from time import time @@ -15,7 +15,8 @@ class Configuration(object): def __init__(self, user_id, sim_config={}, initial_state={}, seeds={}, env_processes={}, exogenous_states={}, partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], - session_id=0, simulation_id=0, run_id=1, **kwargs) -> None: + session_id=0, simulation_id=0, run_id=1, experiment_id=0, exp_window=deque([0, None], 2), **kwargs + ) -> None: # print(exogenous_states) self.sim_config = sim_config self.initial_state = initial_state @@ -27,88 +28,197 @@ def __init__(self, user_id, sim_config={}, initial_state={}, seeds={}, env_proce self.kwargs = kwargs self.user_id = user_id - self.session_id = session_id + self.session_id = session_id # eesntially config id self.simulation_id = simulation_id self.run_id = run_id + self.experiment_id = experiment_id + self.exp_window = exp_window sanitize_config(self) -def append_configs( - user_id='cadCAD_user', - session_id=0, #ToDo: change to string - sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={}, - partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], _exo_update_per_ts: bool = True, - config_list=configs - ) -> None: - - try: - max_runs = sim_configs[0]['N'] - except KeyError: - max_runs = sim_configs['N'] - - if _exo_update_per_ts is True: - exogenous_states = exo_update_per_ts(raw_exogenous_states) - else: - exogenous_states = raw_exogenous_states - - if isinstance(sim_configs, dict): - sim_configs = [sim_configs] - - simulation_id = 0 - if len(config_list) > 0: - last_config = config_list[-1] - simulation_id = last_config.simulation_id + 1 - - sim_cnt = 0 - new_sim_configs = [] - for t in list(zip(sim_configs, list(range(len(sim_configs))))): - sim_config = t[0] - N = sim_config['N'] - - if N > 1: - for n in range(N): - sim_config['simulation_id'] = simulation_id + sim_cnt - sim_config['run_id'] = n - sim_config['N'] = 1 - # sim_config['N'] = n + 1 - new_sim_configs.append(deepcopy(sim_config)) - del sim_config +class Experiment: + def __init__(self): + self.exp_id = 0 + self.exp_window = deque([self.exp_id, None], 2) + + def append_configs( + self, + user_id='cadCAD_user', + session_id=0, # ToDo: change to string + sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={}, + partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], _exo_update_per_ts: bool = True, + config_list=configs + ) -> None: + + try: + max_runs = sim_configs[0]['N'] + except KeyError: + max_runs = sim_configs['N'] + + if _exo_update_per_ts is True: + exogenous_states = exo_update_per_ts(raw_exogenous_states) else: - sim_config['simulation_id'] = simulation_id - sim_config['run_id'] = 0 - new_sim_configs.append(deepcopy(sim_config)) - # del sim_config - - sim_cnt += 1 - - run_id = 0 - for sim_config in new_sim_configs: - sim_config['N'] = run_id + 1 - if max_runs == 1: - sim_config['run_id'] = run_id - elif max_runs >= 1: - if run_id >= max_runs: - sim_config['N'] = run_id - (max_runs - 1) - - config = Configuration( - sim_config=sim_config, - initial_state=initial_state, - seeds=seeds, - exogenous_states=exogenous_states, - env_processes=env_processes, - partial_state_update_blocks=partial_state_update_blocks, - policy_ops=policy_ops, - - # session_id=session_id, - user_id=user_id, - session_id=f"{user_id}={sim_config['simulation_id']}_{sim_config['run_id']}", - simulation_id=sim_config['simulation_id'], - # run_id=run_id_config - run_id=sim_config['run_id'] - ) - configs.append(config) - run_id += 1 + exogenous_states = raw_exogenous_states + + if isinstance(sim_configs, dict): + sim_configs = [sim_configs] + + simulation_id = 0 + if len(config_list) > 0: + last_config = config_list[-1] + simulation_id = last_config.simulation_id + 1 + + sim_cnt = 0 + new_sim_configs = [] + for t in list(zip(sim_configs, list(range(len(sim_configs))))): + sim_config = t[0] + N = sim_config['N'] + + if N > 1: + for n in range(N): + sim_config['simulation_id'] = simulation_id + sim_cnt + sim_config['run_id'] = n + sim_config['N'] = 1 + # sim_config['N'] = n + 1 + new_sim_configs.append(deepcopy(sim_config)) + del sim_config + else: + sim_config['simulation_id'] = simulation_id + sim_config['run_id'] = 0 + new_sim_configs.append(deepcopy(sim_config)) + # del sim_config + + sim_cnt += 1 + + run_id = 0 + print(self.exp_id) + for sim_config in new_sim_configs: + sim_config['N'] = run_id + 1 + if max_runs == 1: + sim_config['run_id'] = run_id + elif max_runs >= 1: + if run_id >= max_runs: + sim_config['N'] = run_id - (max_runs - 1) + + self.exp_window = deepcopy(self.exp_window) + config = Configuration( + sim_config=sim_config, + initial_state=initial_state, + seeds=seeds, + exogenous_states=exogenous_states, + env_processes=env_processes, + partial_state_update_blocks=partial_state_update_blocks, + policy_ops=policy_ops, + + # session_id=session_id, + user_id=user_id, + session_id=f"{user_id}={sim_config['simulation_id']}_{sim_config['run_id']}", + simulation_id=sim_config['simulation_id'], + # run_id=run_id_config + run_id=sim_config['run_id'], + experiment_id=self.exp_id, + exp_window=self.exp_window + ) + configs.append(config) + run_id += 1 + + # print(exp_cnt) + self.exp_id += 1 + self.exp_window.appendleft(self.exp_id) + # print() + # print(self.exp_id) + + +# def append_configs( +# user_id='cadCAD_user', +# session_id=0, #ToDo: change to string +# sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={}, +# partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], _exo_update_per_ts: bool = True, +# config_list=configs +# ) -> None: +# +# try: +# max_runs = sim_configs[0]['N'] +# except KeyError: +# max_runs = sim_configs['N'] +# +# if _exo_update_per_ts is True: +# exogenous_states = exo_update_per_ts(raw_exogenous_states) +# else: +# exogenous_states = raw_exogenous_states +# +# if isinstance(sim_configs, dict): +# sim_configs = [sim_configs] +# +# simulation_id = 0 +# if len(config_list) > 0: +# last_config = config_list[-1] +# simulation_id = last_config.simulation_id + 1 +# +# sim_cnt = 0 +# new_sim_configs = [] +# for t in list(zip(sim_configs, list(range(len(sim_configs))))): +# sim_config = t[0] +# N = sim_config['N'] +# +# if N > 1: +# for n in range(N): +# sim_config['simulation_id'] = simulation_id + sim_cnt +# sim_config['run_id'] = n +# sim_config['N'] = 1 +# # sim_config['N'] = n + 1 +# new_sim_configs.append(deepcopy(sim_config)) +# del sim_config +# else: +# sim_config['simulation_id'] = simulation_id +# sim_config['run_id'] = 0 +# new_sim_configs.append(deepcopy(sim_config)) +# # del sim_config +# +# sim_cnt += 1 +# +# # print(configs) +# run_id = 0 +# # if len(configs) > 0: +# # ds_run_id = configs[-1].__dict__['run_id'] + 1 +# # # print() +# # # print(configs[-1].__dict__['simulation_id']) +# # # print(configs[-1].__dict__['run_id']) +# # # configs[-1].__dict__['run_id'] +# # # print(configs[-1].__dict__['run_id'] + 1) +# # run_id = ds_run_id + 1 +# +# for sim_config in new_sim_configs: +# sim_config['N'] = run_id + 1 +# if max_runs == 1: +# sim_config['run_id'] = run_id +# elif max_runs >= 1: +# if run_id >= max_runs: +# sim_config['N'] = run_id - (max_runs - 1) +# +# config = Configuration( +# sim_config=sim_config, +# initial_state=initial_state, +# seeds=seeds, +# exogenous_states=exogenous_states, +# env_processes=env_processes, +# partial_state_update_blocks=partial_state_update_blocks, +# policy_ops=policy_ops, +# +# # session_id=session_id, +# user_id=user_id, +# session_id=f"{user_id}={sim_config['simulation_id']}_{sim_config['run_id']}", +# simulation_id=sim_config['simulation_id'], +# # run_id=run_id_config +# run_id=sim_config['run_id'] +# ) +# configs.append(config) +# run_id += 1 +# +# # print(configs) +# # print(f'simulation_id: {configs[-1].__dict__["simulation_id"]}') +# # print(f'run_id: {configs[-1].__dict__["run_id"]}') class Identity: diff --git a/cadCAD/engine/__init__.py b/cadCAD/engine/__init__.py index 901e5622..8c1e27db 100644 --- a/cadCAD/engine/__init__.py +++ b/cadCAD/engine/__init__.py @@ -65,7 +65,7 @@ def execute(self) -> Tuple[Any, Any, Dict[str, Any]]: sessions = [] var_dict_list, states_lists = [], [] - Ts, Ns, SimIDs, RunIDs = [], [], [], [] + Ts, Ns, SimIDs, RunIDs, ExpIDs, ExpWindows = [], [], [], [], [], [] eps, configs_structs, env_processes_list = [], [], [] partial_state_updates, sim_executors = [], [] config_idx = 0 @@ -78,11 +78,16 @@ def execute(self) -> Tuple[Any, Any, Dict[str, Any]]: t1 = time() for x in self.configs: sessions.append( - {'user_id': x.user_id, 'session_id': x.session_id, 'simulation_id': x.simulation_id, 'run_id': x.run_id} + { + 'user_id': x.user_id, 'experiment_id': x.experiment_id, 'session_id': x.session_id, + 'simulation_id': x.simulation_id, 'run_id': x.run_id + } ) Ts.append(x.sim_config['T']) Ns.append(x.sim_config['N']) + ExpIDs.append(x.experiment_id) + ExpWindows.append(x.exp_window) SimIDs.append(x.simulation_id) RunIDs.append(x.run_id) @@ -136,14 +141,15 @@ def auto_mode_switcher(config_amt): print("Execution Method: " + self.exec_method.__name__) simulations_results = self.exec_method( - sim_executors, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, SimIDs, RunIDs #Ns + sim_executors, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, SimIDs, RunIDs, + ExpIDs #Ns ) final_result = get_final_results(simulations_results, partial_state_updates, eps, sessions, remote_threshold) elif self.exec_context == ExecutionMode.distributed: print("Execution Method: " + self.exec_method.__name__) simulations_results = self.exec_method( sim_executors, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, - SimIDs, RunIDs, self.sc + SimIDs, RunIDs, ExpIDs, self.sc ) final_result = get_final_dist_results(simulations_results, partial_state_updates, eps, sessions) diff --git a/cadCAD/engine/execution.py b/cadCAD/engine/execution.py index 9a3d8bd1..93c933ea 100644 --- a/cadCAD/engine/execution.py +++ b/cadCAD/engine/execution.py @@ -20,7 +20,8 @@ def single_proc_exec( env_processes_list: List[EnvProcessesType], Ts: List[range], SimIDs, - Ns: List[int] + Ns: List[int], + ExpIDs: List[int] ): print(f'Execution Mode: single_threaded') params = [simulation_execs, states_lists, configs_structs, env_processes_list, Ts, SimIDs, Ns] @@ -37,13 +38,14 @@ def parallelize_simulations( env_processes_list: List[EnvProcessesType], Ts: List[range], SimIDs, - Ns: List[int] + Ns: List[int], + ExpIDs: List[int] ): # indexed sim_ids # SimIDs = list(range(len(SimIDs))) # print(SimIDs) # print(list(range(len(Ns)))) - print(Ns) + # print(Ns) # exit() print(f'Execution Mode: parallelized') @@ -76,6 +78,12 @@ def parallelize_simulations( configs_structs[count * highest_divisor: (count + 1) * highest_divisor] ) + print(SimIDs) + print(Ns) + print(ExpIDs) + # pprint(new_configs_structs) + # exit() + def threaded_executor(params): # tp = TPool(len_configs_structs) tp = TPool() @@ -96,9 +104,9 @@ def threaded_executor(params): # pprint(params) # print() - # pp = PPool() - results = flatten(list(map(lambda params: threaded_executor(params), new_params))) - # pp.close() + pp = PPool() + results = flatten(list(pp.map(lambda params: threaded_executor(params), new_params))) + pp.close() return results @@ -111,17 +119,20 @@ def local_simulations( env_processes_list: List[EnvProcessesType], Ts: List[range], SimIDs, - Ns: List[int] + Ns: List[int], + ExpIDs: List[int] ): config_amt = len(configs_structs) try: if len(configs_structs) == 1: return single_proc_exec( - simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, SimIDs, Ns + simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, SimIDs, Ns, + ExpIDs ) elif len(configs_structs) > 1 and config_amt < remote_threshold: return parallelize_simulations( - simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, SimIDs, Ns + simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, SimIDs, Ns, + ExpIDs ) except ValueError: print('ValueError: sim_configs\' N must > 0') diff --git a/cadCAD/engine/simulation.py b/cadCAD/engine/simulation.py index be575af4..3ded8288 100644 --- a/cadCAD/engine/simulation.py +++ b/cadCAD/engine/simulation.py @@ -231,13 +231,14 @@ def generate_init_sys_metrics(genesis_states_list, sim_id, _run): # for d in genesis_states_list.asDict(): for D in genesis_states_list: d = deepcopy(D) - print(str(sim_id) + ' ' + ' ' + str(_run)) + # d = D + # print(str(sim_id) + ' ' + ' ' + str(_run)) d['simulation'], d['run'], d['substep'], d['timestep'] = sim_id, _run, 0, 0 # d['simulation'], d['run'], d['substep'], d['timestep'] = _run, sim_id, 0, 0 # print('simulation_id') # print(simulation_id) yield d - print(tuple(states_list)) + # print(tuple(states_list)) states_list_copy: List[Dict[str, Any]] = list(generate_init_sys_metrics(tuple(states_list), simulation_id, run)) # simulation_id = + 1 diff --git a/simulations/regression_tests/experiments/__init__.py b/simulations/regression_tests/experiments/__init__.py new file mode 100644 index 00000000..947ce42d --- /dev/null +++ b/simulations/regression_tests/experiments/__init__.py @@ -0,0 +1,3 @@ +from cadCAD.configuration import Experiment + +exp_a = Experiment() \ No newline at end of file diff --git a/simulations/regression_tests/models/config1.py b/simulations/regression_tests/models/config1.py index 77fd621b..bfc80651 100644 --- a/simulations/regression_tests/models/config1.py +++ b/simulations/regression_tests/models/config1.py @@ -2,8 +2,9 @@ from datetime import timedelta from cadCAD import configs -from cadCAD.configuration import append_configs +# from cadCAD.configuration import append_configs from cadCAD.configuration.utils import bound_norm_random, config_sim, time_step, env_trigger +from simulations.regression_tests.experiments import exp_a seeds = { 'z': np.random.RandomState(1), @@ -148,8 +149,8 @@ def update_timestamp(_g, step, sL, s, _input, **kwargs): } sim_config = config_sim(sim_config_dict) - -append_configs( +# exp_a = Experiment() +exp_a.append_configs( config_list=configs, user_id='user_a', sim_configs=sim_config, @@ -157,4 +158,4 @@ def update_timestamp(_g, step, sL, s, _input, **kwargs): env_processes=env_processes, partial_state_update_blocks=partial_state_update_block, policy_ops=[lambda a, b: a + b] -) \ No newline at end of file +) diff --git a/simulations/regression_tests/models/config2.py b/simulations/regression_tests/models/config2.py index 1827b666..2f66794e 100644 --- a/simulations/regression_tests/models/config2.py +++ b/simulations/regression_tests/models/config2.py @@ -2,8 +2,9 @@ from datetime import timedelta from cadCAD import configs -from cadCAD.configuration import append_configs +# from cadCAD.configuration import append_configs from cadCAD.configuration.utils import bound_norm_random, config_sim, env_trigger, time_step +from simulations.regression_tests.experiments import exp_a seeds = { 'z': np.random.RandomState(1), @@ -139,8 +140,8 @@ def update_timestamp(_g, step, sL, s, _input, **kwargs): sim_config = config_sim(sim_config_dict) - -append_configs( +# exp_a = Experiment() +exp_a.append_configs( config_list=configs, user_id='user_b', sim_configs=sim_config, diff --git a/testing/experiments/__init__.py b/testing/experiments/__init__.py new file mode 100644 index 00000000..a78e6840 --- /dev/null +++ b/testing/experiments/__init__.py @@ -0,0 +1,3 @@ +from cadCAD.configuration import Experiment + +exp_param_sweep = Experiment() \ No newline at end of file diff --git a/testing/models/param_sweep.py b/testing/models/param_sweep.py index e8afea95..b4c1c31c 100644 --- a/testing/models/param_sweep.py +++ b/testing/models/param_sweep.py @@ -1,8 +1,9 @@ import pprint from typing import Dict, List -from cadCAD.configuration import append_configs +# from cadCAD.configuration import append_configs from cadCAD.configuration.utils import env_trigger, var_substep_trigger, config_sim, psub_list +from testing.experiments import exp_param_sweep pp = pprint.PrettyPrinter(indent=4) @@ -75,7 +76,7 @@ def sweeped(_g, step, sL, s, _input, **kwargs): sim_config = config_sim( { - "N": 2, + "N": 1, "T": range(2), "M": g, # Optional } @@ -83,7 +84,7 @@ def sweeped(_g, step, sL, s, _input, **kwargs): # New Convention partial_state_update_blocks = psub_list(psu_block, psu_steps) -append_configs( +exp_param_sweep.append_configs( sim_configs=sim_config, initial_state=genesis_states, env_processes=env_process,