Ejemplo n.º 1
0
 def apply_pattern(self, sdfg):
     """ Applies this transformation on the given SDFG. """
     self.apply(sdfg)
     if not self.annotates_memlets():
         labeling.propagate_labels_sdfg(sdfg)
Ejemplo n.º 2
0
def parse_from_function(function, *compilation_args, strict=None):
    """ Try to parse a DaceProgram object and return the `dace.SDFG` object
        that corresponds to it.
        @param function: DaceProgram object (obtained from the `@dace.program`
                         decorator).
        @param compilation_args: Various compilation arguments e.g. types.
        @param strict: Whether to apply strict transformations or not (None
                       uses configuration-defined value). 
        @return: The generated SDFG object.
    """
    if not isinstance(function, DaceProgram):
        raise TypeError(
            'Function must be of type dace.frontend.python.DaceProgram')

    # Obtain parsed DaCe program
    pdp, modules = function.generate_pdp(*compilation_args)

    # Create an empty SDFG
    sdfg = SDFG(pdp.name, pdp.argtypes)

    sdfg.set_sourcecode(pdp.source, 'python')

    # Populate SDFG with states and nodes, according to the parsed DaCe program

    # 1) Inherit dependencies and inject tasklets
    # 2) Traverse program graph and recursively split into states,
    #    annotating edges with their transition conditions.
    # 3) Add arrays, streams, and scalars to the SDFG array store
    # 4) Eliminate empty states with no conditional outgoing transitions
    # 5) Label states in topological order
    # 6) Construct dataflow graph for each state

    # Step 1)
    for primitive in pdp.children:
        depanalysis.inherit_dependencies(primitive)

    # Step 2)
    state_primitives = depanalysis.create_states_simple(pdp, sdfg)

    # Step 3)
    for dataname, datadesc in pdp.all_arrays().items():
        sdfg.add_datadesc(dataname, datadesc)

    # Step 4) Absorb next state into current, if possible
    oldstates = list(sdfg.topological_sort(sdfg.start_state))
    for state in oldstates:
        if state not in sdfg.nodes():  # State already removed
            continue
        if sdfg.out_degree(state) == 1:
            edge = sdfg.out_edges(state)[0]
            nextState = edge.dst
            if not edge.data.is_unconditional():
                continue
            if sdfg.in_degree(nextState) > 1:  # If other edges point to state
                continue
            if len(state_primitives[nextState]) > 0:  # Don't fuse full states
                continue

            outEdges = list(sdfg.out_edges(nextState))
            for e in outEdges:
                # Construct new edge from the current assignments, new
                # assignments, and new conditions
                newEdge = copy.deepcopy(edge.data)
                newEdge.assignments.update(e.data.assignments)
                newEdge.condition = e.data.condition
                sdfg.add_edge(state, e.dst, newEdge)
            sdfg.remove_node(nextState)

    # Step 5)
    stateList = sdfg.topological_sort(sdfg.start_state)
    for i, state in enumerate(stateList):
        if state.label is None or state.label == "":
            state.set_label("s" + str(i))

    # Step 6)
    for i, state in enumerate(stateList):
        depanalysis.build_dataflow_graph(sdfg, state, state_primitives[state],
                                         modules)

    # Fill in scope entry/exit connectors
    sdfg.fill_scope_connectors()

    # Memlet propagation
    if sdfg.propagate:
        labeling.propagate_labels_sdfg(sdfg)

    # Drawing the SDFG before strict transformations
    sdfg.draw_to_file(recursive=True)

    # Apply strict transformations automatically
    if (strict == True
            or (strict is None
                and Config.get_bool('optimizer', 'automatic_state_fusion'))):
        sdfg.apply_strict_transformations()

    # Drawing the SDFG (again) to a .dot file
    sdfg.draw_to_file(recursive=True)

    # Validate SDFG
    sdfg.validate()

    return sdfg
