def verify(inputs, outputs, in_vals=1., out_vals=1., pathnames=False, comm=None, final=True, rank=None): global_shape = (size, ) if final else 'Unavailable' inputs = sorted(inputs) outputs = sorted(outputs) with multi_proc_exception_check(comm): if comm is not None: sizes, offsets = evenly_distrib_idxs(comm.size, size) local_size = sizes[comm.rank] else: local_size = size if rank is None or comm is None or rank == comm.rank: test.assertEqual(len(inputs), 1) name, meta = inputs[0] test.assertEqual(name, 'C2.invec' if pathnames else 'invec') test.assertEqual(meta['shape'], (local_size,)) test.assertEqual(meta['global_shape'], global_shape) test.assertTrue(all(meta['val'] == in_vals*np.ones(size))) test.assertEqual(len(outputs), 1) name, meta = outputs[0] test.assertEqual(name, 'C2.outvec' if pathnames else 'outvec') test.assertEqual(meta['shape'], (local_size,)) test.assertEqual(meta['global_shape'], global_shape) test.assertTrue(all(meta['val'] == out_vals*np.ones(size)))
def verify(inputs, outputs, full_size, loc_size, in_vals=1., out_vals=1., pathnames=False, rank=None): inputs = sorted(inputs) outputs = sorted(outputs) with multi_proc_exception_check(p.comm): if rank is None or p.comm.rank == rank: test.assertEqual(len(inputs), 1) name, meta = inputs[0] test.assertEqual(name, 'C2.invec' if pathnames else 'invec') test.assertTrue(meta['shape'] == (loc_size, )) test.assertEqual(meta['val'].size, full_size) test.assertTrue( all(meta['val'] == in_vals * np.ones(full_size))) test.assertEqual(len(outputs), 1) name, meta = outputs[0] test.assertEqual(name, 'C2.outvec' if pathnames else 'outvec') test.assertTrue(meta['shape'] == (loc_size, )) test.assertTrue( all(meta['val'] == out_vals * np.ones(full_size)))
def test_distributed_array_list_vars(self): size = 100 # how many items in the array prob = om.Problem() prob.model.add_subsystem('des_vars', om.IndepVarComp('x', np.ones(size)), promotes=['x']) prob.model.add_subsystem('plus', DistributedAdder(size=size), promotes=['x', 'y']) prob.model.add_subsystem('summer', Summer(size=size), promotes_outputs=['sum']) prob.model.promotes('summer', inputs=[('invec', 'y')], src_indices=om.slicer[:]) prob.setup(force_alloc_complex=True) # force complex array storage to detect mpi bug prob['x'] = np.arange(size) prob.run_driver() stream = StringIO() with multi_proc_exception_check(prob.comm): inputs = sorted(prob.model.list_inputs(values=True, print_arrays=True, out_stream=stream)) if prob.comm.rank: self.assertEqual(inputs, []) else: self.assertEqual(inputs[0][0], 'plus.x') self.assertEqual(inputs[1][0], 'summer.invec') self.assertEqual(inputs[0][1]['val'].size, 100) self.assertEqual(inputs[1][1]['val'].size, 100) text = stream.getvalue() if prob.comm.rank: # Only rank 0 prints self.assertEqual(len(text), 0) else: self.assertEqual(text.count('val'), 3) self.assertEqual(text.count('\nplus'), 1) self.assertEqual(text.count('\n x'), 1) self.assertEqual(text.count('\nsummer'), 1) self.assertEqual(text.count('\n invec'), 1) # make sure all the arrays written have 100 elements in them self.assertEqual(len(text.split('[')[1].split(']')[0].split()), 100) self.assertEqual(len(text.split('[')[2].split(']')[0].split()), 100) stream = StringIO() with multi_proc_exception_check(prob.comm): outputs = sorted(prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=True, out_stream=stream)) if prob.comm.rank: self.assertEqual(outputs, []) else: self.assertEqual(outputs[0][0], 'des_vars.x') self.assertEqual(outputs[1][0], 'plus.y') self.assertEqual(outputs[2][0], 'summer.sum') self.assertEqual(outputs[0][1]['val'].size, 100) self.assertEqual(outputs[1][1]['val'].size, 100) self.assertEqual(outputs[2][1]['val'].size, 1) text = stream.getvalue() if prob.comm.rank: # Only rank 0 prints self.assertEqual(len(text), 0) else: self.assertEqual(text.count('val'), 3) self.assertEqual(text.count('\ndes_vars'), 1) self.assertEqual(text.count('\n x'), 1) self.assertEqual(text.count('\nplus'), 1) self.assertEqual(text.count('\n y'), 1) self.assertEqual(text.count('\nsummer'), 1) self.assertEqual(text.count('\n sum'), 1) # make sure all the arrays written have 100 elements in them self.assertEqual(len(text.split('[')[1].split(']')[0].split()), 100) self.assertEqual(len(text.split('[')[2].split(']')[0].split()), 100) self.assertEqual(len(text.split('[')[3].split(']')[0].split()), 100) self.assertEqual(len(text.split('[')[4].split(']')[0].split()), 100)
def test_parallel_list_vars(self): print_opts = {'linewidth': 1024, 'precision': 1} if LooseVersion(np.__version__) >= LooseVersion("1.14"): print_opts['legacy'] = '1.13' prob = om.Problem(FanOutGrouped()) # add another subsystem with similar prefix prob.model.add_subsystem('sub2', om.ExecComp(['y=x'])) prob.model.connect('iv.x', 'sub2.x') prob.setup() prob.run_model() # # list inputs, not hierarchical # stream = StringIO() with printoptions(**print_opts): prob.model.list_inputs(values=True, hierarchical=False, out_stream=stream) with multi_proc_exception_check(prob.comm): if prob.comm.rank == 0: # Only rank 0 prints text = stream.getvalue().split('\n') expected = [ "6 Input(s) in 'model'", '', 'varname val', '-------- -----', 'c1.x', 'sub.c2.x', 'sub.c3.x', 'c2.x', 'c3.x', 'sub2.x' ] for i, line in enumerate(expected): if line and not line.startswith('-'): self.assertTrue(text[i].startswith(line), '\nExpected: %s\nReceived: %s\n' % (line, text[i])) # # list inputs, hierarchical # stream = StringIO() with printoptions(**print_opts): prob.model.list_inputs(values=True, hierarchical=True, out_stream=stream) with multi_proc_exception_check(prob.comm): if prob.comm.rank == 0: text = stream.getvalue().split('\n') expected = [ "6 Input(s) in 'model'", '', 'varname val', '------- -----', 'c1', ' x', 'sub', ' c2', ' x', ' c3', ' x', 'c2', ' x', 'c3', ' x', 'sub2', ' x' ] for i, line in enumerate(expected): if line and not line.startswith('-'): self.assertTrue(text[i].startswith(line), '\nExpected: %s\nReceived: %s\n' % (line, text[i])) # # list outputs, not hierarchical # stream = StringIO() with printoptions(**print_opts): prob.model.list_outputs(values=True, residuals=True, hierarchical=False, out_stream=stream) with multi_proc_exception_check(prob.comm): if prob.comm.rank == 0: text = stream.getvalue().split('\n') expected = [ "7 Explicit Output(s) in 'model'", '', 'varname val resids', '-------- ---- ------', 'iv.x', 'c1.y', 'sub.c2.y', 'sub.c3.y', 'c2.y', 'c3.y', 'sub2.y', '', '', "0 Implicit Output(s) in 'model'", ] for i, line in enumerate(expected): if line and not line.startswith('-'): self.assertTrue(text[i].startswith(line), '\nExpected: %s\nReceived: %s\n' % (line, text[i])) # # list outputs, hierarchical # stream = StringIO() with printoptions(**print_opts): prob.model.list_outputs(values=True, residuals=True, hierarchical=True, out_stream=stream) with multi_proc_exception_check(prob.comm): if prob.comm.rank == 0: text = stream.getvalue().split('\n') expected = [ "7 Explicit Output(s) in 'model'", '', 'varname val resids', '------- ----- ------', 'iv', ' x', 'c1', ' y', 'sub', ' c2', ' y', ' c3', ' y', 'c2', ' y', 'c3', ' y', 'sub2', ' y', '', '', "0 Implicit Output(s) in 'model'", ] for i, line in enumerate(expected): if line and not line.startswith('-'): self.assertTrue(text[i].startswith(line), '\nExpected: %s\nReceived: %s\n' % (line, text[i]))
def test_distributed_list_vars(self): from openmdao.utils.general_utils import set_pyoptsparse_opt # check that pyoptsparse is installed. if it is, try to use SLSQP. OPT, OPTIMIZER = set_pyoptsparse_opt('SLSQP') if OPTIMIZER: from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver else: raise unittest.SkipTest("pyOptSparseDriver is required.") class Mygroup(om.Group): def setup(self): self.add_subsystem('indep_var_comp', om.IndepVarComp('x'), promotes=['*']) self.add_subsystem('Cy', om.ExecComp('y=2*x'), promotes=['*']) self.add_subsystem('Cc', om.ExecComp('c=x+2'), promotes=['*']) self.add_design_var('x') self.add_constraint('c', lower=-3.) prob = om.Problem() prob.model.add_subsystem('par', om.ParallelGroup()) prob.model.par.add_subsystem('G1', Mygroup()) prob.model.par.add_subsystem('G2', Mygroup()) prob.model.add_subsystem('Obj', om.ExecComp('obj=y1+y2')) prob.model.connect('par.G1.y', 'Obj.y1') prob.model.connect('par.G2.y', 'Obj.y2') prob.model.add_objective('Obj.obj') prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.setup() prob.run_driver() prob.cleanup() stream = StringIO() with multi_proc_exception_check(prob.comm): inputs = sorted(prob.model.list_inputs(values=True, print_arrays=True, out_stream=stream)) if prob.comm.rank: self.assertEqual(inputs, []) else: inames = [t[0] for t in inputs] self.assertEqual(inames, ['Obj.y1', 'Obj.y2', 'par.G1.Cc.x', 'par.G1.Cy.x', 'par.G2.Cc.x', 'par.G2.Cy.x']) self.assertTrue('val' in inputs[0][1]) text = stream.getvalue() if prob.comm.rank: # Only rank 0 prints self.assertEqual(len(text), 0) else: self.assertEqual(1, text.count("6 Input(s) in 'model'"), 1) self.assertEqual(1, text.count('val')) self.assertEqual(1, text.count('par')) self.assertEqual(1, text.count(' G1')) self.assertEqual(1, text.count(' G2')) self.assertEqual(2, text.count(' Cy')) self.assertEqual(2, text.count(' Cc')) self.assertEqual(4, text.count(' x')) self.assertEqual(1, text.count('Obj')) self.assertEqual(1, text.count(' y1')) self.assertEqual(1, text.count(' y2')) stream = StringIO() with multi_proc_exception_check(prob.comm): outputs = sorted(prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=True, out_stream=stream)) onames = [t[0] for t in outputs] if prob.comm.rank == 0: self.assertEqual(onames, ['Obj.obj', 'par.G1.Cc.c', 'par.G1.Cy.y', 'par.G1.indep_var_comp.x', 'par.G2.Cc.c', 'par.G2.Cy.y', 'par.G2.indep_var_comp.x']) self.assertTrue('val' in outputs[0][1]) self.assertTrue('units' in outputs[0][1]) else: self.assertEqual(onames, []) text = stream.getvalue() if prob.comm.rank: # Only rank 0 prints self.assertEqual(len(text), 0) else: self.assertEqual(1, text.count("7 Explicit Output(s) in 'model'")) self.assertEqual(1, text.count('val')) self.assertEqual(1, text.count('units')) self.assertEqual(1, text.count('par')) self.assertEqual(1, text.count(' G1')) self.assertEqual(1, text.count(' G2')) self.assertEqual(2, text.count(' Cy')) self.assertEqual(2, text.count(' Cc')) self.assertEqual(2, text.count(' indep_var_comp')) self.assertEqual(2, text.count(' x')) self.assertEqual(2, text.count(' y')) self.assertEqual(2, text.count(' c')) self.assertEqual(1, text.count('Obj')) self.assertEqual(1, text.count(' obj'))
def _inverse(self): """ Return the inverse Jacobian. This is only used by the Broyden solver when calculating a full model Jacobian. Since it is only done for a single RHS, no need for LU. Returns ------- ndarray Inverse Jacobian. """ system = self._system iproc = system.comm.rank nproc = system.comm.size if self._assembled_jac is not None: with multi_proc_exception_check( system.comm) if nproc > 1 else do_nothing_context(): if nproc == 1: matrix = self._assembled_jac._int_mtx._matrix else: matrix = self._assembled_jac._int_mtx._get_assembled_matrix( system) if self._owned_size_totals is None: self._owned_size_totals = np.sum(system._owned_sizes, axis=1) if matrix is None: # This happens if we're not rank 0 sz = np.sum(system._owned_sizes) inv_jac = np.zeros((sz, sz)) # Dense and Sparse matrices have their own inverse method. elif isinstance(matrix, np.ndarray): # Detect singularities and warn user. with warnings.catch_warnings(): if self.options['err_on_singular']: warnings.simplefilter('error', RuntimeWarning) try: inv_jac = scipy.linalg.inv(matrix) except RuntimeWarning as err: raise RuntimeError( format_singular_error(err, system, matrix)) # NaN in matrix. except ValueError as err: raise RuntimeError(format_nan_error( system, matrix)) elif isinstance(matrix, csc_matrix): try: inv_jac = scipy.sparse.linalg.inv(matrix) except RuntimeError as err: if 'exactly singular' in str(err): raise RuntimeError( format_singular_csc_error(system, matrix)) else: reraise(*sys.exc_info()) else: raise RuntimeError( "Direct solver not implemented for matrix type %s" " in %s." % (type(matrix), system.msginfo)) else: mtx = self._build_mtx() # During inversion detect singularities and warn user. with warnings.catch_warnings(): if self.options['err_on_singular']: warnings.simplefilter('error', RuntimeWarning) try: inv_jac = scipy.linalg.inv(mtx) except RuntimeWarning as err: raise RuntimeError(format_singular_error(err, system, mtx)) # NaN in matrix. except ValueError as err: raise RuntimeError(format_nan_error(system, mtx)) return inv_jac
def _linearize(self): """ Perform factorization. """ system = self._system nproc = system.comm.size if self._assembled_jac is not None: with multi_proc_exception_check( system.comm) if nproc > 1 else do_nothing_context(): if nproc == 1: matrix = self._assembled_jac._int_mtx._matrix else: matrix = self._assembled_jac._int_mtx._get_assembled_matrix( system) if self._owned_size_totals is None: self._owned_size_totals = np.sum(system._owned_sizes, axis=1) if matrix is None: # this happens if we're not rank 0 self._lu = self._lup = None self._nodup_size = np.sum(system._owned_sizes) # Perform dense or sparse lu factorization. elif isinstance(matrix, csc_matrix): try: self._lu = scipy.sparse.linalg.splu(matrix) self._nodup_size = matrix.shape[1] except RuntimeError as err: if 'exactly singular' in str(err): raise RuntimeError( format_singular_csc_error(system, matrix)) else: reraise(*sys.exc_info()) elif isinstance(matrix, np.ndarray): # dense # During LU decomposition, detect singularities and warn user. with warnings.catch_warnings(): if self.options['err_on_singular']: warnings.simplefilter('error', RuntimeWarning) try: self._lup = scipy.linalg.lu_factor(matrix) self._nodup_size = matrix.shape[1] except RuntimeWarning as err: raise RuntimeError( format_singular_error(err, system, matrix)) # NaN in matrix. except ValueError as err: raise RuntimeError(format_nan_error( system, matrix)) # Note: calling scipy.sparse.linalg.splu on a COO actually transposes # the matrix during conversion to csc prior to LU decomp, so we can't use COO. else: raise RuntimeError( "Direct solver not implemented for matrix type %s" " in %s." % (type(self._assembled_jac._int_mtx), system.msginfo)) else: if nproc > 1: raise RuntimeError( "DirectSolvers without an assembled jacobian are not supported " "when running under MPI if comm.size > 1.") mtx = self._build_mtx() self._nodup_size = mtx.shape[1] # During LU decomposition, detect singularities and warn user. with warnings.catch_warnings(): if self.options['err_on_singular']: warnings.simplefilter('error', RuntimeWarning) try: self._lup = scipy.linalg.lu_factor(mtx) except RuntimeWarning as err: raise RuntimeError(format_singular_error(err, system, mtx)) # NaN in matrix. except ValueError as err: raise RuntimeError(format_nan_error(system, mtx))