code: def _write_parquet(
      df,
      paths,
      compression="snappy",
      index=None,
      statistics="ROWGROUP",
      metadata_file_path=None,
      int96_timestamps=False,
      row_group_size_bytes=ioutils._ROW_GROUP_SIZE_BYTES_DEFAULT,
      row_group_size_rows=None,
      max_page_size_bytes=None,
      max_page_size_rows=None,
      partitions_info=None,
      storage_options=None,
      force_nullable_schema=False,
      header_version="1.0",
      use_dictionary=True,
  ):
      if is_list_like(paths) and len(paths) > 1:
          if partitions_info is None:
              ValueError(
                  "partition info is required for multiple paths"
              )
          elif not is_list_like(partitions_info):
              ValueError(
                  "partition info must be list-like for multiple paths"
              )
          elif not len(paths) == len(partitions_info):
              ValueError(
                  "partitions_info and paths must be of same size"
              )
      if is_list_like(partitions_info) and len(partitions_info) > 1:
          if not is_list_like(paths):
              ValueError(
                  "paths must be list-like when partitions_info provided"
              )
  
      paths_or_bufs = [
          ioutils.get_writer_filepath_or_buffer(
              path_or_data=path,
              mode="wb",
              storage_options=storage_options,
          )
          for path in paths
      ]
      common_args = {
          "index": index,
          "compression": compression,
          "statistics": statistics,
          "metadata_file_path": metadata_file_path,
          "int96_timestamps": int96_timestamps,
          "row_group_size_bytes": row_group_size_bytes,
          "row_group_size_rows": row_group_size_rows,
          "max_page_size_bytes": max_page_size_bytes,
          "max_page_size_rows": max_page_size_rows,
          "partitions_info": partitions_info,
          "force_nullable_schema": force_nullable_schema,
          "header_version": header_version,
          "use_dictionary": use_dictionary,
      }
      if all(ioutils.is_fsspec_open_file(buf) for buf in paths_or_bufs):
          with ExitStack() as stack:
              fsspec_objs = [
                  stack.enter_context(file) for file in paths_or_bufs
              ]
              file_objs = [
                  ioutils.get_IOBase_writer(file_obj)
                  for file_obj in fsspec_objs
              ]
              write_parquet_res = libparquet.write_parquet(
                  df, filepaths_or_buffers=file_objs, **common_args
              )
      else:
          write_parquet_res = libparquet.write_parquet(
              df, filepaths_or_buffers=paths_or_bufs, **common_args
          )
  
      return write_parquet_res
  
imports: from __future__ import annotations
  import itertools
  import math
  import operator
  import shutil
  import tempfile
  import warnings
  from collections import defaultdict
  from contextlib import ExitStack
  from functools import partial, reduce
  from typing import Callable, Dict, List, Optional, Tuple
  from uuid import uuid4
  import numpy
  import pandas
  from pyarrow import dataset
  import cudf
  from cudf._lib import parquet
  from cudf.api.types import is_list_like
  from cudf.core.column import build_categorical_column, column_empty, full
  from cudf.utils import ioutils
  from cudf.utils.nvtx_annotation import _cudf_nvtx_annotate
label_desc: Use image node_id 1 for calling a global function with example usage: _write_parquet(df, paths, compression, index, statistics, metadata_file_path, int96_timestamps, row_group_size_bytes, row_group_size_rows, max_page_size_bytes, max_page_size_rows, partitions_info, storage_options, force_nullable_schema, header_version, use_dictionary) and returns: write_parquet_res