Skip to content

Commit c30da81

Browse files
committed
Add compile invariant tests for params and closures
Signed-off-by: Rostan Tabet <rtabet@nvidia.com>
1 parent 862f0d3 commit c30da81

1 file changed

Lines changed: 265 additions & 2 deletions

File tree

dali/test/python/experimental_mode/test_compile_invariants.py

Lines changed: 265 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import importlib.util
16+
import pathlib
17+
import tempfile
1518
import functools
1619
import os
1720
from collections.abc import Callable
@@ -63,8 +66,6 @@ def test():
6366
return decorator
6467

6568

66-
# Module-level fixtures for the rejection tests
67-
#
6869
_MODULE_DTYPE = ndd.float32
6970
_GLOBAL_ANGLE = 60
7071

@@ -217,6 +218,171 @@ def transform(images):
217218
compiled_test(expect_captured=True)(transform)()
218219

219220

221+
@compiled_test(expect_captured=True)
222+
def test_param_literal(images):
223+
def rotate(imgs, angle):
224+
return ndd.rotate(imgs, angle=angle)
225+
226+
return rotate(images, 60)
227+
228+
229+
@compiled_test(expect_captured=True)
230+
def test_param_expression(images):
231+
def rotate(imgs, angle):
232+
return ndd.rotate(imgs, angle=angle)
233+
234+
return rotate(images, 40 + 20)
235+
236+
237+
@compiled_test(expect_captured=True)
238+
def test_param_dali_attribute(images):
239+
def cast(imgs, dtype):
240+
return ndd.cast(imgs, dtype=dtype)
241+
242+
return cast(images, ndd.int32)
243+
244+
245+
@compiled_test(expect_captured=True)
246+
def test_param_chained(images):
247+
def inner(imgs, angle):
248+
return ndd.rotate(imgs, angle=angle)
249+
250+
def outer(imgs, angle):
251+
return inner(imgs, angle)
252+
253+
return outer(images, 60)
254+
255+
256+
@compiled_test(expect_captured=True)
257+
def test_param_recursive(images):
258+
def _rotate_recursive(images, angle, depth):
259+
if depth == 0:
260+
return ndd.rotate(images, angle=angle)
261+
return _rotate_recursive(images, angle, depth - 1)
262+
263+
return _rotate_recursive(images, 60, 4)
264+
265+
266+
@compiled_test(expect_captured=True)
267+
def test_param_cross_file(images):
268+
source = """
269+
import nvidia.dali.experimental.dynamic as ndd
270+
271+
def resize(images, size):
272+
return ndd.resize(images, size=size)
273+
"""
274+
with tempfile.TemporaryDirectory() as tmpdir:
275+
module_path = pathlib.Path(tmpdir) / "module.py"
276+
module_path.write_text(source)
277+
278+
# Import the module
279+
spec = importlib.util.spec_from_file_location("module", module_path)
280+
assert spec is not None and spec.loader is not None
281+
module = importlib.util.module_from_spec(spec)
282+
spec.loader.exec_module(module)
283+
284+
return module.resize(images, (224, 224))
285+
286+
287+
@compiled_test(expect_captured=True)
288+
def test_param_method(images):
289+
class Aug:
290+
def rotate(self, imgs, angle):
291+
return ndd.rotate(imgs, angle=angle)
292+
293+
aug = Aug()
294+
return aug.rotate(images, 60)
295+
296+
297+
@compiled_test(expect_captured=True)
298+
def test_param_classmethod(images):
299+
class Aug:
300+
@classmethod
301+
def rotate(cls, imgs, angle):
302+
return ndd.rotate(imgs, angle=angle)
303+
304+
return Aug.rotate(images, 60)
305+
306+
307+
@compiled_test(expect_captured=True)
308+
def test_param_staticmethod(images):
309+
class Aug:
310+
@staticmethod
311+
def rotate(imgs, angle):
312+
return ndd.rotate(imgs, angle=angle)
313+
314+
return Aug.rotate(images, 60)
315+
316+
317+
@compiled_test(expect_captured=True)
318+
def test_param_partial_keyword(images):
319+
def resize(imgs, width, height):
320+
return ndd.resize(imgs, size=[width, height])
321+
322+
resize_partial = functools.partial(resize, width=64)
323+
return resize_partial(images, height=128)
324+
325+
326+
@compiled_test(expect_captured=True)
327+
def test_closure_param(images):
328+
def make_rotate(angle):
329+
def rotate():
330+
return ndd.rotate(images, angle=angle)
331+
332+
return rotate
333+
334+
return make_rotate(60)()
335+
336+
337+
@compiled_test(expect_captured=True)
338+
def test_closure_local(images):
339+
def make_rotate():
340+
def rotate():
341+
return ndd.rotate(images, angle=angle)
342+
343+
angle = 60
344+
return rotate
345+
346+
return make_rotate()()
347+
348+
349+
@compiled_test(expect_captured=True)
350+
def test_closure_live_parent(images):
351+
def rotate(angle):
352+
def transform():
353+
return ndd.rotate(images, angle=angle)
354+
355+
return transform()
356+
357+
return rotate(60)
358+
359+
360+
@compiled_test(expect_captured=True)
361+
def test_param_default_literal(images):
362+
def rotate(imgs, angle=60):
363+
return ndd.rotate(imgs, angle=angle)
364+
365+
return rotate(images)
366+
367+
368+
@compiled_test(expect_captured=True)
369+
def test_param_default_dali_attribute(images):
370+
def cast(imgs, dtype=ndd.int32):
371+
return ndd.cast(imgs, dtype=dtype)
372+
373+
return cast(images)
374+
375+
376+
@compiled_test(expect_captured=True)
377+
def test_param_default_name(images):
378+
angle = 60
379+
380+
def rotate(imgs, angle=angle):
381+
return ndd.rotate(imgs, angle=angle)
382+
383+
return rotate(images)
384+
385+
220386
# Tests for rejected cases
221387

