code: def test_batch_permutation(batch_size, num_split_level):
      """
      Split the batch into `2**num_split_level` random groups and permute
      the groups separately
      """
  
      def split_and_permute(batch, num_levels, group=0):
          assert num_levels >= 0
          if num_levels == 0:
              return (
                  fn.permute_batch(
                      batch, indices=fn.batch_permutation()
                  ),
                  group,
              )
          else:
              if fn.random.coin_flip():
                  return split_and_permute(batch, num_levels - 1, group)
              else:
                  return split_and_permute(
                      batch,
                      num_levels - 1,
                      group + 2 ** (num_levels - 1),
                  )
  
      @pipeline_def(
          batch_size=batch_size,
          device_id=0,
          num_threads=4,
          enable_conditionals=True,
      )
      def pipeline():
          sample_idx = fn.external_source(
              lambda sample_info: np.array(sample_info.idx_in_batch),
              batch=False,
          )
          sample_idx, group = split_and_permute(
              sample_idx, num_split_level
          )
          return sample_idx, group
  
      p = pipeline()
      p.build()
  
      for _ in range(3):
          sample_indices, groups = p.run()
          sample_idx = [
              np.array(sample).item() for sample in sample_indices
          ]
          group = [np.array(sample).item() for sample in groups]
          groups = {i: ([], []) for i in range(2**num_split_level)}
  
          for group_idx in range(batch_size):
              got, expected = groups[group[group_idx]]
              got.append(sample_idx[group_idx])
              expected.append(group_idx)
  
          for group_idx, (got, expected) in groups.items():
              assert (
                  sorted(got) == expected
              ), f"{group_idx}: {got} vs {expected}"
  
imports: from nvidia.dali.pipeline import pipeline_def, experimental
  import nvidia.dali.fn
  import nvidia.dali.types
  from nvidia.dali.types import SampleInfo
  from nvidia.dali import _conditionals
  from nvidia.dali.data_node import DataNode
  import numpy
  import os
  from test_utils import check_batch, compare_pipelines
  from nose_utils import assert_raises
  from test_utils import get_dali_extra_path
  from nose2.tools import params
  import itertools
label_desc: Use image node_id 40 for calling a global function with example usage: test_batch_permutation(batch_size, num_split_level) and returns: sample_idx,  group, fn,  group, split_and_permute, split_and_permute