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

Compiler cache: honor XDG_CACHE_HOME on MacOS #716

Merged
merged 1 commit into from
Mar 22, 2024
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
22 changes: 11 additions & 11 deletions pyopencl/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,20 +348,20 @@ def _create_built_program_from_source_cached(ctx, src, options_bytes,
except ImportError:
import appdirs

cache_dir = join(appdirs.user_cache_dir("pyopencl", "pyopencl"),
# Determine the cache directory in the same way as pytools.PersistentDict,
# which PyOpenCL uses for invoker caches.
if sys.platform == "darwin" and os.getenv("XDG_CACHE_HOME") is not None:
# appdirs and platformdirs do not handle XDG_CACHE_HOME on macOS
# https://github.com/platformdirs/platformdirs/issues/269
cache_dir = join(os.getenv("XDG_CACHE_HOME"), "pyopencl")
else:
cache_dir = appdirs.user_cache_dir("pyopencl", "pyopencl")

cache_dir = join(cache_dir,
"pyopencl-compiler-cache-v2-py{}".format(
".".join(str(i) for i in sys.version_info)))

# {{{ ensure cache directory exists

try:
os.makedirs(cache_dir)
except OSError as e:
from errno import EEXIST
if e.errno != EEXIST:
raise

# }}}
os.makedirs(cache_dir, exist_ok=True)

if devices is None:
devices = ctx.devices
Expand Down
44 changes: 44 additions & 0 deletions test/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -2350,6 +2350,50 @@ def test_logical_not(ctx_factory):
np.logical_not(np.ones(10)))


# {{{ test XDG_CACHE_HOME handling

@pytest.mark.skipif(sys.platform == "win32",
reason="XDG_CACHE_HOME is not used on Windows")
def test_xdg_cache_home(ctx_factory):
import os
import shutil
from os.path import join

context = ctx_factory()
queue = cl.CommandQueue(context)

a = np.array([1, 2, 3, 4, 5]).astype(np.float32)
a_gpu = cl_array.to_device(queue, a)

xdg_dir = "tmpdir_pyopencl_xdg_test"

# PyOpenCL uses pytools.PersistentDict for invoker caches,
# which is why xdg_dir will always exist. Therefore, check
# whether xdg_pyopencl_dir exists.
xdg_pyopencl_dir = join(xdg_dir, "pyopencl")
assert not os.path.exists(xdg_dir)

old_xdg_cache_home = None

try:
old_xdg_cache_home = os.getenv("XDG_CACHE_HOME")
os.environ["XDG_CACHE_HOME"] = xdg_dir

result = pow(a_gpu, a_gpu).get()
assert (np.abs(a ** a - result) < 3e-3).all()

assert os.path.exists(xdg_pyopencl_dir)
finally:
if old_xdg_cache_home is not None:
os.environ["XDG_CACHE_HOME"] = old_xdg_cache_home
else:
del os.environ["XDG_CACHE_HOME"]

shutil.rmtree(xdg_dir)

# }}}


if __name__ == "__main__":
if len(sys.argv) > 1:
exec(sys.argv[1])
Expand Down
Loading