예제 #1
0
def get_sparsity(problem,
                 mode='fwd',
                 repeats=1,
                 tol=1.e-15,
                 show_jac=False,
                 setup=False,
                 run_model=False,
                 stream=sys.stdout):
    """
    Compute derivative sparsity for the given problem.

    Parameters
    ----------
    problem : Problem
        The Problem being analyzed.
    mode : str
        Derivative direction.
    repeats : int
        Number of times to repeat total jacobian computation.
    tol : float
        Tolerance used to determine if an array entry is nonzero.
    show_jac : bool
        If True, display a visualization of the final total jacobian used to compute the coloring.
    stream : file-like or None
        Stream where output coloring info will be written.
    setup : bool
        If True, run setup before calling compute_totals.
    run_model : bool
        If True, run run_model before calling compute_totals.

    Returns
    -------
    dict
        A nested dict specifying subjac sparsity for each total deriv, e.g., sparsity[resp][dv].
    """
    driver = problem.driver

    J = _get_bool_jac(problem,
                      mode=mode,
                      repeats=repeats,
                      tol=tol,
                      setup=setup,
                      run_model=run_model)

    of = driver._get_ordered_nl_responses()
    wrt = list(driver._designvars)

    sparsity = _sparsity_from_jac(J, of, wrt, driver)

    driver._total_jac = None

    if stream is not None:
        _write_sparsity(sparsity, stream)
        stream.write("\n")

        if show_jac and stream is not None:
            stream.write("\n\n")
            array_viz(J, problem, of, wrt, stream)

    return sparsity
예제 #2
0
    def show(self, stream=sys.stdout):
        array_viz(self.J)

        maxdeg_fwd = np.max(np.count_nonzero(self.J, axis=1))
        maxdeg_rev = np.max(np.count_nonzero(self.J, axis=0))

        print("Shape:", self.J.shape, file=stream)
        print("Density:", np.count_nonzero(self.J) / self.J.size)
        print("Max degree (fwd, rev):", maxdeg_fwd, maxdeg_rev)

        simul_coloring_summary(self.J, self.coloring, stream=stream)
예제 #3
0
    def show(self, stream=sys.stdout):
        array_viz(self.J)

        maxdeg_fwd = np.max(np.count_nonzero(self.J, axis=1))
        maxdeg_rev = np.max(np.count_nonzero(self.J, axis=0))

        print("Shape:", self.J.shape, file=stream)
        print("Density:", np.count_nonzero(self.J) / self.J.size)
        print("Max degree (fwd, rev):", maxdeg_fwd, maxdeg_rev)

        simul_coloring_summary(self.J, self.coloring, stream=stream)
예제 #4
0
def get_sparsity(problem, mode='fwd', repeats=1, tol=1.e-15, show_jac=False,
                 setup=False, run_model=False, stream=sys.stdout):
    """
    Compute derivative sparsity for the given problem.

    Parameters
    ----------
    problem : Problem
        The Problem being analyzed.
    mode : str
        Derivative direction.
    repeats : int
        Number of times to repeat total jacobian computation.
    tol : float
        Tolerance used to determine if an array entry is nonzero.
    show_jac : bool
        If True, display a visualization of the final total jacobian used to compute the coloring.
    stream : file-like or None
        Stream where output coloring info will be written.
    setup : bool
        If True, run setup before calling compute_totals.
    run_model : bool
        If True, run run_model before calling compute_totals.

    Returns
    -------
    dict
        A nested dict specifying subjac sparsity for each total deriv, e.g., sparsity[resp][dv].
    """
    driver = problem.driver

    J = _get_bool_jac(problem, repeats=repeats, tol=tol, setup=setup,
                      run_model=run_model)

    of = driver._get_ordered_nl_responses()
    wrt = list(driver._designvars)

    sparsity = _sparsity_from_jac(J, of, wrt, driver)

    driver._total_jac = None

    if stream is not None:
        _write_sparsity(sparsity, stream)
        stream.write("\n")

        if show_jac and stream is not None:
            stream.write("\n\n")
            array_viz(J, problem, of, wrt, stream)

    return sparsity
