Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3.12 #1386

Merged
merged 44 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ea32695
Trying Python 3.12
alexnick83 Oct 6, 2023
6a320d1
Preparing for deprecation.
alexnick83 Oct 7, 2023
b6f56d5
Fixed assertEqual(s) call.
alexnick83 Oct 7, 2023
dcbfd2a
Reworked code to avoid deprecation warnings and errors.
alexnick83 Oct 7, 2023
a8d7431
Reworked code to avoid deprecation warnings and errors.
alexnick83 Oct 7, 2023
10108c7
Fixed comma/dots.
alexnick83 Oct 7, 2023
d8efaca
Another comma/dot fix.
alexnick83 Oct 7, 2023
f4cb38a
Reworked access to slice attribute.
alexnick83 Oct 8, 2023
772a629
Fixed invalid escape sequence backlash-space.
alexnick83 Oct 8, 2023
c9277ce
Using StrConstant instead of ast.Str.
alexnick83 Oct 8, 2023
1884809
Fixed invalid escape sequence backslash-asterisk.
alexnick83 Oct 8, 2023
209d44a
Removed extraneous and deprecated alias.
alexnick83 Oct 8, 2023
b5cb4b6
Accesing numerical constant value with t.value for Python >= 3.8.
alexnick83 Oct 8, 2023
52011cb
Accessing numerical constant value with node.value for Python >= 3.8.
alexnick83 Oct 8, 2023
e4288ed
Accessing numerical constant value with node.func.value for Python >=…
alexnick83 Oct 8, 2023
6afee58
ast.Ellipsis check predicated by Python < 3.8.
alexnick83 Oct 8, 2023
b302ec5
Using NameConstant instead of ast.NameConstant.
alexnick83 Oct 8, 2023
fa1d5c7
Check for ast.Num predicated by Python < 3.8.
alexnick83 Oct 8, 2023
fa805f3
Fixed invalid escape sequence backslash-space.
alexnick83 Oct 9, 2023
dbd286d
Predicated access to `n` attribute.
alexnick83 Oct 9, 2023
1bfaee5
Fixed pytest None warning deprecation.
alexnick83 Oct 9, 2023
8e0f883
Fixed pytest incorrect return deprecation warning.
alexnick83 Oct 9, 2023
b64f124
Predicated access to s attribute.
alexnick83 Oct 9, 2023
70a61bb
Using NameConstant alias.
alexnick83 Oct 9, 2023
f34cb50
Using NumConstant and predication for n atttribute access.
alexnick83 Oct 9, 2023
8689c63
Predicated access to n attribute.
alexnick83 Oct 9, 2023
2a756b9
Fixed pytest mark misconfiguration.
alexnick83 Oct 9, 2023
736bd0b
Using Index and NumConstant.
alexnick83 Oct 9, 2023
e553510
Refactored if chain/nest
alexnick83 Oct 9, 2023
5ae0b47
Fixed use of ast.Str.
alexnick83 Oct 9, 2023
fead1d6
Fixed ast.Num and n attribute.
alexnick83 Oct 9, 2023
e5c6451
Disallowing type aliases.
alexnick83 Oct 9, 2023
9a96ef3
Fixed TypeAlias for older Python versions.
alexnick83 Oct 9, 2023
e8317ed
Don't run test for Python < 3.12.
alexnick83 Oct 9, 2023
d1d4616
Fixed typo.
alexnick83 Oct 9, 2023
b41ba7e
Fixed typo.
alexnick83 Oct 9, 2023
52002ac
Trying to disable test for Python < 3.12.
alexnick83 Oct 9, 2023
6c90205
Added py312 mark.
alexnick83 Oct 9, 2023
a9cc686
Comment out test.
alexnick83 Oct 9, 2023
d5e656e
Fixed JoinedStr visitor method.
alexnick83 Oct 9, 2023
650e386
Added more disallowed statements.
alexnick83 Oct 9, 2023
4cf6959
Unparsing constant.
alexnick83 Oct 9, 2023
d79a403
Revered changes to FPGA tests.
alexnick83 Oct 9, 2023
159033e
Removed py312 mark.
alexnick83 Oct 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/general-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7,'3.11']
python-version: [3.7,'3.12']
simplify: [0,1,autoopt]

steps:
Expand Down
2 changes: 1 addition & 1 deletion dace/codegen/control_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

