kerncraft/models/layer_condition.py
def analyze(self):
        """Run complete analysis."""
        # check that layer conditions can be applied on this kernel:
        # 1. All iterations may only have a step width of 1
        loop_stack = list(self.kernel.get_loop_stack())
        if any([l['increment'] != 1 for l in loop_stack]):
            raise ValueError("Can not apply layer condition, since not all loops are of step "
                             "length 1.")

        # 2. The order of iterations must be reflected in the order of indices in all array
        #    references containing the inner loop index. If the inner loop index is not part of the
        #    reference, the reference is simply ignored
        # TODO support flattend array indexes
        for aref in list(self.kernel.index_order()):
            # Strip left most empty sets (refereces without index)
            while aref and len(aref[0]) == 0:
                aref.pop(0)
            for i, idx_names in enumerate(aref):
                # 1. Check for that there are enough loops to handle access dimensions
                # 2. Check that offset index matches loop index (in same order)
                if i >= len(loop_stack) or \
                        any([loop_stack[i]['index'] != idx.name for idx in idx_names]):
                    raise ValueError("Can not apply layer condition, order of indices in array "
                                     "does not follow order of loop indices. Single-dimension is "
                                     "currently not supported.")

        # 3. Indices may only increase with one
        # TODO use a public interface, not self.kernel._*
        for arefs in chain(chain(*self.kernel.sources.values()),
                           chain(*self.kernel.destinations.values())):
            if not arefs:
                continue

            # Strip left most constant offsets (refereces without index) to support things like:
            # a[0][i+1][j][k-1] with an i, j and k loop-nest
            while arefs and not arefs[0].free_symbols:
                arefs = arefs[1:]

            # Check that remaining indices are in orde
            for i, expr in enumerate(arefs):
                diff = sympy.diff(expr, sympy.Symbol(loop_stack[i]['index']))
                if diff != 0 and diff != 1:
                    # TODO support -1 aswell
                    raise ValueError("Can not apply layer condition, array references may not "
                                     "increment more then one per iteration.")

        self.results = self.calculate_cache_access()
def analyze(self):
        """Run complete analysis."""
        # check that layer conditions can be applied on this kernel:
        # 1. All iterations may only have a step width of 1
        loop_stack = list(self.kernel.get_loop_stack())
        if any([l['increment'] != 1 for l in loop_stack]):
            raise ValueError("Can not apply layer condition, since not all loops are of step "
                             "length 1.")

        # 2. The order of iterations must be reflected in the order of indices in all array
        #    references containing the inner loop index. If the inner loop index is not part of the
        #    reference, the reference is simply ignored
        # TODO support flattend array indexes
        for aref in list(self.kernel.index_order()):
            # Strip left most empty sets (refereces without index)
            while aref and len(aref[0]) == 0:
                aref.pop(0)
            for i, idx_names in enumerate(aref):
                # 1. Check for that there are enough loops to handle access dimensions
                # 2. Check that offset index matches loop index (in same order)
                if i >= len(loop_stack) or \
                        any([loop_stack[i]['index'] != idx.name for idx in idx_names]):
                    raise ValueError("Can not apply layer condition, order of indices in array "
                                     "does not follow order of loop indices. Single-dimension is "
                                     "currently not supported.")

        # 3. Indices may only increase with one
        # TODO use a public interface, not self.kernel._*
        for arefs in chain(chain(*self.kernel.sources.values()),
                           chain(*self.kernel.destinations.values())):
            if not arefs:
                continue

            # Strip left most constant offsets (refereces without index) to support things like:
            # a[0][i+1][j][k-1] with an i, j and k loop-nest
            while arefs and not arefs[0].free_symbols:
                arefs = arefs[1:]

            # Check that remaining indices are in orde
            for i, expr in enumerate(arefs):
                diff = sympy.diff(expr, sympy.Symbol(loop_stack[i]['index']))
                if diff != 0 and diff != 1:
                    # TODO support -1 aswell
                    raise ValueError("Can not apply layer condition, array references may not "
                                     "increment more then one per iteration.")

        self.results = self.calculate_cache_access()
Run complete analysis.