예제 #1
0
파일: space.py 프로젝트: navjotk/devito
 def reorder(cls, items, relations):
     if not all(isinstance(i, AbstractInterval) for i in items):
         raise ValueError("Cannot create an IntervalGroup from objects of type [%s]" %
                          ', '.join(str(type(i)) for i in items))
     # The relations are between dimensions, not intervals. So we take
     # care of that here
     ordering = filter_ordered(toposort(relations) + [i.dim for i in items])
     return sorted(items, key=lambda i: ordering.index(i.dim))
예제 #2
0
def dimension_sort(expr, key=None):
    """
    Topologically sort the :class:`Dimension`s in ``expr``, based on the order
    in which they appear within :class:`Indexed`s.

    :param expr: The :class:`devito.Eq` from which the :class:`Dimension`s are
                 extracted.
    :param key: A callable used as key to enforce a final ordering.
    """

    def handle_indexed(indexed):
        constraint = []
        for i in indexed.indices:
            try:
                maybe_dim = split_affine(i).var
                if isinstance(maybe_dim, Dimension):
                    constraint.append(maybe_dim)
            except ValueError:
                # Maybe there are some nested Indexeds (e.g., the situation is A[B[i]])
                nested = flatten(handle_indexed(n) for n in retrieve_indexed(i))
                if nested:
                    constraint.extend(nested)
                else:
                    # Fallback: Just insert all the Dimensions we find, regardless of
                    # what the user is attempting to do
                    constraint.extend([d for d in filter_sorted(i.free_symbols)
                                       if isinstance(d, Dimension)])
        return constraint

    constraints = [handle_indexed(i) for i in retrieve_indexed(expr, mode='all')]

    ordering = toposort(constraints)

    # Add in leftover free dimensions (not an Indexed' index)
    extra = set([i for i in expr.free_symbols if isinstance(i, Dimension)])

    # Add in pure data dimensions (e.g., those accessed only via explicit values,
    # such as A[3])
    indexeds = retrieve_indexed(expr, deep=True)
    if indexeds:
        extra.update(set.union(*[set(i.function.indices) for i in indexeds]))

    # Enforce determinism
    extra = filter_sorted(extra, key=attrgetter('name'))

    ordering.extend([i for i in extra if i not in ordering])

    # Add in parent dimensions
    for i in list(ordering):
        if i.is_Derived and i.parent not in ordering:
            ordering.insert(ordering.index(i), i.parent)

    return sorted(ordering, key=key)
예제 #3
0
 def reorder(cls, items, relations):
     # The relations are between dimensions, not intervals. So we take
     # care of that here
     ordering = filter_ordered(toposort(relations) + [i.dim for i in items])
     return sorted(items, key=lambda i: ordering.index(i.dim))
예제 #4
0
def test_toposort(elements, expected):
    try:
        ordering = toposort(elements)
        assert ordering == expected
    except ValueError:
        assert expected is None
예제 #5
0
파일: space.py 프로젝트: opesci/devito
 def reorder(cls, items, relations):
     # The relations are between dimensions, not intervals. So we take
     # care of that here
     ordering = filter_ordered(toposort(relations) + [i.dim for i in items])
     return sorted(items, key=lambda i: ordering.index(i.dim))
예제 #6
0
파일: test_tools.py 프로젝트: opesci/devito
def test_toposort(elements, expected):
    try:
        ordering = toposort(elements)
        assert ordering == expected
    except ValueError:
        assert expected is None