spcl / dace

DaCe - Data Centric Parallel Programming
http://dace.is/fast
BSD 3-Clause "New" or "Revised" License
496 stars 130 forks source link

[Python frontend]: Python 3.11.7 + enumerate + subscript breakage #1568

Closed FlorianDeconinck closed 5 months ago

FlorianDeconinck commented 5 months ago

Describe the bug The interaction of python 3.11.7 and enumerate + subscript is breaking the parsing. The following code is a reduction of a code in NASA/NOAA dynamical core. This works with python 3.8.X

To Reproduce

With python-3.11.7:


import numpy as np
import dace

tracer_variables = ["vapor", "rain", "nope"]

@dace.program
def enumerate_parsing(
    A,
    tracers: dace.compiletime,  # Dict[str, np.float64]
):
    for i, q in enumerate(tracer_variables[0:2]):
        tracers[q][:] = A

sz = (3, 3)
A_field = np.zeros(sz)
all_qs = {
    "ice": np.ones(sz),
    "rain": np.ones(sz),
    "vapor": np.ones(sz),
}

dace.config.Config.set(
    "frontend",
    "unroll_threshold",
    value=False,
)

enumerate_parsing(A_field, all_qs)

Traceback:

...
  File "/home/fgdeconi/work/git/ndsl/external/dace/dace/frontend/python/preprocessing.py", line 764, in visit_Subscript
    return self._visit_potential_constant(node.value.elts[gslice], True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/fgdeconi/work/git/ndsl/external/dace/dace/frontend/python/preprocessing.py", line 735, in _visit_potential_constant
    return self.generic_visit(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/fgdeconi/work/git/ndsl/external/dace/dace/frontend/python/preprocessing.py", line 486, in generic_visit
    return super().generic_visit(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/fgdeconi/work/git/ndsl/external/dace/dace/frontend/python/astutils.py", line 453, in generic_visit
    for field, old_value in ast.iter_fields(node):
  File "/home/fgdeconi/.pyenv/versions/3.11.7/lib/python3.11/ast.py", line 260, in iter_fields
    for field in node._fields:
                 ^^^^^^^^^^^^
AttributeError: 'list' object has no attribute '_fields'
alexnick83 commented 5 months ago

First evaluation:

I checked the code snippet above with both Python versions, and the issue at a superficial level is the following. In Python 3.8, the ast.Slice of an ast.Subscript does not contain line and column number information. In Python 3.11, the ast.Slice has all the information. Due to the missing numbers in Python 3.8, parsing follows a different path, which doesn't crash.

Information for further debugging (@tbennun maybe you have an insight on this?): Place a breakpoint at dace/frontent/python/preprocessing line 750:

            try:
                gslice = astutils.evalnode(node.slice, self.globals)
            except SyntaxError:
                return self.generic_visit(node)
FlorianDeconinck commented 5 months ago

I haven't dug in this code so much, but it seem to me something changed to _visit_potential_constant which made the calling code non-relevant anymore for list.

Indeed in 3.8 it all failed so the return is just the same node.

I pushed a PR that, restrict the list to the slice then try to turn elements into constant, then return the corrected list. Works for my use case.