예제 #5
0
 def show(self, stream=sys.stdout):
     array_viz(self.J)
     print("Shape:", self.J.shape, file=stream)
     print("Density:", np.count_nonzero(self.J) / self.J.size)
     tup = _solves_info(self.coloring)
     dominant_mode = tup[-1]
     if dominant_mode == 'fwd':
         if 'rev' in self.coloring:
             opp_rows = self.coloring['rev'][0][0]
             Jcopy = self.J.copy()
             Jcopy[opp_rows] = False
         else:
             Jcopy = self.J
         maxdeg = np.max(np.count_nonzero(Jcopy, axis=1))
     else:
         if 'fwd' in self.coloring:
             opp_cols = self.coloring['fwd'][0][0]
             Jcopy = self.J.copy()
             Jcopy[:, opp_cols] = False
         else:
             Jcopy = self.J
         maxdeg = np.max(np.count_nonzero(Jcopy, axis=0))
     print("Max degree:", maxdeg)
     simul_coloring_summary(self.coloring, stream=stream)
예제 #6
0
def get_simul_meta(problem,
                   mode='fwd',
                   repeats=1,
                   tol=1.e-15,
                   show_jac=False,
                   include_sparsity=True,
                   setup=False,
                   run_model=False,
                   stream=sys.stdout):
    """
    Compute simultaneous derivative colorings for the given problem.

    Parameters
    ----------
    problem : Problem
        The Problem being analyzed.
    mode : str
        Derivative direction.
    repeats : int
        Number of times to repeat total jacobian computation.
    tol : float
        Tolerance used to determine if an array entry is nonzero.
    show_jac : bool
        If True, display a visualiation of the final total jacobian used to compute the coloring.
    include_sparsity : bool
        If True, include the sparsity structure of the total jacobian mapped to design vars
        and responses.  (This info is used by pyOptSparseDriver).
    setup : bool
        If True, run setup before calling compute_totals.
    run_model : bool
        If True, run run_model before calling compute_totals.
    stream : file-like or None
        Stream where output coloring info will be written.

    Returns
    -------
    tuple of the form (col_lists, row_maps, sparsity)
        col_lists is a list of column lists, where the first list is the list of uncolored columns.
        row_maps is a list of nonzero rows for each column, or None for uncolored columns.
        sparsity is a nested dict specifying subjac sparsity for each total derivative, or None.
    """
    driver = problem.driver

    # TODO: fix this to work in rev mode as well
    assert mode == 'fwd', "Simultaneous derivatives are currently supported only in fwd mode."

    J = _get_bool_jac(problem,
                      mode=mode,
                      repeats=repeats,
                      tol=tol,
                      setup=setup,
                      run_model=run_model)

    full_disjoint, rows = _find_global_disjoint(problem, J)
    uncolored_cols = [i for i, r in enumerate(rows) if r is None]

    # the first col_list entry corresponds to all uncolored columns (columns that are not disjoint
    # wrt any other columns).  The other entries are groups of columns that do not share any
    # nonzero row entries in common.
    col_lists = [uncolored_cols]
    col_lists.extend(full_disjoint)

    sparsity = None
    if include_sparsity or (show_jac and stream is not None):
        of = driver._get_ordered_nl_responses()
        wrt = list(driver._designvars)

    if include_sparsity:
        sparsity = _sparsity_from_jac(J, of, wrt, driver)

    driver._total_jac = None

    if stream is not None:
        if stream.isatty():
            stream.write(
                "\n########### BEGIN COLORING DATA ################\n")
            _write_coloring(col_lists, rows, sparsity, stream)
            stream.write("\n########### END COLORING DATA ############\n")
        else:
            _write_coloring(col_lists, rows, sparsity, stream)

        if show_jac:
            s = stream if stream.isatty() else sys.stdout
            s.write("\n\n")
            array_viz(J, problem, of, wrt, s)

    return col_lists, rows, sparsity
