Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions changelog.d/vtk-holds-device-memory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
### Fixed

- A VTK with DLPack but without the device's memory (the nightly wheels, whose
Viskores runs on the CPU alone yet lists CUDA among
`dlpack_support.supported_device_types()`) no longer fails every VTK
algorithm on a GPU as it hands its output back: the interop tries a
four-value array once per type of device (`_vtk_holds`) and copies to the
host where VTK cannot hold the memory.
5 changes: 4 additions & 1 deletion packages/tack-core/tests/test_arrays_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,10 @@ def test_implicit_arrays_index_from_the_host_as_arrays_do():
ta.CountingArray(5, start=3, step=2),
ta.UniformCoordinates((3, 2, 2), origin=(1, 0, 0), spacing=(0.5, 1, 1)),
ta.CartesianProduct([0.0, 1.0, 3.0], [0.0, 2.0]),
ta.Permutation(stored, tack.array(np.array([5, 0, 3], np.int32)))]
ta.Permutation(tack.array(np.array([5, 0, 3], np.int32)), stored)]
# Ids first: given the other way round, the floats were ids into the three
# ids, read out of bounds alike on the host and in the kernel (TACK_DEBUG).
np.testing.assert_array_equal(ta.to_host(cases[-1]), [7.5, 0.0, 4.5])
for values in cases:
host = np.asarray(ta.to_host(values))
assert len(values) == host.shape[0]
Expand Down
5 changes: 4 additions & 1 deletion packages/tack-vis/examples/51_vtk_openfoam.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"""

import argparse
import os

import numpy as np

Expand Down Expand Up @@ -79,7 +80,9 @@ def area(surface):
# THE CASE, WITH ITS PATCHES
# ================================================================

reader = vtkOpenFOAMReader(file_name=_vtk_data.path("OpenFOAM/squareBend/squareBend.foam"))
# The case's directory, so that every file of the case is fetched.
reader = vtkOpenFOAMReader(
file_name=os.path.join(_vtk_data.path("OpenFOAM/squareBend"), "squareBend.foam"))
reader.UpdateInformation()
for i in range(reader.GetNumberOfPatchArrays()):
reader.SetPatchArrayStatus(reader.GetPatchArrayName(i), 1)
Expand Down
5 changes: 4 additions & 1 deletion packages/tack-vis/examples/52_vtk_pathlines.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"""

import argparse
import os

import numpy as np

Expand Down Expand Up @@ -77,7 +78,9 @@ def ends(lines):
# THE CASE
# ================================================================

reader = vtkOpenFOAMReader(file_name=_vtk_data.path("OpenFOAM/cavity/cavity.foam"))
# The case's directory, so that every file of the case is fetched.
reader = vtkOpenFOAMReader(
file_name=os.path.join(_vtk_data.path("OpenFOAM/cavity"), "cavity.foam"))
reader.UpdateInformation()
steps = list(reader.GetOutputInformation(0).Get(
vtkStreamingDemandDrivenPipeline.TIME_STEPS()))
Expand Down
22 changes: 21 additions & 1 deletion packages/tack-vis/src/tack/interop/vtk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2059,7 +2059,27 @@ def _stored_on_device(values):
_dlpack_support()
except RuntimeError:
return False
return True
return _vtk_holds(values.device)


#: Whether this VTK holds each type of device's memory in its arrays, by the type.
_holds = {}


def _vtk_holds(device):
"""Whether this VTK makes arrays of ``device``'s memory: a four-value array is
tried once for each type of device. A VTK with DLPack whose Viskores has no such
device (the nightly wheels', on the CPU alone) still lists the type in
``dlpack_support.supported_device_types()``, and refuses it only when asked."""
if device.type not in _holds:
try:
# Not array_to_vtk: a Level Zero context VTK does not share is its
# error to give, where the array is made.
probe = _dlpack_support().dlpack_to_vtk(tack.zeros((4, 1), device=device))
_holds[device.type] = _device_type(probe) == device.type
except (ImportError, RuntimeError):
_holds[device.type] = False
return _holds[device.type]


def _vtk_cells(offsets, connectivity, share=False):
Expand Down
6 changes: 4 additions & 2 deletions packages/tack-vis/tests/test_vtk_interop.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ def _init_device(arch):


def _device_arches():
"""Backends on this machine whose memory VTK can describe."""
"""Backends on this machine whose memory VTK can describe, and holds: a VTK whose
Viskores runs on the CPU alone (the nightly wheels') has DLPack but no device."""
from tack.runtime.dispatch import get_backend

found = []
Expand All @@ -377,7 +378,8 @@ def _device_arches():
_init_device(arch)
except (ImportError, RuntimeError, OSError, AttributeError):
continue # not built, no device, no driver, or no shared context
if get_backend().device_memory_spaces:
if get_backend().device_memory_spaces and interop._vtk_holds(
tack.get_default_device()):
found.append(pytest.param(arch, space, id=arch))
tack.set_default_device("cpu")
return found
Expand Down
Loading