Ejemplo n.º 3
0
    def optimize(self, debugprint=True):
        """ A command-line UI for applying patterns on the SDFG.
            @param debugprint: Whether to print verbose information to the 
                               console.
            @return: An optimized SDFG object
        """
        sdfg_file = self.sdfg.name + '.sdfg'
        if os.path.isfile(sdfg_file):
            ui_input = input('An SDFG with the filename "%s" was found. '
                             'Would you like to use it instead? [Y/n] ' %
                             sdfg_file)
            if len(ui_input) == 0 or ui_input[0] not in ['n', 'N']:
                return dace.SDFG.from_file(sdfg_file)

        # Visualize SDFGs during optimization process
        VISUALIZE = Config.get_bool('optimizer', 'visualize')
        VISUALIZE_SDFV = Config.get_bool('optimizer', 'visualize_sdfv')
        SAVE_DOTS = Config.get_bool('optimizer', 'savedots')

        if SAVE_DOTS:
            self.sdfg.draw_to_file('before.dot')
            self.sdfg.save(os.path.join('_dotgraphs', 'before.sdfg'))
            if VISUALIZE:
                os.system('xdot _dotgraphs/before.dot&')
            if VISUALIZE_SDFV:
                os.system('sdfv _dotgraphs/before.sdfg&')

        # Optimize until there is not pattern matching or user stops the process.
        pattern_counter = 0
        while True:
            # Print in the UI all the pattern matching options.
            ui_options = sorted(self.get_pattern_matches())
            ui_options_idx = 0
            for pattern_match in ui_options:
                sdfg = self.sdfg.sdfg_list[pattern_match.sdfg_id]
                print('%d. Transformation %s' %
                      (ui_options_idx, pattern_match.print_match(sdfg)))
                ui_options_idx += 1

            # If no pattern matchings were found, quit.
            if ui_options_idx == 0:
                print('No viable transformations found')
                break

            ui_input = input(
                'Select the pattern to apply (0 - %d or name$id): ' %
                (ui_options_idx - 1))

            pattern_name, occurrence, param_dict = _parse_cli_input(ui_input)

            pattern_match = None
            if (pattern_name is None and occurrence >= 0
                    and occurrence < ui_options_idx):
                pattern_match = ui_options[occurrence]
            elif pattern_name is not None:
                counter = 0
                for match in ui_options:
                    if type(match).__name__ == pattern_name:
                        if occurrence == counter:
                            pattern_match = match
                            break
                        counter = counter + 1

            if pattern_match is None:
                print(
                    'You did not select a valid option. Quitting optimization ...'
                )
                break

            match_id = (str(occurrence) if pattern_name is None else '%s$%d' %
                        (pattern_name, occurrence))
            sdfg = self.sdfg.sdfg_list[pattern_match.sdfg_id]
            print('You selected (%s) pattern %s with parameters %s' %
                  (match_id, pattern_match.print_match(sdfg), str(param_dict)))

            # Set each parameter of the parameter dictionary separately
            for k, v in param_dict.items():
                setattr(pattern_match, k, v)

            pattern_match.apply(sdfg)
            self.applied_patterns.add(type(pattern_match))

            if SAVE_DOTS:
                filename = 'after_%d_%s_b4lprop' % (
                    pattern_counter + 1, type(pattern_match).__name__)
                self.sdfg.draw_to_file(filename + '.dot')
                self.sdfg.save(os.path.join('_dotgraphs', filename + '.sdfg'))

            if not pattern_match.annotates_memlets():
                labeling.propagate_labels_sdfg(self.sdfg)

            if True:
                pattern_counter += 1
                if SAVE_DOTS:
                    filename = 'after_%d_%s' % (pattern_counter,
                                                type(pattern_match).__name__)
                    self.sdfg.draw_to_file(filename + '.dot')
                    self.sdfg.save(
                        os.path.join('_dotgraphs', filename + '.sdfg'))

                    if VISUALIZE:
                        time.sleep(0.7)
                        os.system(
                            'xdot _dotgraphs/after_%d_%s.dot&' %
                            (pattern_counter, type(pattern_match).__name__))

                    if VISUALIZE_SDFV:
                        os.system(
                            'sdfv _dotgraphs/after_%d_%s.sdfg&' %
                            (pattern_counter, type(pattern_match).__name__))

        return self.sdfg
Ejemplo n.º 4
0
    def optimize(self, debugprint=True):
        """ A command-line UI for applying patterns on the SDFG.
            @param debugprint: Whether to print verbose information to the 
                               console.
            @return: An optimized SDFG object
        """

        # Visualize SDFGs during optimization process
        VISUALIZE = Config.get_bool('optimizer', 'visualize')
        SAVE_DOTS = Config.get_bool('optimizer', 'savedots')

        if SAVE_DOTS:
            with open('before.dot', 'w') as dot_file:
                dot_file.write(self.sdfg.draw())
            if VISUALIZE:
                os.system('xdot before.dot&')

        # Optimize until there is not pattern matching or user stops the process.
        pattern_counter = 0
        while True:
            # Print in the UI all the pattern matching options.
            ui_options = self.get_pattern_matches()
            ui_options_idx = 0
            for pattern_match in ui_options:
                sdfg = self.sdfg.sdfg_list[pattern_match.sdfg_id]
                print('%d. Transformation %s' %
                      (ui_options_idx, pattern_match.print_match(sdfg)))
                ui_options_idx += 1

            # If no pattern matchings were found, quit.
            if ui_options_idx == 0:
                print('No viable transformations found')
                break

            # Code working for both python 2.x and 3.x.
            try:
                ui_input = raw_input(
                    'Select the pattern to apply (0 - %d or name$id): ' %
                    (ui_options_idx - 1))
            except NameError:
                ui_input = input(
                    'Select the pattern to apply (0 - %d or name$id): ' %
                    (ui_options_idx - 1))

            pattern_name, occurrence, param_dict = _parse_cli_input(ui_input)

            pattern_match = None
            if (pattern_name is None and occurrence >= 0
                    and occurrence < ui_options_idx):
                pattern_match = ui_options[occurrence]
            elif pattern_name is not None:
                counter = 0
                for match in ui_options:
                    if type(match).__name__ == pattern_name:
                        if occurrence == counter:
                            pattern_match = match
                            break
                        counter = counter + 1

            if pattern_match is None:
                print(
                    'You did not select a valid option. Quitting optimization ...'
                )
                break

            match_id = (str(occurrence) if pattern_name is None else
                        '%s$%d' % (pattern_name, occurrence))
            sdfg = self.sdfg.sdfg_list[pattern_match.sdfg_id]
            print('You selected (%s) pattern %s with parameters %s' %
                  (match_id, pattern_match.print_match(sdfg), str(param_dict)))

            # Set each parameter of the parameter dictionary separately
            for k, v in param_dict.items():
                setattr(pattern_match, k, v)

            pattern_match.apply(sdfg)
            self.applied_patterns.add(type(pattern_match))

            if SAVE_DOTS:
                with open(
                        'after_%d_%s_b4lprop.dot' %
                    (pattern_counter + 1, type(pattern_match).__name__),
                        'w') as dot_file:
                    dot_file.write(self.sdfg.draw())

            if not pattern_match.annotates_memlets():
                labeling.propagate_labels_sdfg(self.sdfg)

            if True:
                pattern_counter += 1
                if SAVE_DOTS:
                    with open(
                            'after_%d_%s.dot' % (pattern_counter,
                                                 type(pattern_match).__name__),
                            'w') as dot_file:
                        dot_file.write(self.sdfg.draw())
                    if VISUALIZE:
                        time.sleep(0.7)
                        os.system(
                            'xdot after_%d_%s.dot&' %
                            (pattern_counter, type(pattern_match).__name__))

        return self.sdfg