예제 #7
0
def get_simul_meta(problem,
                   mode='fwd',
                   repeats=1,
                   tol=1.e-30,
                   show_jac=False,
                   stream=sys.stdout):
    """
    Compute simultaneous derivative colorings for the given problem.

    Parameters
    ----------
    problem : Problem
        The Problem being analyzed.
    mode : str
        Derivative direction.
    repeats : int
        Number of times to repeat total jacobian computation.
    tol : float
        Tolerance used to determine if an array entry is nonzero.
    show_jac : bool
        If True, display a visualiation of the final total jacobian used to compute the coloring.
    stream : file-like or None
        Stream where output coloring info will be written.

    Returns
    -------
    tuple of the form (simul_colorings, simul_maps)
        Where simul_colorings is a dict of the form {dvname1: coloring_array, ...} and
        simul_maps is a dict of the form
        {resp_name: {dvname: {color: (row_idxs, col_idxs), ...}, ...}, ...}
    """
    driver = problem.driver

    dv_idxs, res_idxs, J = _find_disjoint(problem,
                                          mode=mode,
                                          tol=tol,
                                          repeats=repeats)
    all_colors = set()

    simul_colorings = {}
    simul_maps = {}

    for dv in dv_idxs:
        # negative colors will be iterated over individually, so start by filling the coloring array
        # with -1.  We then replace specific entries with positive colors which will be iterated
        # over as a group.
        coloring = np.full(driver._designvars[dv]['size'], -1, dtype=int)

        for color in dv_idxs[dv]:
            coloring[np.array(dv_idxs[dv][color], dtype=int)] = color
            all_colors.add(color)

        if np.any(coloring != -1):
            # need int conversion to avoid JSON serialization error
            simul_colorings[dv] = [int(c) for c in coloring]

    simul_colorings = OrderedDict(sorted(simul_colorings.items()))

    for res in res_idxs:
        simul_map = {}
        for dv in res_idxs[res]:
            simul_map[dv] = {
                c: v
                for c, v in iteritems(res_idxs[res][dv]) if c in all_colors
            }
            if not simul_map[dv]:
                del simul_map[dv]

        if simul_map:
            simul_maps[res] = OrderedDict(sorted(simul_map.items()))

    simul_maps = OrderedDict(sorted(simul_maps.items()))

    if stream is not None:
        if stream.isatty():
            stream.write("\n({\n")
            for n, coloring in iteritems(simul_colorings):
                stream.write("   '%s': %s,\n" % (n, coloring))
            stream.write("},")

            stream.write("\n{\n")
            for res, dvdict in iteritems(simul_maps):
                stream.write("   '%s': {\n" % res)
                for dv, coldict in iteritems(dvdict):
                    stream.write("      '%s': {\n" % dv)
                    for color, idxs in iteritems(coldict):
                        stream.write("         %s: %s,\n" % (color, idxs))
                    stream.write("      },\n")
                stream.write("   },\n")
            stream.write("})")
        else:  # output json format to a file
            s = json.dumps((simul_colorings, simul_maps))

            # do a little pretty printing since the built-in json pretty printing stretches
            # the output vertically WAY too much.
            s = s.replace(',"', ',\n"')
            s = s.replace(', "', ',\n"')
            s = s.replace('{"', '{\n"')
            s = s.replace(', {', ',\n{')
            s = s.replace(']}', ']\n}')
            s = s.replace('{}', '{\n}')
            s = s.replace('}}', '}\n}')
            s = s.replace('[{', '[\n{')
            s = s.replace(' {', '\n{')

            lines = []
            indent = 0
            for line in s.split('\n'):
                start = line[0] if len(line) > 0 else ''
                if start in ('{', '['):
                    tab = ' ' * indent
                    indent += 3
                elif start in ('}', ']'):
                    indent -= 3
                    tab = ' ' * indent
                else:
                    tab = ' ' * indent

                lines.append("%s%s" % (tab, line))

            stream.write('\n'.join(lines))
            stream.write("\n")

    if show_jac and stream is not None:
        of = list(driver._objs)
        of.extend([
            c for c, meta in iteritems(driver._cons)
            if not ('linear' in meta and meta['linear'])
        ])
        wrt = list(driver._designvars)

        stream.write("\n\n")
        array_viz(J, problem, of, wrt, stream)

    return simul_colorings, simul_maps
