code: def idx_split_train_val(
      datapipe: IterDataPipe,
      train_perc: float,
      decimal_places: int = 2,
      key_fn: Callable[[int], int] = _default_key_fn,
  ) -> Tuple[IterDataPipe, IterDataPipe]:
      if not 0.0 < train_perc < 1.0:
          raise ValueError("train_perc must be in range (0.0, 1.0)")
      return (
          _IdxFilter(
              datapipe,
              partial(train_filter, key_fn, train_perc, decimal_places),
          ),
          _IdxFilter(
              datapipe,
              partial(val_filter, key_fn, train_perc, decimal_places),
          ),
      )
  
imports: import csv
  import math
  import random
  from dataclasses import dataclass
  from functools import partial
  from io import IOBase
  from typing import Any, Callable, Iterable, Iterator, List, Sequence, Tuple, TypeVar
  import torch
  from iopath.common.file_io import PathManager, PathManagerFactory
  from torch.utils.data import functional_datapipe, get_worker_info, IterDataPipe
  from torchrec.sparse.jagged_tensor import KeyedJaggedTensor
  from torchrec.streamable import Pipelineable
label_desc: Use image node_id 4 for calling a global function with example usage: idx_split_train_val(datapipe, train_perc, decimal_places, key_fn) and returns: _IdxFilter,  _IdxFilter