x < 5
/------>[s2]--------\\
[s1] \ ->[s5]
[s1] \\ ->[s5]
------>[s3]->[s4]--/
x >= 5

Expand Down
46 changes: 32 additions & 14 deletions dace/codegen/cppunparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,21 @@
from dace import dtypes
from dace.codegen.tools import type_inference


if sys.version_info < (3, 8):
BytesConstant = ast.Bytes
EllipsisConstant = ast.Ellipsis
NameConstant = ast.NameConstant
NumConstant = ast.Num
StrConstant = ast.Str
else:
BytesConstant = ast.Constant
EllipsisConstant = ast.Constant
NameConstant = ast.Constant
NumConstant = ast.Constant
StrConstant = ast.Constant


# Large float and imaginary literals get turned into infinities in the AST.
# We unparse those infinities to INFSTR.
INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
Expand Down Expand Up @@ -574,7 +589,7 @@ def _generic_FunctionDef(self, t, is_async=False):
self.write('/* async */ ')

if getattr(t, "returns", False):
if isinstance(t.returns, ast.NameConstant):
if isinstance(t.returns, NameConstant):
if t.returns.value is None:
self.write('void')
else:
Expand Down Expand Up @@ -729,25 +744,26 @@ def _Repr(self, t):
raise NotImplementedError('Invalid C++')

def _Num(self, t):
repr_n = repr(t.n)
t_n = t.value if sys.version_info >= (3, 8) else t.n
repr_n = repr(t_n)
# For complex values, use DTYPE_TO_TYPECLASS dictionary
if isinstance(t.n, complex):
if isinstance(t_n, complex):
dtype = dtypes.DTYPE_TO_TYPECLASS[complex]

# Handle large integer values
if isinstance(t.n, int):
bits = t.n.bit_length()
if isinstance(t_n, int):
bits = t_n.bit_length()
if bits == 32: # Integer, potentially unsigned
if t.n >= 0: # unsigned
if t_n >= 0: # unsigned
repr_n += 'U'
else: # signed, 64-bit
repr_n += 'LL'
elif 32 < bits <= 63:
repr_n += 'LL'
elif bits == 64 and t.n >= 0:
elif bits == 64 and t_n >= 0:
repr_n += 'ULL'
elif bits >= 64:
warnings.warn(f'Value wider than 64 bits encountered in expression ({t.n}), emitting as-is')
warnings.warn(f'Value wider than 64 bits encountered in expression ({t_n}), emitting as-is')

if repr_n.endswith("j"):
self.write("%s(0, %s)" % (dtype, repr_n.replace("inf", INFSTR)[:-1]))
Expand Down Expand Up @@ -898,13 +914,13 @@ def _BinOp(self, t):
self.write(")")
# Special cases for powers
elif t.op.__class__.__name__ == 'Pow':
if isinstance(t.right, (ast.Num, ast.Constant, ast.UnaryOp)):
if isinstance(t.right, (NumConstant, ast.Constant, ast.UnaryOp)):
power = None
if isinstance(t.right, (ast.Num, ast.Constant)):
power = t.right.n
if isinstance(t.right, (NumConstant, ast.Constant)):
power = t.right.value if sys.version_info >= (3, 8) else t.right.n
elif isinstance(t.right, ast.UnaryOp) and isinstance(t.right.op, ast.USub):
if isinstance(t.right.operand, (ast.Num, ast.Constant)):
power = -t.right.operand.n
if isinstance(t.right.operand, (NumConstant, ast.Constant)):
power = - (t.right.operand.value if sys.version_info >= (3, 8) else t.right.operand.n)

