Skip to content

[Python parser] Unroll/nounroll transparency over list of objects/functions #2332

@FlorianDeconinck

Description

@FlorianDeconinck

Describe the bug

Behavior of loop on constant list of objects/list between unroll and nounroll differs (see example below).

When using nounroll the parser fails during visit_Subscript, raising because it builds a tuple of non symbol/NumConstant. But the unroll behavior is fully capable of laying out the calls properly.

Even if those behavior do not share code, I'd expect a transparency between them.

This is ticket is not urgent as we can go around by using unroll on said loop at the cost of a build time blow up.

Parser trap:

        # Obtain array/tuple
        node_parsed = self._gettype(node.value)

        if len(node_parsed) > 1 or (len(node_parsed) == 1 and isinstance(node_parsed[0], tuple)
                                    and node_parsed[0][1] in ('symbol', 'NumConstant')):
            # If the value is a tuple of constants (e.g., array.shape) and the
            # slice is constant, return the value itself
            nslice = self.visit(node.slice)
            if isinstance(nslice, (Index, Number)):
                v = nslice
                try:
                    value, valtype = node_parsed[int(v)]
                    return value
                except (TypeError, ValueError):
                    pass  # Passthrough to exception

            raise DaceSyntaxError(self, node.value, 'Subscripted object cannot be a tuple')

To Reproduce
DaCe main (0ec62e)

import numpy as np
from dace import program, unroll, nounroll


class ProgramB:
    def __init__(self, parameter):
        self.parameter = parameter

    def __call__(self, A, B):
        A[:] = B[:] + self.parameter


B1 = ProgramB(0.1)
B2 = ProgramB(0.2)
Bs = [B1, B2]
nB = 2


@program
def A(array_a, array_b):
    B1(array_a, array_b)
    B2(array_a, array_b)

    for n in unroll(range(nB)):  # <--- works
        Bs[n](array_a, array_b)

    for n in nounroll(range(nB)):  # <--- fails
        Bs[n](array_a, array_b)


np_a = np.zeros((10,))
np_b = np.ones((10,))

A(np_a, np_b)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions