Skip to content

Commit 6a26931

Browse files
committed
cuda-core: simplify strided memory CPU example flow
Refactor the cffi CPU example into small helpers so setup/teardown is easier to follow and avoid global state for compiled symbols. Also direct progress prints to stderr to match example logging behavior. Made-with: Cursor
1 parent 34ecbb2 commit 6a26931

1 file changed

Lines changed: 26 additions & 26 deletions

File tree

cuda_core/examples/strided_memory_view_cpu.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
# ################################################################################
1616

1717
import importlib
18-
import shutil
1918
import string
2019
import sys
2120
import tempfile
21+
from contextlib import contextmanager
2222

2323
try:
2424
from cffi import FFI
@@ -61,9 +61,7 @@
6161
# We assume the 0-th argument supports either DLPack or CUDA Array Interface (both
6262
# of which are supported by StridedMemoryView).
6363
@args_viewable_as_strided_memory((0,))
64-
def my_func(arr):
65-
global cpu_func
66-
global cpu_prog
64+
def my_func(arr, cpu_prog, cpu_func):
6765
# Create a memory view over arr (assumed to be a 1D array of int32). The stream
6866
# ordering is taken care of, so that arr can be safely accessed on our work
6967
# stream (ordered after a data stream on which arr is potentially prepared).
@@ -79,8 +77,7 @@ def my_func(arr):
7977
cpu_func(cpu_prog.cast("int*", view.ptr), size)
8078

8179

82-
def run():
83-
global my_func, cpu_func, cpu_prog
80+
def _create_cpu_program():
8481
# Here is a concrete (very naive!) implementation on CPU:
8582
cpu_code = string.Template(r"""
8683
extern "C"
@@ -101,34 +98,37 @@ def run():
10198
source_extension=".cpp",
10299
extra_compile_args=["-std=c++11"],
103100
)
104-
temp_dir = tempfile.mkdtemp()
105-
cpu_func = None
101+
return cpu_prog
102+
103+
104+
@contextmanager
105+
def _compiled_cpu_func(cpu_prog, temp_dir):
106106
saved_sys_path = sys.path.copy()
107107
try:
108108
cpu_prog.compile(tmpdir=temp_dir)
109-
110109
sys.path.append(temp_dir)
111110
cpu_func = getattr(importlib.import_module("_cpu_obj.lib"), func_name)
111+
yield cpu_func
112+
finally:
113+
sys.path = saved_sys_path
114+
# Ensure cffi modules are unloadable before removing the temp build dir.
115+
sys.modules.pop("_cpu_obj.lib", None)
116+
sys.modules.pop("_cpu_obj", None)
112117

113-
# Create input array on CPU
114-
arr_cpu = np.zeros(1024, dtype=np.int32)
115-
print(f"before: {arr_cpu[:10]=}")
116118

117-
# Run the workload
118-
my_func(arr_cpu)
119+
def _run_example(cpu_prog, cpu_func):
120+
arr_cpu = np.zeros(1024, dtype=np.int32)
121+
print(f"before: {arr_cpu[:10]=}", file=sys.stderr)
122+
my_func(arr_cpu, cpu_prog, cpu_func)
123+
print(f"after: {arr_cpu[:10]=}", file=sys.stderr)
124+
assert np.allclose(arr_cpu, np.arange(1024, dtype=np.int32))
119125

120-
# Check the result
121-
print(f"after: {arr_cpu[:10]=}")
122-
assert np.allclose(arr_cpu, np.arange(1024, dtype=np.int32))
123-
finally:
124-
sys.path = saved_sys_path
125-
# to allow FFI module to unload, we delete references to
126-
# to cpu_func
127-
if cpu_func is not None:
128-
del cpu_func
129-
del cpu_prog, my_func
130-
# clean up temp directory
131-
shutil.rmtree(temp_dir)
126+
127+
def run():
128+
cpu_prog = _create_cpu_program()
129+
with tempfile.TemporaryDirectory() as temp_dir:
130+
with _compiled_cpu_func(cpu_prog, temp_dir) as cpu_func:
131+
_run_example(cpu_prog, cpu_func)
132132

133133

134134
if __name__ == "__main__":

0 commit comments

Comments
 (0)