if power is not None and int(power) == power:
negative = power < 0
Expand Down Expand Up @@ -984,7 +1000,9 @@ def _Attribute(self, t):
# Special case: 3.__abs__() is a syntax error, so if t.value
# is an integer literal then we need to either parenthesize
# it or add an extra space to get 3 .__abs__().
if (isinstance(t.value, (ast.Num, ast.Constant)) and isinstance(t.value.n, int)):
if isinstance(t.value, ast.Constant) and isinstance(t.value.value, int):
self.write(" ")
elif sys.version_info < (3, 8) and isinstance(t.value, ast.Num) and isinstance(t.value.n, int):
self.write(" ")
if (isinstance(t.value, ast.Name) and t.value.id in ('dace', 'dace::math', 'dace::cmath')):
self.write("::")
Expand Down
2 changes: 1 addition & 1 deletion dace/codegen/instrumentation/papi.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ class PAPIUtils(object):
def available_counters() -> Dict[str, int]:
"""
Returns the available PAPI counters on this machine. Only works on
\*nix based systems with ``grep`` and ``papi-tools`` installed.
*nix based systems with ``grep`` and ``papi-tools`` installed.

:return: A set of available PAPI counters in the form of a dictionary
mapping from counter name to the number of native hardware
Expand Down
6 changes: 4 additions & 2 deletions dace/codegen/targets/cpp.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019-2021 ETH Zurich and the DaCe authors. All rights reserved.
# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved.
"""
Helper functions for C++ code generation.
NOTE: The C++ code generator is currently located in cpu.py.
Expand All @@ -9,6 +9,7 @@
import itertools
import math
import numbers
import sys
import warnings

import sympy as sp
Expand Down Expand Up @@ -1275,7 +1276,8 @@ def visit_BinOp(self, node: ast.BinOp):
evaluated_constant = symbolic.evaluate(unparsed, self.constants)
evaluated = symbolic.symstr(evaluated_constant, cpp_mode=True)
value = ast.parse(evaluated).body[0].value
if isinstance(evaluated_node, numbers.Number) and evaluated_node != value.n:
if isinstance(evaluated_node, numbers.Number) and evaluated_node != (
value.value if sys.version_info >= (3, 8) else value.n):
raise TypeError
node.right = ast.parse(evaluated).body[0].value
except (TypeError, AttributeError, NameError, KeyError, ValueError, SyntaxError):
Expand Down
10 changes: 9 additions & 1 deletion dace/codegen/tools/type_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,15 @@ def _BinOp(t, symbols, inferred_symbols):
return dtypes.result_type_of(type_left, type_right)
# Special case for integer power
elif t.op.__class__.__name__ == 'Pow':
if (isinstance(t.right, (ast.Num, ast.Constant)) and int(t.right.n) == t.right.n and t.right.n >= 0):
if (sys.version_info >= (3, 8) and isinstance(t.right, ast.Constant) and
int(t.right.value) == t.right.value and t.right.value >= 0):
if t.right.value != 0:
type_left = _dispatch(t.left, symbols, inferred_symbols)
for i in range(int(t.right.n) - 1):
_dispatch(t.left, symbols, inferred_symbols)
return dtypes.result_type_of(type_left, dtypes.typeclass(np.uint32))
elif (sys.version_info < (3, 8) and isinstance(t.right, ast.Num) and
int(t.right.n) == t.right.n and t.right.n >= 0):
if t.right.n != 0:
type_left = _dispatch(t.left, symbols, inferred_symbols)
for i in range(int(t.right.n) - 1):
Expand Down
32 changes: 20 additions & 12 deletions dace/frontend/python/astutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
from dace import dtypes, symbolic


if sys.version_info >= (3, 8):
NumConstant = ast.Constant
else:
NumConstant = ast.Num


def _remove_outer_indentation(src: str):
""" Removes extra indentation from a source Python function.

Expand Down Expand Up @@ -66,8 +72,9 @@ def is_constant(node: ast.AST) -> bool:
if sys.version_info >= (3, 8):
if isinstance(node, ast.Constant):
return True
if isinstance(node, (ast.Num, ast.Str, ast.NameConstant)): # For compatibility
return True
else:
if isinstance(node, (ast.Num, ast.Str, ast.NameConstant)): # For compatibility
return True
return False


Expand All @@ -82,13 +89,14 @@ def evalnode(node: ast.AST, gvars: Dict[str, Any]) -> Any:
"""
if not isinstance(node, ast.AST):
return node
if isinstance(node, ast.Index): # For compatibility
if sys.version_info < (3, 9) and isinstance(node, ast.Index): # For compatibility
node = node.value
if isinstance(node, ast.Num): # For compatibility
return node.n
if sys.version_info >= (3, 8):
if isinstance(node, ast.Constant):
return node.value
else:
if isinstance(node, ast.Num): # For compatibility
return node.n

# Replace internal constants with their values
node = copy_tree(node)
Expand All @@ -112,7 +120,7 @@ def rname(node):