222388

@@ -307,3 +473,100 @@ def test_import_name(images):
307473
from math import pi
308474

309475
return ndd.rotate(images, angle=pi)
476+
477+
478+
@compiled_test(expect_captured=False)
479+
def test_param_mutable(images):
480+
def resize(imgs, size):
481+
size[1] = 42
482+
return ndd.resize(imgs, size=size)
483+
484+
return resize(images, [224, 224])
485+
486+
487+
@compiled_test(expect_captured=False)
488+
def test_param_varargs(images):
489+
def resize(imgs, *size):
490+
return ndd.resize(imgs, size=size)
491+
492+
return resize(images, 224, 224)
493+
494+
495+
@compiled_test(expect_captured=False)
496+
def test_default_mutable(images):
497+
def resize(imgs, size=[224, 224]): # noqa: B006
498+
return ndd.resize(imgs, size=size)
499+
500+
return resize(images)
501+
502+
503+
@compiled_test(expect_captured=False)
504+
def test_closure_mutable_cell(images):
505+
def make_resize(size):
506+
def resize():
507+
return ndd.resize(images, size=size)
508+
509+
return resize
510+
511+
return make_resize([224, 224])()
512+
513+
514+
@compiled_test(expect_captured=False)
515+
def test_closure_nonlocal_rebind(images):
516+
def make_rotate():
517+
angle = 60
518+
519+
def rebind():
520+
nonlocal angle
521+
angle = 90
522+
523+
def rotate():
524+
return ndd.rotate(images, angle=angle)
525+
526+
rebind()
527+
return rotate
528+
529+
return make_rotate()()
530+
531+
532+
@compiled_test(expect_captured=False)
533+
def test_param_through_decorator(images):
534+
def rotate(imgs, angle):
535+
return ndd.rotate(imgs, angle=angle)
536+
537+
@functools.wraps(rotate)
538+
def wrapped(*args, **kwargs):
539+
return rotate(*args, **kwargs)
540+
541+
return wrapped(images, 60)
542+
543+
544+
@compiled_test(expect_captured=False)
545+
def test_param_inline_call_target(images):
546+
def make_rotate():
547+
def rotate(imgs, angle):
548+
return ndd.rotate(imgs, angle=angle)
549+
550+
return rotate
551+
552+
return make_rotate()(images, 60)
553+
554+
555+
@compiled_test(expect_captured=False)
556+
def test_param_callable_instance_attr(images):
557+
class Aug:
558+
def __call__(self, imgs, angle):
559+
return ndd.rotate(imgs, angle=angle)
560+
561+
class Holder:
562+
aug = Aug()
563+
564+
return Holder.aug(images, 60)
565+
566+
567+
@compiled_test(expect_captured=False)
568+
def test_param_global_arg(images):
569+
def augment(imgs, crop):
570+
return ndd.rotate(imgs, angle=crop)
571+
572+
return augment(images, _GLOBAL_ANGLE)

0 commit comments

Comments
 (0)