def __init__(self, dataloader: Any, io_config: dict, batch_size: int = None):
        """Initialize FileListCommonDataLoader.

        Each batch in the common dataloader is saved as a raw input file.

        :param dataloader: dataloader object. Dataloader must be iterable and return a tuple of (input, target).
            input is a dictionary of input names and input tensors.
        :param io_config: dictionary containing input and output names and shapes of the model.
        :param batch_size: number of inputs per chunked input list file for batch processing. If None, all inputs are in
            a single input list file. This is not the same as the batch size of the common dataloader.
        """
        import torch

        # create temporary directory for processed data
        temp_data_dir = tempfile.TemporaryDirectory("olive_tmp_")  # pylint: disable=consider-using-with

        logger.debug("Converting dataloader of type %s to FileList dataloader", type(dataloader))
        input_specs = {}
        for input_name, input_shape in zip(io_config["input_names"], io_config["input_shapes"]):
            input_specs[input_name] = {"target_shape": input_shape}

        # get single data sample
        input_data, _ = next(iter(dataloader))
        # source input names
        for input_name, input_spec in input_specs.items():
            if input_name in input_data:
                source_name = input_name
            elif input_name.strip(":0") in input_data:
                source_name = input_name.strip(":0")
            else:
                raise ValueError(f"Input name {input_name} not found in dataset")
            input_spec["source_name"] = source_name

        # source input_shapes and permutations
        for input_spec in input_specs.values():
            # get source shape
            source_shape = list(input_data[input_spec["source_name"]].shape)
            input_spec["source_shape"] = source_shape

            # get permutation from source shape to target shape
            target_shape = input_spec["target_shape"]
            assert len(source_shape) == len(target_shape), (
                f"Source shape {source_shape} and target shape {target_shape} must have the same length"
            )

            # find the permutation of the source shape that matches the target shape
            # e.g. source_shape = [1, 3, 224, 224], target_shape = [1, 224, 224, 3]
            #      -> permutation = [0, 2, 3, 1]
            # NCDHW -> NDHWC, NCHW -> NHWC, NFC -> NCF
            channel_permutation = [0, *list(range(2, len(source_shape))), 1]
            # NTF -> TNF
            # TODO(jambayk): confirm if it is NTF -> TNF or TNF -> NTF. Doesn't really matter since the first two
            # dimensions are transposed anyway
            time_permutation = [1, 0, *list(range(2, len(source_shape)))]
            if source_shape == target_shape:
                permutation = None  # no permutation needed
            elif target_shape == [source_shape[idx] for idx in channel_permutation]:
                permutation = channel_permutation
            elif target_shape == [source_shape[idx] for idx in time_permutation]:
                permutation = time_permutation
            else:
                raise ValueError(
                    f"Cannot find a valid permutation of the source shape {source_shape} that matches the target"
                    f" shape {target_shape}"
                )

            input_spec["permutation"] = permutation
        logger.debug("Input specs: %s", input_specs)

        data_dir = Path(temp_data_dir.name) / "data"
        data_dir.mkdir()  # create data dir

        input_order = []
        annotations = []
        num_samples = len(dataloader)
        sample_digits = len(str(num_samples))
        for i, (input_data_i, annotation) in enumerate(dataloader):
            if isinstance(input_data_i, tuple):
                input_data = dict(zip(input_specs.keys(), input_data_i))
            elif isinstance(input_data_i, (torch.Tensor, np.ndarray)):
                input_data = dict(zip(input_specs.keys(), [input_data_i]))
            else:
                input_data = input_data_i
                assert isinstance(input_data, dict), (
                    f"Input data must be a tuple, torch.Tensor, np.ndarray, or dict. Got {type(input_data)}"
                )

            input_file_name = f"{i}.bin".zfill(sample_digits + 4)
            input_order.append(input_file_name)
            for input_spec in input_specs.values():
                data = input_data[input_spec["source_name"]]
                # FileList data loader only supports float32
                data = np.array(data, dtype=np.float32)

                # permute if necessary
                if input_spec["permutation"] is not None:
                    data = np.transpose(data, input_spec["permutation"])

                # save input data
                input_dir_path = data_dir / input_spec["source_name"]
                input_dir_path.mkdir(exist_ok=True)
                input_file_path = input_dir_path / input_file_name
                data.tofile(input_file_path)

            annotations.append(annotation.tolist())

        annotations = None if annotations[0] is None else np.array(annotations)

        # create input_list
        input_list_file = input_list_utils.create_input_list(
            data_dir=str(data_dir),
            input_names=list(input_specs.keys()),
            input_dirs=[input_spec["source_name"] for input_spec in input_specs.values()],
            add_input_names=len(input_specs) > 1,
            add_output_names=len(io_config["output_names"]) > 1,
            output_names=io_config["output_names"],
        )

        # get input list with absolute paths
        input_list = input_list_utils.get_input_list(str(data_dir), input_list_file, temp_data_dir.name)

        super().__init__(str(data_dir), input_list, annotations, batch_size)
        # save a reference to the temp_data_dir so that it persists with the object
        self.temp_data_dir = temp_data_dir
Initialize FileListCommonDataLoader.

        Each batch in the common dataloader is saved as a raw input file.

        :param dataloader: dataloader object. Dataloader must be iterable and return a tuple of (input, target).
            input is a dictionary of input names and input tensors.
        :param io_config: dictionary containing input and output names and shapes of the model.
        :param batch_size: number of inputs per chunked input list file for batch processing. If None, all inputs are in
            a single input list file. This is not the same as the batch size of the common dataloader.
        
olive/platform_sdk/qualcomm/utils/data_loader.py