Core Python Language Support

Note

This section is a work in progress. It may not reflect the capabilities provided in the latest version of DaCe.

This document describes in detail which features of Python are supported by the Data-Centric Python-Frontend. The comparison is made against the Python Language Reference.

2 Lexical Analysis

2.1 Line Structure

The DaCe Python-Frontend uses the Python AST module to parse code. Therefore, full support of the line structure section is expected. However, we explicitly test for the following subsections (see line_structure_test):

  • 2.1.3 Comments

  • 2.1.5 Explicit Line Joining

  • 2.1.6 Implicit Line Joining

  • 2.1.7 Blank Lines

2.3 Identifiers and Keywords

The DaCe Python-Frontend uses exactly the same rules for identifiers as normal Python. However, for a generated SDFG to compile to a target architecture, the identifiers used must be valid in the output language (e.g., C/C++). We currently provide no automatic transformation of identifiers used as variable names. Therefore, it is the responsibility of the user to ensure that the variable names are compatible.

2.3.1 Keywords:

The following keywords are recognized (for at least a subset of their Python functionality):

  • True, False, None

  • or, and, not

  • if, elif, else

  • for, while, break, continue, in

  • def, return, lambda, with

The following keywords are NOT accepted:

  • global, nonlocal

  • class

  • try, except, finally

  • raise, yield, pass

  • import, from, as

  • assert, async, await, del

2.3.2 Reserved classes of identifiers:

Reserved class of Python identifiers are not supported. Furthermore, identifiers starting with double underscore (__) are reserved by the SDFG language.

2.4 Literals

The DaCe Python-Frontend supports in general the same literals as Python. However, there is currently limited support for strings and char/byte arrays. For example, it is not possible to instantiate an (u)int8 array with a string or byte literal.

2.5 Operators

The DaCe Python-Frontend supports all Python operators. The operators are only supported in the context of arithmetic/logical operations among scalar values and DaCe (NumPy-compatible) arrays. For example, it is not possible to concatenate 2 strings with the + operator. The := operator (Named Expression) is parsed as an assignment statement.

2.6 Delimiters

The DaCe Python-Frontend supports all Python delimiters. However, not all uses of those delimiters are supported. For example, we do not support lists, sets, and dictionaries. Therefore, the delimiters [, ], {, } cannot be used to define those datatypes.

6 Expressions

6.1 Arithmetic Conversions

The arithmetic conversions for most binary operators are implemented with casting:

  • If any of the operands is of complex type, but the other operand is a float, int or bool, then it is cast to the same complex type.

  • If any of the operands is of float type, but the other operand is int or bool, the it is cast to the same float type.

Some binary operations are handled differently, as described in the sections below.

6.2 Atoms

All Python atoms are parsed. However, their intended usage may not be supported:

  • Identifiers: Supported

  • Literals: Only use of numerical literals supported

  • Parethesized forms: Some uses of tuples supported

  • Displays for lists, sets and dictionaries: Unsupported

  • List displays: Supported only for (supported) method arguments that expect a list/tuple

  • Set displays: Unsupported

  • Dictionary displays: Unsupported

  • Generator expressions: Only the built-in range supported

  • Yield expressions: Unsupported

6.3 Primaries

Similarly to atoms, Python primaries are parsed. However, their intended usage may not be supported:

  • Attribute references: Supported for a subset of the DaCe and Numpy modules

  • Subscripts: Supported on DaCe/Numpy arrays

  • Slicing: Supported on DaCe/Numpy arrays

  • Calls: Supported for other DaCe programs, and a subset of methods from the DaCe and NumPy modules

One caveat of subscripts with NumPy arrays is that NumPy allows negative indices to wrap around the array. In DaCe this is not supported.

6.4 Await expression

Unsupported

6.5 The power (**) operator

Supported. If the base is an integer and the exponent a signed integer, both operands are cast to float64 and the result is also of type float64.

6.6 Unary arithmetic and bitwise operations

Supported

6.7 Binary arithmetic operations

Supported. Notable differences compared to the expected Python result:

  • Modulo operator always returns a natural number (like in C/C++)

6.8 Shifting operations

Only integral types supported.

6.9 Binary bitwise operations

Only integral types supported.

6.10 Comparisons

Supported

6.11 Boolean operations

Supported

6.12 Assignment expressions

Experimental support

6.13 Conditional expressions

Supported

6.14 Lambdas

Supported only for defining WCR/reduction operators

6.15 Expression lists

Supported only for (supported) method arguments that expect a list/tuple

6.16 Evaluation order

Supported

6.17 Operator precedence

Evaluated exactly as in Python.

7 Simple Statements

7.1 Expression statements

Partially supported, as described in the previous section. Python interactive mode is not supported.

7.2 Assignment statements

Assignment statements with single or multiple targets are supported, both with and without parentheses. Statements with starred targets are not supported. Targets may only be identifiers, and subscriptions/slices of Numpy arrays.

7.2.1 Augmented assignment statements:

Supported with the same constraints for targets as in assignment statements.

7.2.2 Annotated assignment statements:

Unsupported

7.3 The assert statement

Unsupported

7.4 The pass statement

Supported

7.5 The del statement

Unsupported

7.6 The return statement

Supported

7.7 The yield statement

Unsupported

7.8 The raise statement

Unsupported

7.9 The break statement

Supported for for/while loops, as long as the break statement is in the same SDFG-level as the for/while statement.

7.10 The continue statement

Supported for for/while loops, as long as the continue statement is in the same SDFG-level as the for/while statement.

7.11 The import statement

Unsupported, including 7.11.1 Future statements

7.12 The global statement

Unsupported

7.13 The nonlocal statement

Unsupported

8 Compound Statements

8.1 The if statement

Supported. Note that if the type of some variable depends on the branch taken, then the variable will always have the type of the first branch. E.g., in the following code, variable b will be of type dace.int always, even if a[0] == np.float32(np.pi), unless it is explicitly declared as such:

@dace.program
def single_target(a: dace.float32[1]):
    if (a[0] < 0):
        b = 0
    elif (a[0] < 1):
        b = 1
    else:
        b = a
    return b

8.2 The while statement

Supported

8.3 The for statement

Supported, but only with range, parrange, and dace.map.

8.4 The try statement

Unsupported

8.5 The with statement

Only supported with dace.tasklet

8.6 Function definitions

Supported only with the dace.program decorator. Function arguments must be type-annotated. Nested dace.program definitions are not supported.

8.7 Class definitions

Supported through the Preprocessing component of the Python frontend.

8.8 Coroutines

Unsupported