Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallelize the test suite and fix a test polluted bug #1338

Merged
merged 12 commits into from
May 30, 2024
9 changes: 7 additions & 2 deletions datashader/data_libraries/cudf.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from __future__ import annotations
from contextlib import suppress
from datashader.data_libraries.pandas import default
from datashader.core import bypixel
import cudf


@bypixel.pipeline.register(cudf.DataFrame)
def cudf_pipeline(df, schema, canvas, glyph, summary, *, antialias=False):
return default(glyph, df, schema, canvas, summary, antialias=antialias, cuda=True)


with suppress(ImportError):
import cudf

cudf_pipeline = bypixel.pipeline.register(cudf.DataFrame)(cudf_pipeline)
9 changes: 7 additions & 2 deletions datashader/data_libraries/dask_cudf.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from __future__ import annotations
from contextlib import suppress
from datashader.data_libraries.dask import dask_pipeline
from datashader.core import bypixel
import dask_cudf


@bypixel.pipeline.register(dask_cudf.DataFrame)
def dask_cudf_pipeline(df, schema, canvas, glyph, summary, *, antialias=False):
return dask_pipeline(df, schema, canvas, glyph, summary, antialias=antialias, cuda=True)


with suppress(ImportError):
import dask_cudf

dask_cudf_pipeline = bypixel.pipeline.register(dask_cudf.DataFrame)(dask_cudf_pipeline)
2 changes: 1 addition & 1 deletion datashader/datashape/coretypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def to_numpy_dtype(self):
return np.dtype('datetime64[us]')


_units = set(['ns', 'us', 'ms', 's', 'm', 'h', 'D', 'W', 'M', 'Y'])
_units = ('ns', 'us', 'ms', 's', 'm', 'h', 'D', 'W', 'M', 'Y')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pytest-xdist can't handle sets as the order are not consistent, see here.



_unit_aliases = {
Expand Down
3 changes: 3 additions & 0 deletions datashader/tests/benchmarks/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import pytest

pytestmark = pytest.mark.benchmark
34 changes: 34 additions & 0 deletions datashader/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CUSTOM_MARKS = ("benchmark",)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from HoloViews. Basically, it makes it so benchmark only runs when you pass in --benchmark. Benchmark does not work with pytest-xdist (it emits a warning if both are enabled at the same time, which is why I disable it with --benchmark-skip.

At some point, I would also like to add a GPU marker, so it is possible to run only the GPU tests and not all the tests with GPU tests enabled.



def pytest_addoption(parser):
for marker in CUSTOM_MARKS:
parser.addoption(
f"--{marker}",
action="store_true",
default=False,
help=f"Run {marker} related tests",
)


def pytest_configure(config):
for marker in CUSTOM_MARKS:
config.addinivalue_line("markers", f"{marker}: {marker} test marker")


def pytest_collection_modifyitems(config, items):
skipped, selected = [], []
markers = [m for m in CUSTOM_MARKS if config.getoption(f"--{m}")]
empty = not markers
for item in items:
if empty and any(m in item.keywords for m in CUSTOM_MARKS):
skipped.append(item)
elif empty:
selected.append(item)
elif not empty and any(m in item.keywords for m in markers):
selected.append(item)
else:
skipped.append(item)

config.hook.pytest_deselected(items=skipped)
items[:] = selected
3 changes: 2 additions & 1 deletion datashader/tests/test_quadmesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ def test_raster_quadmesh_upsamplex_and_downsampley(array_module):
assert_eq_xr(res, out)


@pytest.mark.parametrize('array_module', array_modules)
# FIXME: dask.array does not work for this test
hoxbro marked this conversation as resolved.
Show resolved Hide resolved
@pytest.mark.parametrize('array_module', [array_modules[0], *array_modules[2:]])
def test_raster_quadmesh_autorange_reversed(array_module):
c = ds.Canvas(plot_width=8, plot_height=4)
da = xr.DataArray(
Expand Down
7 changes: 5 additions & 2 deletions datashader/tests/test_transfer_functions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import os
from io import BytesIO

import numpy as np
Expand All @@ -13,6 +14,8 @@
coords = dict([('x_axis', [3, 4, 5]), ('y_axis', [0, 1, 2])])
dims = ['y_axis', 'x_axis']

test_gpu = bool(int(os.getenv("DATASHADER_TEST_GPU", 0)))

# CPU
def build_agg(array_module=np):
a = array_module.arange(10, 19, dtype='u4').reshape((3, 3))
Expand Down Expand Up @@ -42,12 +45,12 @@ def create_dask_array_np(*args, **kwargs):
return da.from_array(np.array(*args, **kwargs))


try:
if test_gpu:
import cupy
aggs = [build_agg(np), build_agg(cupy), build_agg_dask()]
arrays = [np.array, cupy.array, create_dask_array_np]
array_modules = [np, cupy]
except ImportError:
else:
cupy = None
aggs = [build_agg(np), build_agg_dask()]
arrays = [np.array, create_dask_array_np]
Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
'pytest <8', # Fails lint with IPynbFile is deprecated
'pytest-benchmark',
'pytest-cov',
'psutil',
'pytest-xdist',
'rasterio',
'rioxarray',
'scikit-image',
Expand Down
5 changes: 3 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ commands = flake8
[_unit]
description = Run unit tests
deps = .[tests]
commands = pytest datashader --cov=./datashader --cov-append
commands = pytest datashader -n logical --dist loadgroup --cov=./datashader --cov-append --benchmark-skip
pytest datashader --benchmark --cov=./datashader --cov-append

[_unit_deploy]
description = Run unit tests without coverage
Expand All @@ -27,7 +28,7 @@ commands = pytest datashader
[_unit_nojit]
description = Run select unit tests with numba jit disabled
deps = .[tests]
commands = pytest datashader -k "not benchmarks and not test_tiles" --cov=./datashader --cov-append
commands = pytest datashader -k "not test_tiles" -n logical --dist loadgroup --cov=./datashader --cov-append --benchmark-skip

[_examples]
description = Test that default examples run
Expand Down
Loading