Пример #1
0
def make_sir_compliant(schedule):
    '''
    Applies various transformations to the supplied schedule to replace any
    features that cannot be represented in SIR with alternative forms:

    1. Converts any accesses of individual array elements into 1-trip loops.
    2. Transforms array assignments into loops.
    3. Replaces any ABS, SIGN, MIN or MAX intrinsics with equivalent PSyIR.
    4. Hoists any loop-invariant assignments out of loops over levels.

    :param schedule: the schedule to transform.
    :type schedule: :py:class:`psyclone.psyir.nodes.Schedule`

    '''
    abs_trans = Abs2CodeTrans()
    sign_trans = Sign2CodeTrans()
    min_trans = Min2CodeTrans()
    max_trans = Max2CodeTrans()
    array_range_trans = NemoAllArrayRange2LoopTrans()
    array_access_trans = NemoAllArrayAccess2LoopTrans()
    hoist_trans = HoistTrans()

    # Transform any single index accesses in array assignments
    # (e.g. a(1)) into 1-trip loops.
    for assignment in schedule.walk(Assignment):
        array_access_trans.apply(assignment)

    # Transform any array assignments (Fortran ':' notation) into loops.
    for assignment in schedule.walk(Assignment):
        array_range_trans.apply(assignment)

    for kernel in schedule.walk(NemoKern):

        kernel_schedule = kernel.get_kernel_schedule()
        for oper in kernel_schedule.walk(Operation):
            if oper.operator == UnaryOperation.Operator.ABS:
                # Apply ABS transformation
                abs_trans.apply(oper)
            elif oper.operator == BinaryOperation.Operator.SIGN:
                # Apply SIGN transformation
                sign_trans.apply(oper)
            elif oper.operator in [BinaryOperation.Operator.MIN,
                                   NaryOperation.Operator.MIN]:
                # Apply (2-n arg) MIN transformation
                min_trans.apply(oper)
            elif oper.operator in [BinaryOperation.Operator.MAX,
                                   NaryOperation.Operator.MAX]:
                # Apply (2-n arg) MAX transformation
                max_trans.apply(oper)

    # Remove any loop invariant assignments inside k-loops to make
    # them perfectly nested. At the moment this transformation
    # does not perform any dependence analysis validation so could
    # move code that should not be moved, see issue
    # #1387. However, it is known that it is safe do apply this
    # transformation to this particular code
    # (tra_adv_compute.F90).
    for loop in schedule.loops():
        # outermost only
        if loop.loop_type == "levels":
            for child in loop.loop_body[:]:
                if isinstance(child, Assignment):
                    hoist_trans.apply(child)