Skip to content

Commit

Permalink
Merge pull request #882 from spcl/nested-transients
Browse files Browse the repository at this point in the history
Support transient fields with strict-mode disabled, better nested error handling
  • Loading branch information
tbennun authored Nov 12, 2021
2 parents aff1bd9 + bd9bc46 commit 5cbf090
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 13 deletions.
10 changes: 6 additions & 4 deletions dace/frontend/python/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def __str__(self):
col = 0

if self.visitor is not None:
return (self.message + "\n in File " + str(self.visitor.filename) +
", line " + str(line) + ":" + str(col))
return (self.message + "\n File \"" + str(self.visitor.filename) +
"\", line " + str(line) + ", column " + str(col))
else:
return (self.message + "\n in line " + str(line) + ":" + str(col))

Expand Down Expand Up @@ -162,5 +162,7 @@ def combine_nested_closures(self):

new_name = data.find_new_name(arrname,
self.closure_arrays.keys())
self.closure_arrays[new_name] = (arrname, desc, evaluator, True)
self.array_mapping[id(arr)] = new_name
if not desc.transient:
self.closure_arrays[new_name] = (arrname, desc, evaluator,
True)
self.array_mapping[id(arr)] = new_name
17 changes: 11 additions & 6 deletions dace/frontend/python/newast.py
Original file line number Diff line number Diff line change
Expand Up @@ -3651,10 +3651,11 @@ def _parse_sdfg_call(self, funcname: str,
outer_name = self.sdfg.add_datadesc(aname,
desc,
find_new_name=True)
self.nested_closure_arrays[outer_name] = (arr, desc)
# Add closure arrays as function arguments
args.append((aname, outer_name))
required_args.append(aname)
if not desc.transient:
self.nested_closure_arrays[outer_name] = (arr, desc)
# Add closure arrays as function arguments
args.append((aname, outer_name))
required_args.append(aname)
else:
raise DaceSyntaxError(
self, node, 'Unrecognized SDFG type "%s" in call to "%s"' %
Expand Down Expand Up @@ -4006,9 +4007,13 @@ def visit_Call(self, node: ast.Call):
if func or funcname in self.other_sdfgs:
try:
return self._parse_sdfg_call(funcname, func, node)
except SkipCall:
except SkipCall as ex:
# Re-parse call with non-parsed information
return self.visit_Call(node.func.oldnode)
try:
return self.visit_Call(node.func.oldnode)
except Exception: # Anything could happen here
# Raise original exception instead
raise ex.__context__

# Set arguments
args = []
Expand Down
61 changes: 58 additions & 3 deletions tests/python_frontend/callee_autodetect_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
not annotated with @dace decorators.
"""
import dace
from dace.frontend.python.common import DaceSyntaxError
from dace.frontend.python.common import DaceSyntaxError, SDFGConvertible
from dataclasses import dataclass
import numpy as np
import pytest
Expand Down Expand Up @@ -104,7 +104,7 @@ def notworking2(a: dace.float64[20]):
return notworking_nested(a)

A = np.random.rand(20)
with pytest.raises(DaceSyntaxError, match='notworking_nested'):
with pytest.raises(DaceSyntaxError, match='numpy.allclose'):
notworking2(A)


Expand Down Expand Up @@ -133,7 +133,7 @@ def recursive_autoparse(a: dace.float64[20]):
return nested_a(a)

A = np.random.rand(20)
with pytest.raises(DaceSyntaxError, match='nested_a'):
with pytest.raises(DaceSyntaxError, match='nested_b'):
recursive_autoparse(A)


Expand Down Expand Up @@ -173,6 +173,59 @@ def adff(A):
assert np.allclose(A, ref + 2 * 5)


def test_error_handling():
class NotConvertible(SDFGConvertible):
def __call__(self, a):
import numpy as np
print('A very pythonic method', a)

def __sdfg__(self, *args, **kwargs):
# Raise a special type of error that does not naturally occur in dace
raise NotADirectoryError('I am not really convertible')

def __sdfg_signature__(self):
return ([], [])

A = np.random.rand(20)

with pytest.raises(NotADirectoryError):

@dace.program
def testprogram(A, nc: dace.constant):
nc(A)

testprogram(A, NotConvertible())


def test_nested_class_error_handling():
def not_convertible(f):
class NotConvertibleMethod(SDFGConvertible):
def __sdfg__(self, *args, **kwargs):
# Raise a special type of error that does not naturally occur in dace
raise NotADirectoryError('I am not really convertible')

def __sdfg_signature__(self):
return ([], [])

return NotConvertibleMethod()

class MaybeConvertible:
@not_convertible
def __call__(self, a):
import numpy as np
print('A very pythonic method', a)

A = np.random.rand(20)

with pytest.raises(NotADirectoryError):

@dace.program
def testprogram(A, nc: dace.constant):
nc(A)

testprogram(A, MaybeConvertible())


if __name__ == '__main__':
test_autodetect_function()
test_autodetect_method()
Expand All @@ -184,3 +237,5 @@ def adff(A):
test_nested_recursion2_fail()
test_nested_autoparse_dec_fail()
test_autodetect_function_in_for()
test_error_handling()
test_nested_class_error_handling()
33 changes: 33 additions & 0 deletions tests/python_frontend/fields_and_global_arrays_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,38 @@ def __call__(self, A):
assert np.allclose(1.0, A)


def test_nested_transient_field():
class Something:
def __init__(self):
self._nonglobal = TransientField(shape=[10, 11], dtype=np.float64)

@dace.method
def __call__(self, A):
self._nonglobal[...] = A
return self._nonglobal + 1

class MainSomething:
def __init__(self) -> None:
self.something_else = Something()

@dace.method
def __call__(self, A):
return self.something_else(A)

A = np.ones((10, 11))

outer = MainSomething()

# Ensure no other global arrays were created apart from A and __return
sdfg = outer.__call__.to_sdfg(A)
assert len([k for k, v in sdfg.arrays.items() if not v.transient]) == 2

# Run code
outer(A)

assert np.allclose(1.0, A)


if __name__ == '__main__':
test_bad_closure()
test_dynamic_closure()
Expand Down Expand Up @@ -702,3 +734,4 @@ def __call__(self, A):
test_same_global_array()
test_two_inner_methods()
test_transient_field()
test_nested_transient_field()

0 comments on commit 5cbf090

Please sign in to comment.