Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
# python-version: "3.12"
# QT_API: PyQt5
# with_opencl: true
- os: macos-13
- os: macos-latest
python-version: "3.13"
QT_API: PyQt6
with_opencl: true
Expand Down
11 changes: 10 additions & 1 deletion src/silx/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,21 @@ def pytest_configure(config):
"ignore:Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more.:UserWarning",
# Remove __array__ ignore once h5py v3.12 is released
"ignore:__array__ implementation doesn't accept a copy keyword, so passing copy=False failed. __array__ must implement 'dtype' and 'copy' keyword arguments.:DeprecationWarning",
"ignore::pyopencl.RepeatedKernelRetrieval",
# Deprecated pyparsing usage in matplotlib: https://github.com/matplotlib/matplotlib/issues/30617
"ignore::DeprecationWarning:matplotlib._fontconfig_pattern",
"ignore::DeprecationWarning:matplotlib._mathtext",
"ignore::DeprecationWarning:pyparsing.util",
)
try:
import pyopencl
except Exception:
pass
else:
pyopen_version = tuple(int(i) for i in pyopencl.__version__.split(".")[:2])
if pyopen_version >= (2025, 2):
_FILTERWARNINGS = _FILTERWARNINGS + (
"ignore::pyopencl.RepeatedKernelRetrieval",
)


def pytest_collection_modifyitems(items):
Expand Down
9 changes: 8 additions & 1 deletion src/silx/io/test/test_nxdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@

__authors__ = ["P. Knobel"]
__license__ = "MIT"
__date__ = "24/03/2020"
__date__ = "02/12/2025"


import os
import tempfile
import unittest

Expand Down Expand Up @@ -490,6 +491,12 @@ def setUp(self):
tmp.file.close()
self.h5fname = tmp.name

def tearDown(self):
try:
os.unlink(self.h5fname)
except Exception as err:
print(f"{type(err).__name__}: {err}\nWhile deleting `{self.h5fname}`")

def testSimpleSave(self):
sig = numpy.array([0, 1, 2])
a0 = numpy.array([2, 3, 4])
Expand Down
46 changes: 33 additions & 13 deletions src/silx/opencl/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Project: S I L X project
# https://github.com/silx-kit/silx
#
# Copyright (C) 2012-2023 European Synchrotron Radiation Facility, Grenoble, France
# Copyright (C) 2012-2025 European Synchrotron Radiation Facility, Grenoble, France
#
# Principal author: Jérôme Kieffer ([email protected])
#
Expand Down Expand Up @@ -37,7 +37,7 @@
__contact__ = "[email protected]"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
__date__ = "20/11/2024"
__date__ = "08/12/2025"
__status__ = "stable"

import os
Expand Down Expand Up @@ -67,43 +67,63 @@


class KernelContainer:
"""Those object holds a copy of all kernels accessible as attributes"""
"""Those object holds a copy of all kernels accessible as attributes

Allows a work around for this issue: https://github.com/inducer/pyopencl/issues/830
"""

def __init__(self, program):
"""Constructor of the class

:param program: the OpenCL program as generated by PyOpenCL
"""
self._program = program
self._kernels = {}
for kernel in program.all_kernels():
self.__setattr__(kernel.function_name, kernel)
self._kernels[kernel.function_name] = kernel

def __repr__(self):
return (
self.__class__.__name__
+ " with kernels: "
+ ", ".join(self._kernels.keys())
+ "."
)

def __getattr__(self, name: str):
"""Retrieve a kernel, if available

:param name: name of the kernel
:return: the kernel (not a copy)
"""
if name in self._kernels:
return self._kernels[name]
raise AttributeError(f"`{self.__class__.__name__}` has no attribute `{name}`")

def get_kernels(self):
"return the dictionary with all kernels"
return dict(
item for item in self.__dict__.items() if not item[0].startswith("_")
)
return self._kernels

def get_kernel(self, name):
def get_kernel(self, name: str):
"get a kernel from its name"
logger.debug("KernelContainer.get_kernel(%s)", name)
return self.__dict__.get(name)
return self._kernels.get(name)

def max_workgroup_size(self, kernel_name):
def max_workgroup_size(self, kernel_name: str) -> int:
"Retrieve the compile time WORK_GROUP_SIZE for a given kernel"
if isinstance(kernel_name, pyopencl.Kernel):
kernel = kernel_name
else:
kernel = self.get_kernel(kernel_name)
kernel = self._kernels.get(kernel_name)

return query_kernel_info(self._program, kernel, "WORK_GROUP_SIZE")

def min_workgroup_size(self, kernel_name):
def min_workgroup_size(self, kernel_name) -> int:
"Retrieve the compile time PREFERRED_WORK_GROUP_SIZE_MULTIPLE for a given kernel"
if isinstance(kernel_name, pyopencl.Kernel):
kernel = kernel_name
else:
kernel = self.get_kernel(kernel_name)
kernel = self._kernels.get(kernel_name)

return query_kernel_info(
self._program, kernel, "PREFERRED_WORK_GROUP_SIZE_MULTIPLE"
Expand Down
Loading