예제 #8
0
파일: coloring.py 프로젝트: samtx/OpenMDAO
def get_simul_meta(problem, mode='fwd', repeats=1, tol=1.e-30, show_jac=False, stream=sys.stdout):
    """
    Compute simultaneous derivative colorings for the given problem.

    Parameters
    ----------
    problem : Problem
        The Problem being analyzed.
    mode : str
        Derivative direction.
    repeats : int
        Number of times to repeat total jacobian computation.
    tol : float
        Tolerance used to determine if an array entry is nonzero.
    show_jac : bool
        If True, display a visualiation of the final total jacobian used to compute the coloring.
    stream : file-like or None
        Stream where output coloring info will be written.

    Returns
    -------
    tuple of the form (simul_colorings, simul_maps)
        Where simul_colorings is a dict of the form {dvname1: coloring_array, ...} and
        simul_maps is a dict of the form
        {resp_name: {dvname: {color: (row_idxs, col_idxs), ...}, ...}, ...}
    """
    driver = problem.driver

    dv_idxs, res_idxs, J = _find_disjoint(problem, mode=mode, tol=tol, repeats=repeats)
    all_colors = set()

    simul_colorings = {}
    simul_maps = {}

    for dv in dv_idxs:
        # negative colors will be iterated over individually, so start by filling the coloring array
        # with -1.  We then replace specific entries with positive colors which will be iterated
        # over as a group.
        coloring = np.full(driver._designvars[dv]['size'], -1)

        for color in dv_idxs[dv]:
            coloring[np.array(dv_idxs[dv][color], dtype=int)] = color
            all_colors.add(color)

        if np.any(coloring != -1):
            simul_colorings[dv] = list(coloring)

    simul_colorings = OrderedDict(sorted(simul_colorings.items()))

    for res in res_idxs:
        simul_map = {}
        for dv in res_idxs[res]:
            simul_map[dv] = {c: v for c, v in iteritems(res_idxs[res][dv])
                             if c in all_colors}
            if not simul_map[dv]:
                del simul_map[dv]

        if simul_map:
            simul_maps[res] = OrderedDict(sorted(simul_map.items()))

    simul_maps = OrderedDict(sorted(simul_maps.items()))

    if stream is not None:
        if stream.isatty():
            stream.write("\n({\n")
            for n, coloring in iteritems(simul_colorings):
                stream.write("   '%s': %s,\n" % (n, coloring))
            stream.write("},")

            stream.write("\n{\n")
            for res, dvdict in iteritems(simul_maps):
                stream.write("   '%s': {\n" % res)
                for dv, coldict in iteritems(dvdict):
                    stream.write("      '%s': {\n" % dv)
                    for color, idxs in iteritems(coldict):
                        stream.write("         %s: %s,\n" % (color, idxs))
                    stream.write("      },\n")
                stream.write("   },\n")
            stream.write("})")
        else:  # output json format to a file
            s = json.dumps((simul_colorings, simul_maps))

            # do a little pretty printing since the built-in json pretty printing stretches
            # the output vertically WAY too much.
            s = s.replace(',"', ',\n"')
            s = s.replace(', "', ',\n"')
            s = s.replace('{"', '{\n"')
            s = s.replace(', {', ',\n{')
            s = s.replace(']}', ']\n}')
            s = s.replace('{}', '{\n}')
            s = s.replace('}}', '}\n}')
            s = s.replace('[{', '[\n{')
            s = s.replace(' {', '\n{')

            lines = []
            indent = 0
            for line in s.split('\n'):
                start = line[0] if len(line) > 0 else ''
                if start in ('{', '['):
                    tab = ' ' * indent
                    indent += 3
                elif start in ('}', ']'):
                    indent -= 3
                    tab = ' ' * indent
                else:
                    tab = ' ' * indent

                lines.append("%s%s" % (tab, line))

            stream.write('\n'.join(lines))
            stream.write("\n")

    if show_jac and stream is not None:
        of = list(driver._objs)
        of.extend([c for c, meta in iteritems(driver._cons)
                   if not ('linear' in meta and meta['linear'])])
        wrt = list(driver._designvars)

        stream.write("\n\n")
        array_viz(J, problem, of, wrt, stream)

    return simul_colorings, simul_maps
