def test_linalg(): for mod in list(sys.modules.keys()): if mod.startswith('pascal_lite'): del sys.modules[mod] import pascal_lite as pascal subspace_dimension = 4 V = pascal.symbolic_array(subspace_dimension) v = pascal.symbolic_array() v1 = pascal.dot(V, v) assert not v1.is_distributed v2 = pascal.outer(v1, v) assert v2.is_distributed v3 = pascal.qr_transpose(V)[0] assert v3.is_distributed g = pascal.ComputationalGraph([v1.value, v2.value, v3.value]) n = 16 A = np.random.rand(subspace_dimension, n) b = np.random.rand(n) def actual_inputs(x): if x is V.value: return A elif x is v.value: return b o1, o2, o3 = g(actual_inputs) assert np.allclose(o1, np.dot(A, b)) assert np.allclose(o2, np.outer(np.dot(A, b), b)) assert np.allclose(o3, np.linalg.qr(A.T)[0].T)
def test_add_mul(): for mod in list(sys.modules.keys()): if mod.startswith('pascal_lite'): del sys.modules[mod] import pascal_lite as pascal subspace_dimension = 16 V = pascal.random(subspace_dimension) V = V.reshape([1, -1]).T.transpose().ravel() v0 = pascal.ones().copy() + pascal.zeros() v1 = pascal.symbolic_array() v2 = pascal.symbolic_array(1) a = np.ones(subspace_dimension) V[1:2] = 1 v3 = -v0 / 2 + (V * a).sum() - 2 * v1 + v2[0] v3 = 0.5 - (-v3) / 2 v3 = -0.5 + v3 v3 *= 2 print(v0, v1, v2, len(v0)) g = pascal.ComputationalGraph([v3.value]) n_for_this_mpi_rank = 100000 actual_inputs = { pascal.builtin.ZERO: np.zeros(n_for_this_mpi_rank), pascal.builtin.RANDOM[0]: np.ones(pascal.builtin.RANDOM[0].shape + (n_for_this_mpi_rank, )), v1.value: np.ones(n_for_this_mpi_rank), v2.value: 2.5 * np.ones(n_for_this_mpi_rank) } actual_output, = g(actual_inputs) assert actual_output.shape == (n_for_this_mpi_rank, ) assert abs(actual_output - subspace_dimension).max() < 1E-12 # a different interface def actual_inputs(x): if x is pascal.builtin.ZERO: return np.zeros(n_for_this_mpi_rank) elif x is pascal.builtin.RANDOM[0]: return np.ones(pascal.builtin.RANDOM[0].shape + (n_for_this_mpi_rank, )) elif x is v1.value: return np.ones(n_for_this_mpi_rank) elif x is v2.value: return 2.5 * np.ones(n_for_this_mpi_rank) actual_output, = g(actual_inputs) assert actual_output.shape == (n_for_this_mpi_rank, ) assert abs(actual_output - subspace_dimension).max() < 1E-12
def shadowing(run, u0, parameter, subspace_dimension, num_segments, steps_per_segment, runup_steps, epsilon=1E-6, checkpoint_path=None, checkpoint_interval=1, simultaneous_runs=None, run_ddt=None, return_checkpoint=False, get_host_dir=None, spawn_compute_job=None): ''' run: a function in the form u1, J = run(u0, parameter, steps, run_id, interprocess) inputs - u0: init solution, a flat numpy array of doubles. parameter: design parameter, a single number. steps: number of time steps, an int. run_id: a unique identifier, a string, e.g., "segment02_init_perturb003". interprocess: a tuple of (lock, dict) for synchronizing between different runs. lock: a multiprocessing.Manager.Lock object. dict: a multiprocessing.Manager.dict object. outputs - u1: final solution, a flat numpy array of doubles, must be of the same size as u0. J: quantities of interest, a numpy array of shape (steps, n_qoi), where n_qoi is an arbitrary but consistent number, # quantities of interest. ''' u0 = pascal.symbolic_array(field=u0) run = RunWrapper(run) manager = Manager() interprocess = (manager.Lock(), manager.dict()) if runup_steps > 0: u0, _ = run(u0.field, parameter, runup_steps, 'runup', interprocess) u0 = pascal.symbolic_array(field=u0) #print u0.field V, v = tangent_initial_condition(subspace_dimension) lss = LssTangent() checkpoint = Checkpoint(u0, V, v, lss, [], [], [], [], []) return continue_shadowing(run, parameter, checkpoint, num_segments, steps_per_segment, epsilon, checkpoint_path, checkpoint_interval, simultaneous_runs, run_ddt, return_checkpoint, get_host_dir, spawn_compute_job)
def test_add_mul(): for mod in list(sys.modules.keys()): if mod.startswith('pascal_lite'): del sys.modules[mod] import pascal_lite as pascal subspace_dimension = 16 V = pascal.random(subspace_dimension) V = V.reshape([1, -1]).T.transpose().ravel() v0 = pascal.ones().copy() + pascal.zeros() v1 = pascal.symbolic_array() v2 = pascal.symbolic_array(1) a = np.ones(subspace_dimension) V[1:2] = 1 v3 = -v0 / 2 + (V * a).sum() - 2 * v1 + v2[0] v3 = 0.5 - (-v3) / 2 v3 = -0.5 + v3 v3 *= 2 print(v0, v1, v2, len(v0)) g = pascal.ComputationalGraph([v3.value]) n_for_this_mpi_rank = 100000 actual_inputs = { pascal.builtin.ZERO: np.zeros(n_for_this_mpi_rank), pascal.builtin.RANDOM[0]: np.ones(pascal.builtin.RANDOM[0].shape + (n_for_this_mpi_rank,)), v1.value: np.ones(n_for_this_mpi_rank), v2.value: 2.5 * np.ones(n_for_this_mpi_rank) } actual_output, = g(actual_inputs) assert actual_output.shape == (n_for_this_mpi_rank,) assert abs(actual_output - subspace_dimension).max() < 1E-12 # a different interface def actual_inputs(x): if x is pascal.builtin.ZERO: return np.zeros(n_for_this_mpi_rank) elif x is pascal.builtin.RANDOM[0]: return np.ones(pascal.builtin.RANDOM[0].shape + (n_for_this_mpi_rank,)) elif x is v1.value: return np.ones(n_for_this_mpi_rank) elif x is v2.value: return 2.5 * np.ones(n_for_this_mpi_rank) actual_output, = g(actual_inputs) assert actual_output.shape == (n_for_this_mpi_rank,) assert abs(actual_output - subspace_dimension).max() < 1E-12
def shadowing( run, u0, parameter, subspace_dimension, num_segments, steps_per_segment, runup_steps, epsilon=1E-6, checkpoint_path=None, checkpoint_interval=1, simultaneous_runs=None, run_ddt=None, return_checkpoint=False, get_host_dir=None, spawn_compute_job=None): ''' run: a function in the form u1, J = run(u0, parameter, steps, run_id, interprocess) inputs - u0: init solution, a flat numpy array of doubles. parameter: design parameter, a single number. steps: number of time steps, an int. run_id: a unique identifier, a string, e.g., "segment02_init_perturb003". interprocess: a tuple of (lock, dict) for synchronizing between different runs. lock: a multiprocessing.Manager.Lock object. dict: a multiprocessing.Manager.dict object. outputs - u1: final solution, a flat numpy array of doubles, must be of the same size as u0. J: quantities of interest, a numpy array of shape (steps, n_qoi), where n_qoi is an arbitrary but consistent number, # quantities of interest. ''' u0 = pascal.symbolic_array(field=u0) run = RunWrapper(run) manager = Manager() interprocess = (manager.Lock(), manager.dict()) if runup_steps > 0: u0, _ = run(u0.field, parameter, runup_steps, 'runup', interprocess) u0 = pascal.symbolic_array(field=u0) #print u0.field V, v = tangent_initial_condition(subspace_dimension) lss = LssTangent() checkpoint = Checkpoint(u0, V, v, lss, [], [], [], [], []) return continue_shadowing( run, parameter, checkpoint, num_segments, steps_per_segment, epsilon, checkpoint_path, checkpoint_interval, simultaneous_runs, run_ddt, return_checkpoint, get_host_dir, spawn_compute_job)
def __init__(self, run, u0, parameter, run_id, simultaneous_runs, interprocess): threads = Pool(simultaneous_runs) res = [] for steps in range(1, self.order_of_accuracy + 1): run_id_steps = run_id + '_{0}steps'.format(steps) res.append(threads.apply_async( run, (u0.field, parameter, steps, run_id_steps, interprocess))) u = [res_i.get()[0] for res_i in res] u = [u0] + [pascal.symbolic_array(field=ui) for ui in u] threads.close() threads.join() self.dxdt = compute_dxdt(u) self.dxdt_normalized = self.dxdt / pascal.norm(self.dxdt)
def __init__(self, run, u0, parameter, run_id, simultaneous_runs, interprocess): threads = Pool(simultaneous_runs) res = [] for steps in range(1, self.order_of_accuracy + 1): run_id_steps = run_id + '_{0}steps'.format(steps) # set_trace() res.append(threads.apply_async( run, (u0.field, parameter, steps, run_id_steps, interprocess))) u = [res_i.get()[0] for res_i in res] u = [u0] + [pascal.symbolic_array(field=ui) for ui in u] threads.close() threads.join() self.dxdt = compute_dxdt(u) self.dxdt_normalized = self.dxdt / pascal.norm(self.dxdt)
def run_segment(run, u0, V, v, parameter, i_segment, steps, epsilon, simultaneous_runs, interprocess, get_host_dir=None, compute_outputs=None, spawn_compute_job=None): ''' Run Time Segement i_segment, starting from u0: nonlinear solution V: homogeneous tangents v: inhomogeneous tangent for steps time steps, and returns afterwards u0: nonlinear solution V: homogeneous tangents v: inhomogeneous tangent J0: history of quantities of interest for the nonlinear solution G: sensitivities of the homogeneous tangents g: sensitivity of the inhomogeneous tangent ''' if get_host_dir is None: get_host_dir = lambda x: x if compute_outputs is None: compute_outputs = [] threads = Pool(simultaneous_runs) run_id = 'segment{0:02d}_baseline'.format(i_segment) # run homogeneous tangents res_h = [] subspace_dimension = len(V) u1i = u0 + v * epsilon run_ids = [ 'segment{0:02d}_param_perturb{1:03d}'.format(i_segment, subspace_dimension) ] u1i.value.field = os.path.join(get_host_dir(run_ids[0]), 'input.h5') u1h = [] for j in range(subspace_dimension): u1h.append(u0 + V[j] * epsilon) run_ids.append('segment{0:02d}_init_perturb{1:03d}'.format( i_segment, j)) u1h[-1].value.field = os.path.join(get_host_dir(run_ids[-1]), 'input.h5') # compute all outputs run_compute([u1i] + u1h + compute_outputs, spawn_compute_job=spawn_compute_job, interprocess=interprocess) res_0 = threads.apply_async( run, (u0.field, parameter, steps, run_id, interprocess)) for j in range(subspace_dimension): res_h.append( threads.apply_async(run, (u1h[j].field, parameter, steps, run_ids[1 + j], interprocess))) # run inhomogeneous tangent res_i = threads.apply_async( run, (u1i.field, parameter + epsilon, steps, run_ids[0], interprocess)) u0p, J0 = res_0.get() u0p = pascal.symbolic_array(field=u0p) # get homogeneous tangents G = [] V = pascal.random(subspace_dimension) for j in range(subspace_dimension): u1p, J1 = res_h[j].get() u1p = pascal.symbolic_array(field=u1p) V[j] = (u1p - u0p) / epsilon G.append(trapez_mean(J1 - J0, 0) / epsilon) # get inhomogeneous tangent u1p, J1 = res_i.get() u1p = pascal.symbolic_array(field=u1p) v, g = (u1p - u0p) / epsilon, trapez_mean(J1 - J0, 0) / epsilon threads.close() threads.join() return u0p, V, v, J0, G, g