if isinstance(node, str):
return node
if isinstance(node, ast.Num):
if sys.version_info < (3, 8) and isinstance(node, ast.Num):
return str(node.n)
if isinstance(node, ast.Name): # form x
return node.id
Expand Down Expand Up @@ -174,11 +182,11 @@ def subscript_to_ast_slice(node, without_array=False):

# Python <3.9 compatibility
result_slice = None
if isinstance(node.slice, ast.Index):
if sys.version_info < (3, 9) and isinstance(node.slice, ast.Index):
slc = node.slice.value
if not isinstance(slc, ast.Tuple):
result_slice = [slc]
elif isinstance(node.slice, ast.ExtSlice):
elif sys.version_info < (3, 9) and isinstance(node.slice, ast.ExtSlice):
slc = tuple(node.slice.dims)
else:
slc = node.slice
Expand All @@ -196,7 +204,7 @@ def subscript_to_ast_slice(node, without_array=False):
# Slice
if isinstance(s, ast.Slice):
result_slice.append((s.lower, s.upper, s.step))
elif isinstance(s, ast.Index): # Index (Python <3.9)
elif sys.version_info < (3, 9) and isinstance(s, ast.Index): # Index (Python <3.9)
result_slice.append(s.value)
else: # Index
result_slice.append(s)
Expand Down Expand Up @@ -226,7 +234,7 @@ def _Subscript(self, t):
self.dispatch(t.value)
self.write('[')
# Compatibility
if isinstance(t.slice, ast.Index):
if sys.version_info < (3, 9) and isinstance(t.slice, ast.Index):
slc = t.slice.value
else:
slc = t.slice
Expand Down Expand Up @@ -600,9 +608,9 @@ def visit_Name(self, node: ast.Name):
def visit_Constant(self, node):
return self.visit_Num(node)

def visit_Num(self, node: ast.Num):
def visit_Num(self, node: NumConstant):
newname = f'__uu{self.id}'
self.gvars[newname] = node.n
self.gvars[newname] = node.value if sys.version_info >= (3, 8) else node.n
self.id += 1
return ast.copy_location(ast.Name(id=newname, ctx=ast.Load()), node)

Expand Down
24 changes: 20 additions & 4 deletions dace/frontend/python/memlet_parser.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright 2019-2021 ETH Zurich and the DaCe authors. All rights reserved.
# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved.
import ast
import copy
import re
import sys
from collections import namedtuple
from typing import Any, Dict, List, Optional, Tuple, Union
from dataclasses import dataclass
Expand All @@ -16,6 +16,22 @@
MemletType = Union[ast.Call, ast.Attribute, ast.Subscript, ast.Name]


if sys.version_info < (3, 8):
_simple_ast_nodes = (ast.Constant, ast.Name, ast.NameConstant, ast.Num)
BytesConstant = ast.Bytes
EllipsisConstant = ast.Ellipsis
NameConstant = ast.NameConstant
NumConstant = ast.Num
StrConstant = ast.Str
else:
_simple_ast_nodes = (ast.Constant, ast.Name)
BytesConstant = ast.Constant
EllipsisConstant = ast.Constant
NameConstant = ast.Constant
NumConstant = ast.Constant
StrConstant = ast.Constant


@dataclass
class MemletExpr:
name: str
Expand Down Expand Up @@ -114,7 +130,7 @@ def _fill_missing_slices(das, ast_ndslice, array, indices):
offsets.append(idx)
idx += 1
new_idx += 1
elif (isinstance(dim, ast.Ellipsis) or dim is Ellipsis
elif ((sys.version_info < (3, 8) and isinstance(dim, ast.Ellipsis)) or dim is Ellipsis
or (isinstance(dim, ast.Constant) and dim.value is Ellipsis)
or (isinstance(dim, ast.Name) and dim.id is Ellipsis)):
if has_ellipsis:
Expand All @@ -125,7 +141,7 @@ def _fill_missing_slices(das, ast_ndslice, array, indices):
ndslice[j] = (0, array.shape[j] - 1, 1)
idx += 1
new_idx += 1
elif (dim is None or (isinstance(dim, (ast.Constant, ast.NameConstant)) and dim.value is None)):
elif (dim is None or (isinstance(dim, (ast.Constant, NameConstant)) and dim.value is None)):
new_axes.append(new_idx)
new_idx += 1
# NOTE: Do not increment idx here
Expand Down
Loading
Loading