# Buggy code
def fetch_table_data(
    table_cache,
    path,
    cache="disk",
    cats_only=False,
    reader=None,
    columns=None,
    **kwargs,
):
    """Utility to retrieve a cudf DataFrame from a cache (and add the
    DataFrame to a cache if the element is missing).  Note that `cats_only=True`
    results in optimized logic for the `Categorify` transformation.
    """
    table = table_cache.get(path, None)
    if table and not isinstance(table, cudf.DataFrame):
        if not cats_only:
            return cudf.io.read_parquet(table, index=False)
        df = cudf.io.read_parquet(table, index=False, columns=columns)
        df.index.name = "labels"
        df.reset_index(drop=False, inplace=True)
        return df

    reader = reader or cudf.io.read_parquet
    if table is None:
        if cache in ("device", "disk"):
            table = reader(path, index=False, columns=columns, **kwargs)
        elif cache == "host":
            if reader == cudf.io.read_parquet:
                # If the file is already in parquet format,
                # we can just move the same bytes to host memory
                with open(path, "rb") as f:
                    table_cache[path] = BytesIO(f.read())
                table = reader(
                    table_cache[path], index=False, columns=columns, **kwargs
                )
            else:
                # Otherwise, we should convert the format to parquet
                table = reader(path, index=False, columns=columns, **kwargs)
                table_cache[path] = BytesIO()
                table.to_parquet(table_cache[path])
        if cats_only:
            table.index.name = "labels"
            table.reset_index(drop=False, inplace=True)
        if cache == "device":
            table_cache[path] = table.copy(deep=False)
    return table


# Traceback (FileNotFoundError)
(rapids) root@dafff4b22f48:/nvtabular# python examples/dask-nvtabular-criteo-benchmark.py  -d 0,1,2,3,4,5,6,7 --data-path gs://merlin-datasets/crit_int_pq --out-path gs://merlin-datasets/output --freq-limit 0 --part-mem-frac 0.12 --device-limit-f
rac 0.7 --device-pool-frac 0.8
distributed.worker - WARNING -  Compute Failed
Function:  subgraph_callable
args:      (         label        I1        I2        I3        I4        I5        I6        I7        I8        I9  ...         C17         C18         C19          C20          C21         C22          C23         C24        C25         C26
0            0  2.772589  5.808143  1.609438  2.397895  3.332205  0.000000  1.098612  4.442651  0.000000  ...  -771205462 -1206449222  -864387787    359448199  -1761877609   357969245   -740331133    44548210 -842849922  -507617550
1            0  0.000000  5.147494  1.945910  4.584968  1.098612  0.000000  0.000000  4.394449  2.302585  ...        <NA> -1206449222 -1793932789         <NA>         <NA>        <NA>         <NA> -1441487878  809724924 -1775758394
2            0  2.639057  0.693147  0.693147  2.890372  0.000000  1.791759  0.000000  2.302585  2.833213  ...  1966974451 -1578429167 -1264946531  -2019528747    870435994  -322370806  -1701803791  2093085390  809724924  -317696227
3            0  4.110874  7.392032  0.693147  5.937536  3.610918  0.000
kwargs:    {}
Exception: FileNotFoundError(2, 'No such file or directory')

Traceback (most recent call last):
File "examples/dask-nvtabular-criteo-benchmark.py", line 373, in <module>
main(parse_args())
File "examples/dask-nvtabular-criteo-benchmark.py", line 195, in main
output_path=output_path,
File "/nvtabular/nvtabular/workflow.py", line 876, in apply
dtypes=dtypes,
File "/nvtabular/nvtabular/workflow.py", line 991, in build_and_process_graph
num_threads=num_io_threads,
File "/nvtabular/nvtabular/workflow.py", line 1080, in ddf_to_dataset
num_threads,
File "/nvtabular/nvtabular/io/dask.py", line 110, in _ddf_to_dataset
out = client.compute(out).result()
File "/opt/conda/envs/rapids/lib/python3.7/site-packages/distributed/client.py", line 225, in result
raise exc.with_traceback(tb)
File "/opt/conda/envs/rapids/lib/python3.7/site-packages/dask/optimization.py", line 961, in __call__
return core.get(self.dsk, self.outkey, dict(zip(self.inkeys, args)))
File "/opt/conda/envs/rapids/lib/python3.7/site-packages/dask/core.py", line 151, in get
result = _execute_task(task, cache)
File "/opt/conda/envs/rapids/lib/python3.7/site-packages/dask/core.py", line 121, in _execute_task
return func(*(_execute_task(a, cache) for a in args))
File "/opt/conda/envs/rapids/lib/python3.7/site-packages/dask/utils.py", line 29, in apply
return func(*args, **kwargs)
File "/opt/conda/envs/rapids/lib/python3.7/site-packages/dask/dataframe/core.py", line 5298, in apply_and_enforce
df = func(*args, **kwargs)
File "/nvtabular/nvtabular/workflow.py", line 723, in _aggregated_op
gdf = logic(gdf, columns_ctx, cols_grp, target_cols, stats_context)
File "/opt/conda/envs/rapids/lib/python3.7/contextlib.py", line 74, in inner
return func(*args, **kwds)
File "/nvtabular/nvtabular/ops/categorify.py", line 365, in apply_op
cat_names=cat_names,
File "/nvtabular/nvtabular/ops/categorify.py", line 871, in _encode
cache, path, columns=selection_r, cache=cat_cache, cats_only=True
File "/nvtabular/nvtabular/worker.py", line 84, in fetch_table_data
with open(path, "rb") as f:
FileNotFoundError: [Errno 2] No such file or directory: 'gs://merlin-datasets/output/stats/categories/unique.C1.parquet'

# Fixed code
def fetch_table_data(
    table_cache,
    path,
    cache="disk",
    cats_only=False,
    reader=None,
    columns=None,
    **kwargs,
):
    """Utility to retrieve a cudf DataFrame from a cache (and add the
    DataFrame to a cache if the element is missing).  Note that `cats_only=True`
    results in optimized logic for the `Categorify` transformation.
    """
    table = table_cache.get(path, None)
    if table and not isinstance(table, cudf.DataFrame):
        if not cats_only:
            return cudf.io.read_parquet(table, index=False)
        df = cudf.io.read_parquet(table, index=False, columns=columns)
        df.index.name = "labels"
        df.reset_index(drop=False, inplace=True)
        return df

    reader = reader or cudf.io.read_parquet
    if table is None:
        if cache in ("device", "disk"):
            table = reader(path, index=False, columns=columns, **kwargs)
        elif cache == "host":
            if reader == cudf.io.read_parquet:
                # If the file is already in parquet format,
                # we can just move the same bytes to host memory
                with fsspec.open(path, "rb") as f:
                    table_cache[path] = BytesIO(f.read())
                table = reader(
                    table_cache[path], index=False, columns=columns, **kwargs
                )
            else:
                # Otherwise, we should convert the format to parquet
                table = reader(path, index=False, columns=columns, **kwargs)
                table_cache[path] = BytesIO()
                table.to_parquet(table_cache[path])
        if cats_only:
            table.index.name = "labels"
            table.reset_index(drop=False, inplace=True)
        if cache == "device":
            table_cache[path] = table.copy(deep=False)
    return table