Repository: NVIDIA-Merlin/NVTabular (language: python)

Issue:
Fix for running on CPU only systems
On my macbook and on the linux github actions CI, ``` pytest tests/unit/test_cpu_workflow.py```
fails with:

```
ERROR    nvtabular:workflow.py:366 Failed to transform operator <nvtabular.ops.categorify.Categorify object at 0x7fbed7cdc2b0>
Traceback (most recent call last):
  File "/Users/benf/code/nvtabular/nvtabular/ops/categorify.py", line 395, in transform
    new_df[name] = _encode(
  File "/Users/benf/code/nvtabular/nvtabular/ops/categorify.py", line 998, in _encode
    value = fetch_table_data(
  File "/Users/benf/code/nvtabular/nvtabular/worker.py", line 89, in fetch_table_data
    table = reader(f, **use_kwargs)
  File "/Users/benf/miniconda3/lib/python3.9/site-packages/pandas/io/parquet.py", line 459, in read_parquet
    return impl.read(
  File "/Users/benf/miniconda3/lib/python3.9/site-packages/pandas/io/parquet.py", line 221, in read
    return self.api.parquet.read_table(
  File "/Users/benf/miniconda3/lib/python3.9/site-packages/pyarrow/parquet.py", line 1700, in read_table
    dataset = _ParquetDatasetV2(
  File "/Users/benf/miniconda3/lib/python3.9/site-packages/pyarrow/parquet.py", line 1558, in __init__
    self._dataset = ds.dataset(path_or_paths, filesystem=filesystem,
  File "/Users/benf/miniconda3/lib/python3.9/site-packages/pyarrow/dataset.py", line 657, in dataset
    return _filesystem_dataset(source, **kwargs)
  File "/Users/benf/miniconda3/lib/python3.9/site-packages/pyarrow/dataset.py", line 402, in _filesystem_dataset
    fs, paths_or_selector = _ensure_single_source(source, filesystem)
  File "/Users/benf/miniconda3/lib/python3.9/site-packages/pyarrow/dataset.py", line 378, in _ensure_single_source
    raise FileNotFoundError(path)
FileNotFoundError: <fsspec.implementations.local.LocalFileOpener object at 0x7fbeb9a990d0>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/benf/code/nvtabular/nvtabular/workflow.py", line 364, in _transform_partition
    df = column_group.op.transform(column_group.input_column_names, df)
  File "/Users/benf/code/nvtabular/nvtabular/dispatch.py", line 54, in inner2
    return func(*args, **kwargs)
  File "/Users/benf/code/nvtabular/nvtabular/ops/categorify.py", line 413, in transform
    raise RuntimeError(f"Failed to categorical encode column {name}") from e
RuntimeError: Failed to categorical encode column name-string
```

This seems to be a result of how fsspec.open interacts with pandas. When fsspec.open is called
as a context manager it returns a ```fsspec.implementations.local.LocalFileOpener``` object which
fails with pandas. However when not run as a context manager (just fsspec.open) it returns a
```fsspec.core.OpenFile``` object which works.

Work around this issue by not using the fsspec contextmanager, and use one from contextlib instead.

After this change I can run ``` pytest tests/unit/test_cpu_workflow.py``` on my macbook to test cpu
only capabalities.

<!--

Thank you for contributing to NVTabular :)

Here are some guidelines to help the review process go smoothly.

1. Please write a description in this text box of the changes that are being
   made.

2. Please ensure that you have written units tests for the changes made/features
   added.

3. If you are closing an issue please use one of the automatic closing words as
   noted here: https://help.github.com/articles/closing-issues-using-keywords/

4. If your pull request is not ready for review but you want to make use of the
   continuous integration testing facilities please label it with `[WIP]`.

5. If your pull request is ready to be reviewed without requiring additional
   work on top of it, then remove the `[WIP]` label (if present) and replace
   it with `[REVIEW]`. If assistance is required to complete the functionality,
   for example when the C/C++ code of a feature is complete but Python bindings
   are still required, then add the label `[HELP-REQ]` so that others can triage
   and assist. The additional changes then can be implemented on top of the
   same PR. If the assistance is done by members of the rapidsAI team, then no
   additional actions are required by the creator of the original PR for this,
   otherwise the original author of the PR needs to give permission to the
   person(s) assisting to commit to their personal fork of the project. If that
   doesn't happen then a new PR based on the code of the original PR can be
   opened by the person assisting, which then will be the PR that will be
   merged.

6. Once all work has been done and review has taken place please do not add
   features or make changes out of the scope of those requested by the reviewer
   (doing this just add delays as already reviewed code ends up having to be
   re-reviewed/it is hard to tell what is new etc!). Further, please do not
   rebase your branch on master/force push/rewrite history, doing any of these
   causes the context of any comments made by reviewers to be lost. If
   conflicts occur against master they should be resolved by merging master
   into the branch used for making the pull request.

Many thanks in advance for your cooperation!

-->



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/cpu-ci.yml b/.github/workflows/cpu-ci.yml
new file mode 100644
index 00000000000..a4466bbe3c1
--- /dev/null
+++ b/.github/workflows/cpu-ci.yml
@@ -0,0 +1,46 @@
+name: CPU CI
+
+on:
+  push:
+    branches: [ main ]
+  pull_request:
+    branches: [ main ]
+
+jobs:
+  build:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        python-version: [3.8]
+        os: [ubuntu-latest]
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v2
+      with:
+        python-version: ${{ matrix.python-version }}
+    - name: Install Ubuntu packages
+      run: |
+        sudo apt-get update -y
+        sudo apt-get install -y protobuf-compiler
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip setuptools wheel 
+        python -m pip install -r requirements.txt
+        python -m pip install -r requirements-dev.txt
+    - name: Lint with flake8
+      run: |
+        flake8 .
+    - name: Lint with black
+      run: |
+        black --check .
+    - name: Lint with isort
+      run: |
+        isort -c .
+    - name: Build
+      run: |
+        python -m pip install -e .
+    - name: Run unittests
+      run: |
+        python -m pytest -svv tests/unit/test_cpu_workflow.py


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index ee00bebf650..c11049fe9ec 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -25,8 +25,18 @@
 
 try:
     import cudf
+
+    try:
+        import cudf.testing._utils
+
+        assert_eq = cudf.testing._utils.assert_eq
+    except ImportError:
+        import cudf.tests.utils
+
+        assert_eq = cudf.tests.utils.assert_eq
 except ImportError:
     cudf = None
+
 import numpy as np
 import psutil
 import pytest
@@ -36,18 +46,6 @@
 
 import nvtabular
 
-try:
-    import cudf.testing._utils
-
-    assert_eq = cudf.testing._utils.assert_eq
-except ImportError:
-    if cudf:
-        import cudf.tests.utils
-
-        assert_eq = cudf.tests.utils.assert_eq
-    else:
-        assert_eq = None
-
 allcols_csv = ["timestamp", "id", "label", "name-string", "x", "y", "z"]
 mycols_csv = ["name-string", "id", "label", "x", "y"]
 mycols_pq = ["name-cat", "name-string", "id", "label", "x", "y"]