예제 #9
0
def get_simul_meta(problem, mode='fwd', repeats=1, tol=1.e-15, show_jac=False,
                   include_sparsity=True, setup=False, run_model=False, stream=sys.stdout):
    """
    Compute simultaneous derivative colorings for the given problem.

    Parameters
    ----------
    problem : Problem
        The Problem being analyzed.
    mode : str
        Derivative direction.
    repeats : int
        Number of times to repeat total jacobian computation.
    tol : float
        Tolerance used to determine if an array entry is nonzero.
    show_jac : bool
        If True, display a visualiation of the final total jacobian used to compute the coloring.
    include_sparsity : bool
        If True, include the sparsity structure of the total jacobian mapped to design vars
        and responses.  (This info is used by pyOptSparseDriver).
    setup : bool
        If True, run setup before calling compute_totals.
    run_model : bool
        If True, run run_model before calling compute_totals.
    stream : file-like or None
        Stream where output coloring info will be written.

    Returns
    -------
    tuple of the form (col_lists, row_maps, sparsity)
        col_lists is a list of column lists, where the first list is the list of uncolored columns.
        row_maps is a list of nonzero rows for each column, or None for uncolored columns.
        sparsity is a nested dict specifying subjac sparsity for each total derivative, or None.
    """
    driver = problem.driver

    J = _get_bool_jac(problem, mode=mode, repeats=repeats, tol=tol, setup=setup,
                      run_model=run_model)

    if mode == 'fwd':
        full_disjoint, rows = _get_full_disjoint_cols(J, 0, J.shape[1] - 1)
        uncolored_cols = [i for i, r in enumerate(rows) if r is None]

        print("%d uncolored columns" % len(uncolored_cols))
        for color, cols in enumerate(full_disjoint):
            print("%d columns in color %d" % (len(cols), color + 1))

        # the first col_list entry corresponds to all uncolored columns (columns that are not
        # disjoint wrt any other columns).  The other entries are groups of columns that do not
        # share any nonzero row entries in common.
        col_lists = [uncolored_cols]
        col_lists.extend(full_disjoint)
        lists = col_lists
        other = rows
    elif mode == 'rev':
        full_disjoint, cols = _get_full_disjoint_rows(J, 0, J.shape[0] - 1)
        uncolored_rows = [i for i, r in enumerate(cols) if r is None]

        print("%d uncolored rows" % len(uncolored_rows))
        for color, rows in enumerate(full_disjoint):
            print("%d rows in color %d" % (len(rows), color + 1))

        # the first row_list entry corresponds to all uncolored rows (rows that are not disjoint
        # wrt any other rows).  The other entries are groups of rows that do not share any
        # nonzero column entries in common.
        row_lists = [uncolored_rows]
        row_lists.extend(full_disjoint)
        lists = row_lists
        other = cols
    else:
        raise RuntimeError("get_simul_meta: invalid mode: '%s'" % mode)

    sparsity = None
    if include_sparsity or (show_jac and stream is not None):
        of = driver._get_ordered_nl_responses()
        wrt = list(driver._designvars)

    if include_sparsity:
        sparsity = _sparsity_from_jac(J, of, wrt, driver)

    driver._total_jac = None

    if stream is not None:
        if stream.isatty():
            stream.write("\n########### BEGIN COLORING DATA ################\n")
            if mode == 'fwd':
                _write_coloring(mode, col_lists, rows, sparsity, stream)
            else:
                _write_coloring(mode, row_lists, cols, sparsity, stream)
            stream.write("\n########### END COLORING DATA ############\n")
        else:
            if mode == 'fwd':
                _write_coloring(mode, col_lists, rows, sparsity, stream)
            else:
                _write_coloring(mode, row_lists, cols, sparsity, stream)

        if show_jac:
            s = stream if stream.isatty() else sys.stdout
            s.write("\n\n")
            array_viz(J, problem, of, wrt, s)

    return lists, other, sparsity
