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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
- uses: actions/checkout@v6
- name: "Main Script"
run: |
export PYOPENCL_CACHE_FAILURE_FATAL=1
export CONDA_ENVIRONMENT=.test-conda-env-py3.yml
.ci/hack-intel-cl-into-conda-env.sh

Expand All @@ -86,6 +87,7 @@ jobs:
shell: bash
run: |
set -x
export PYOPENCL_CACHE_FAILURE_FATAL=1
export CONDA_ENVIRONMENT=.test-conda-env-py3.yml

sed -i 's/- ocl-icd/- khronos-opencl-icd-loader/g' "$CONDA_ENVIRONMENT"
Expand Down
2 changes: 2 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ variables:
Python 3 Intel CPU:
script: |
source /opt/enable-intel-cl.sh
export PYOPENCL_CACHE_FAILURE_FATAL=1
export PYOPENCL_TEST="intel(r):pu"
export EXTRA_INSTALL="numpy mako"

Expand All @@ -22,6 +23,7 @@ Python 3 Intel CPU:

Python 3 Nvidia Titan V:
script: |
export PYOPENCL_CACHE_FAILURE_FATAL=1
export PYOPENCL_TEST=nvi:titan
export EXTRA_INSTALL="numpy mako"

Expand Down
44 changes: 25 additions & 19 deletions pyopencl/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,26 +169,26 @@ def error_clean_up(self):

# {{{ #include dependency handling

C_INCLUDE_RE = re.compile(r'^\s*\#\s*include\s+[<"](.+)[">]\s*$',
C_INCLUDE_RE = re.compile(rb'^\s*\#\s*include\s+[<"](.+)[">]\s*$',
re.MULTILINE)


def get_dependencies(src, include_path):
result = {}
def get_dependencies(src: bytes, include_path: Sequence[str]):
result: dict[str, tuple[float, str] | None] = {}

from os.path import join, realpath

def _inner(src):
def _inner(src: bytes):
for match in C_INCLUDE_RE.finditer(src):
included = match.group(1)

found = False
for ipath in include_path:
included_file_name = realpath(join(ipath, included))
included_file_name = realpath(join(ipath, included.decode()))

if included_file_name not in result:
try:
src_file = open(included_file_name)
src_file = open(included_file_name, "rb")
except OSError:
continue

Expand Down Expand Up @@ -218,13 +218,16 @@ def _inner(src):

_inner(src)

result = [(name, *vals) for name, vals in result.items()]
result.sort()
result_list = [
(name, *vals) for name, vals in result.items()
if vals is not None
]
result_list.sort()

return result
return result_list


def get_file_md5sum(fname):
def get_file_md5sum(fname: str):
checksum = new_hash()
inf = open(fname)
try:
Expand Down Expand Up @@ -342,7 +345,7 @@ class _InvalidInfoFileError(RuntimeError):

@dataclass(frozen=True)
class _SourceInfo:
dependencies: list[tuple[str, ...]]
dependencies: list[tuple[str, float, str]]
log: str | None


Expand Down Expand Up @@ -422,7 +425,7 @@ def _create_built_program_from_source_cached(
# defeat implementation caches:
from uuid import uuid4
src = src + b"\n\n__constant int pyopencl_defeat_cache_%s = 0;" % (
uuid4().hex)
uuid4().hex.encode())

logger.debug(
"build program: start building program from source on %s",
Expand Down Expand Up @@ -483,7 +486,7 @@ def _create_built_program_from_source_cached(
from pickle import dump
info_file = open(info_path, "wb")
dump(_SourceInfo(
dependencies=get_dependencies(src, include_path),
dependencies=get_dependencies(src, include_path or []),
log=logs[i]), info_file)
info_file.close()

Expand Down Expand Up @@ -532,12 +535,15 @@ def create_built_program_from_source_cached(
raise

if not build_program_failure:
from traceback import format_exc
from warnings import warn
warn(
"PyOpenCL compiler caching failed with an exception:\n"
f"[begin exception]\n{format_exc()}[end exception]",
stacklevel=2)
if os.environ["PYOPENCL_CACHE_FAILURE_FATAL"]:
raise
else:
from traceback import format_exc
from warnings import warn
warn(
"PyOpenCL compiler caching failed with an exception:\n"
f"[begin exception]\n{format_exc()}[end exception]",
stacklevel=2)

prg = _cl._Program(ctx, src)
was_cached = False
Expand Down
8 changes: 8 additions & 0 deletions src/wrap_cl_part_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,14 @@ void pyopencl_expose_part_2(py::module_ &m)
},
py::arg("context"),
py::arg("src"))
.def(
"__init__",
[](cls *self, context &ctx, py::bytes const &src)
{
create_program_with_source(self, ctx, std::string((const char *) src.data(), src.size()));
},
py::arg("context"),
py::arg("src"))
.def(
"__init__",
[](cls *self, context &ctx, py::sequence devices, py::sequence binaries)
Expand Down
Loading