예제 #10
0
파일: coloring.py 프로젝트: onodip/OpenMDAO
def get_simul_meta(problem, mode=None, repeats=1, tol=1.e-15, show_jac=False,
                   include_sparsity=True, setup=False, run_model=False, bool_jac=None,
                   bidirectional=True, simul_coloring_excludes=None, stream=sys.stdout):
    """
    Compute simultaneous derivative colorings for the given problem.

    Parameters
    ----------
    problem : Problem or None
        The Problem being analyzed.
    mode : str or None
        The direction for computing derivatives.  If None, use problem._mode.
    repeats : int
        Number of times to repeat total jacobian computation.
    tol : float
        Tolerance used to determine if an array entry is nonzero.
    show_jac : bool
        If True, display a visualiation of the final total jacobian used to compute the coloring.
    include_sparsity : bool
        If True, include the sparsity structure of the total jacobian mapped to design vars
        and responses.  (This info is used by pyOptSparseDriver).
    setup : bool
        If True, run setup before calling compute_totals.
    run_model : bool
        If True, run run_model before calling compute_totals.
    bool_jac : ndarray
        If problem is not supplied, a previously computed boolean jacobian can be used.
    bidirectional : bool
        If True, compute a bidirectional coloring.
    simul_coloring_excludes : iter of int
        A collection of rows (fwd) or cols (rev) that are to be excluded from the coloring and
        solved in the opposite direction. Used only if problem is None. Otherwise, problem
        driver will supply exclude information gathered from design vars or responses.
    stream : file-like or None
        Stream where output coloring info will be written.

    Returns
    -------
    dict
        dict['fwd'] = (col_lists, row_maps)
            col_lists is a list of column lists, the first being a list of uncolored columns.
            row_maps is a list of nonzero rows for each column, or None for uncolored columns.
        dict['rev'] = (row_lists, col_maps)
            row_lists is a list of row lists, the first being a list of uncolored rows.
            col_maps is a list of nonzero cols for each row, or None for uncolored rows.
        dict['sparsity'] = a nested dict specifying subjac sparsity for each total derivative.
        dict['J'] = ndarray, the computed boolean jacobian.
    """
    if problem is not None:
        J = _get_bool_jac(problem, repeats=repeats, tol=tol, setup=setup,
                          run_model=run_model)
    elif bool_jac is not None:
        J = bool_jac
    else:
        raise RuntimeError("You must supply either problem or bool_jac to get_simul_meta().")

    if mode is None:
        mode = problem._mode

    if problem is not None:
        simul_coloring_excludes = _get_simul_excludes(problem)

    coloring = _compute_coloring(J, mode, bidirectional, simul_coloring_excludes)

    modes = [m for m in ('fwd', 'rev') if m in coloring]

    sparsity = None
    if problem is not None:
        driver = problem.driver
    else:
        driver = None

    if driver is not None:
        if include_sparsity or (show_jac and stream is not None):
            of = driver._get_ordered_nl_responses()
            wrt = list(driver._designvars)

        if include_sparsity:
            sparsity = _sparsity_from_jac(J, of, wrt, driver)
            coloring['sparsity'] = sparsity

        driver._total_jac = None

    if stream is not None:
        if stream.isatty():
            stream.write("\n########### BEGIN COLORING DATA ################\n")
            _write_coloring(modes, coloring, stream)
            stream.write("\n########### END COLORING DATA ############\n")
        else:
            _write_coloring(modes, coloring, stream)

        if show_jac:
            s = stream if stream.isatty() else sys.stdout
            s.write("\n\n")
            array_viz(J, problem, of, wrt, s)

    return coloring