pygpgpu 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pygpgpu-0.1.0/LICENSE +21 -0
- pygpgpu-0.1.0/MANIFEST.in +14 -0
- pygpgpu-0.1.0/PKG-INFO +425 -0
- pygpgpu-0.1.0/README.md +363 -0
- pygpgpu-0.1.0/README.zh-CN.md +356 -0
- pygpgpu-0.1.0/examples/01_basic_kernel.py +58 -0
- pygpgpu-0.1.0/examples/02_backend_device_selection.py +64 -0
- pygpgpu-0.1.0/examples/03_nd_loop_and_class_method.py +102 -0
- pygpgpu-0.1.0/examples/04_vector_types.py +67 -0
- pygpgpu-0.1.0/examples/05_gnp_zero_copy_and_atomics.py +112 -0
- pygpgpu-0.1.0/examples/06_handwritten_kernels.py +60 -0
- pygpgpu-0.1.0/examples/07_low_level_oop.py +67 -0
- pygpgpu-0.1.0/examples/08_compare_backends.py +78 -0
- pygpgpu-0.1.0/examples/09_reduction.py +160 -0
- pygpgpu-0.1.0/examples/README.md +64 -0
- pygpgpu-0.1.0/examples/README.zh-CN.md +51 -0
- pygpgpu-0.1.0/examples/vecadd.cl +37 -0
- pygpgpu-0.1.0/examples/vecadd_cuda.cu +11 -0
- pygpgpu-0.1.0/pygpgpu/__init__.py +113 -0
- pygpgpu-0.1.0/pygpgpu/constants.py +107 -0
- pygpgpu-0.1.0/pygpgpu/cparser/ShaderBuiltins.py +16874 -0
- pygpgpu-0.1.0/pygpgpu/cparser/__init__.py +4 -0
- pygpgpu-0.1.0/pygpgpu/cparser/cparser.py +1200 -0
- pygpgpu-0.1.0/pygpgpu/cparser/cpreprocessor.py +135 -0
- pygpgpu-0.1.0/pygpgpu/cparser/csyntaxtree.py +88 -0
- pygpgpu-0.1.0/pygpgpu/cparser/ctokens.py +319 -0
- pygpgpu-0.1.0/pygpgpu/cparser/generate_code.py +481 -0
- pygpgpu-0.1.0/pygpgpu/cparser/minifyc.py +311 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/__init__.py +6 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/evaluator.py +897 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/lextab.py +169 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/parser.py +491 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/parsetab.py +2757 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/pcmd.py +465 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/__init__.py +5 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/cpp.py +1050 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/ctokens.py +159 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/lex.py +1237 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/yacc.py +3751 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/ygen.py +75 -0
- pygpgpu-0.1.0/pygpgpu/cparser/pcpp/preprocessor.py +1698 -0
- pygpgpu-0.1.0/pygpgpu/cparser/ts_parser.py +691 -0
- pygpgpu-0.1.0/pygpgpu/cuda/__init__.py +7 -0
- pygpgpu-0.1.0/pygpgpu/cuda/cuimport.py +201 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/__init__.py +48 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/cuda.py +187 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/cuda.pyi +184 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/cuinfo.py +725 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/cutypes.py +364 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtc.py +200 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtc.pyi +54 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtcinfo.py +125 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtctypes.py +63 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/__init__.py +25 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/char3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/char3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/double3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/double3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/float3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/float3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/int3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/int3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long3.pyi +1229 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long4.pyi +3650 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/short3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/short3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uchar3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uchar3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uint3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uint3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong3.pyi +1229 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong4.pyi +3650 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ushort3.py +15 -0
- pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ushort3.pyi +1227 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/__init__.py +2 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/buffer.py +73 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/build_options.py +198 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/context.py +210 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/cuobject.py +137 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/device.py +88 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/device.pyi +733 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/devices.py +92 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/event.py +55 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/kernel.py +423 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/mem_object.py +151 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/nvrtc_program.py +228 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/program.py +135 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/program_info.py +147 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/program_parser.py +482 -0
- pygpgpu-0.1.0/pygpgpu/cuda/oop/stream.py +97 -0
- pygpgpu-0.1.0/pygpgpu/exceptions.py +5 -0
- pygpgpu-0.1.0/pygpgpu/hip/__init__.py +6 -0
- pygpgpu-0.1.0/pygpgpu/hip/driver/__init__.py +15 -0
- pygpgpu-0.1.0/pygpgpu/hip/driver/hip.py +129 -0
- pygpgpu-0.1.0/pygpgpu/hip/driver/hipinfo.py +138 -0
- pygpgpu-0.1.0/pygpgpu/hip/driver/hiptypes.py +28 -0
- pygpgpu-0.1.0/pygpgpu/hip/hipimport.py +179 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/__init__.py +8 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/buffer.py +73 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/build_options.py +21 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/context.py +57 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/device.py +82 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/devices.py +93 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/event.py +60 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/hip_compiler.py +209 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/hipobject.py +137 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/kernel.py +423 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/mem_object.py +148 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/program.py +142 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/program_info.py +147 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/program_parser.py +485 -0
- pygpgpu-0.1.0/pygpgpu/hip/oop/stream.py +98 -0
- pygpgpu-0.1.0/pygpgpu/kernel/__init__.py +14 -0
- pygpgpu-0.1.0/pygpgpu/kernel/builtins.py +125 -0
- pygpgpu-0.1.0/pygpgpu/kernel/decorator.py +594 -0
- pygpgpu-0.1.0/pygpgpu/kernel/translator.py +1846 -0
- pygpgpu-0.1.0/pygpgpu/numpy/__init__.py +9 -0
- pygpgpu-0.1.0/pygpgpu/numpy/array_creation.py +83 -0
- pygpgpu-0.1.0/pygpgpu/numpy/ndarray.py +287 -0
- pygpgpu-0.1.0/pygpgpu/opencl/__init__.py +27 -0
- pygpgpu-0.1.0/pygpgpu/opencl/climport.py +130 -0
- pygpgpu-0.1.0/pygpgpu/opencl/common.py +76 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/__init__.py +120 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/cl.py +196 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/cl.pyi +197 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/clinfo.py +1913 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/cltypes.py +964 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/__init__.py +7 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image1d_array_t.py +25 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image1d_t.py +25 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image2d_array_t.py +25 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image2d_t.py +25 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image3d_t.py +25 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/imagend_t.py +178 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/sampler_t.py +42 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/__init__.py +29 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/char3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/char3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/double3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/double3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/float3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/float3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/int3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/int3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long3.pyi +1229 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long4.pyi +3650 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/short3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/short3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uchar3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uchar3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uint3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uint3.pyi +1230 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong3.pyi +1229 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong4.pyi +3650 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ushort3.py +16 -0
- pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ushort3.pyi +1227 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/__init__.py +18 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/buffer.py +127 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/build_options.py +117 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/clobject.py +151 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/command_queue.py +82 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/command_queue.pyi +42 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/context.py +312 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/context.pyi +122 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/device.py +63 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/device.pyi +481 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/event.py +213 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/event.pyi +68 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/image1d.py +100 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/image1d_array.py +100 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/image2d.py +101 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/image2d_array.py +100 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/image3d.py +100 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/imagend.py +55 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel.py +495 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel.pyi +70 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel_wrapper.py +90 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel_wrapper.pyi +45 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/mem_object.py +147 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/mem_object.pyi +104 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/pipe.py +85 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/platform.py +157 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/platform.pyi +121 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/platforms.py +88 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/program.py +369 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/program.pyi +111 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/program_info.py +192 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/program_parser.py +534 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/program_wrapper.py +109 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/sampler.py +83 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/sampler.pyi +34 -0
- pygpgpu-0.1.0/pygpgpu/opencl/oop/svm_buffer.py +121 -0
- pygpgpu-0.1.0/pygpgpu/py.typed +0 -0
- pygpgpu-0.1.0/pygpgpu/utils.py +362 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/__init__.py +51 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/char8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/double8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float2.py +15 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/float8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/funcs.py +316 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec.py +387 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec16.py +18 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec16.pyi.in +13 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec2.py +13 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec2.pyi.in +15 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec3.py +13 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec3.pyi.in +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec4.py +13 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec4.pyi.in +17 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec8.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/genVec8.pyi.in +13 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/helper.py +167 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/int8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/short8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uchar8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/uint8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort16.py +28 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort16.pyi +192 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort2.py +14 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort2.pyi +320 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort4.py +16 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort4.pyi +3652 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort8.py +20 -0
- pygpgpu-0.1.0/pygpgpu/vec_types/ushort8.pyi +108 -0
- pygpgpu-0.1.0/pygpgpu.egg-info/PKG-INFO +425 -0
- pygpgpu-0.1.0/pygpgpu.egg-info/SOURCES.txt +301 -0
- pygpgpu-0.1.0/pygpgpu.egg-info/dependency_links.txt +1 -0
- pygpgpu-0.1.0/pygpgpu.egg-info/requires.txt +12 -0
- pygpgpu-0.1.0/pygpgpu.egg-info/top_level.txt +1 -0
- pygpgpu-0.1.0/pyproject.toml +184 -0
- pygpgpu-0.1.0/setup.cfg +4 -0
pygpgpu-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Time-Coder
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Source distribution contents beyond the package itself.
|
|
2
|
+
#
|
|
3
|
+
# The numbered scripts under examples/ are the project's end-to-end smoke tests and
|
|
4
|
+
# the only worked examples covering all three backends, so they ship with the sdist
|
|
5
|
+
# (the wheel installs just the pygpgpu package). Their generated .pyi stubs are
|
|
6
|
+
# excluded because they are byproducts of running the examples.
|
|
7
|
+
include README.md
|
|
8
|
+
include README.zh-CN.md
|
|
9
|
+
include LICENSE
|
|
10
|
+
recursive-include examples *.py *.md *.cl *.cu *.hip
|
|
11
|
+
recursive-exclude examples *.pyi
|
|
12
|
+
|
|
13
|
+
# doc/ is deliberately not included: it holds vendor reference PDFs for the CUDA
|
|
14
|
+
# driver API and NVRTC guides, not project documentation.
|
pygpgpu-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pygpgpu
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Import GPU kernels like Python functions across OpenCL / CUDA / HIP backends
|
|
5
|
+
Author: Time-Coder
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Time-Coder
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/Time-Coder/PyGPGPU
|
|
29
|
+
Keywords: gpu,opencl,cuda,hip,rocm,kernel,jit
|
|
30
|
+
Classifier: Development Status :: 3 - Alpha
|
|
31
|
+
Classifier: Intended Audience :: Developers
|
|
32
|
+
Classifier: Intended Audience :: Science/Research
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
35
|
+
Classifier: Programming Language :: Python :: 3
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
44
|
+
Classifier: Topic :: Scientific/Engineering
|
|
45
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
46
|
+
Classifier: Typing :: Typed
|
|
47
|
+
Requires-Python: >=3.7
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
License-File: LICENSE
|
|
50
|
+
Requires-Dist: numpy>=1.21
|
|
51
|
+
Requires-Dist: imageio>=2.30
|
|
52
|
+
Requires-Dist: tree-sitter>=0.20.0
|
|
53
|
+
Requires-Dist: tree-sitter-opencl>=0.0.2
|
|
54
|
+
Requires-Dist: tree-sitter-cuda37>=0.21.2
|
|
55
|
+
Requires-Dist: pygf>=0.1.4
|
|
56
|
+
Requires-Dist: typing_extensions>=4.4.0
|
|
57
|
+
Provides-Extra: dev
|
|
58
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
59
|
+
Requires-Dist: ruff>=0.9; extra == "dev"
|
|
60
|
+
Requires-Dist: ty>=0.0.60; extra == "dev"
|
|
61
|
+
Dynamic: license-file
|
|
62
|
+
|
|
63
|
+
# PyGPGPU
|
|
64
|
+
|
|
65
|
+
**English** | [Chinese](README.zh-CN.md)
|
|
66
|
+
|
|
67
|
+
Decorate a Python function and it runs on the GPU — one codebase, three backends (**OpenCL / CUDA / HIP**).
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import numpy as np
|
|
71
|
+
from pygpgpu import kernel
|
|
72
|
+
|
|
73
|
+
@kernel
|
|
74
|
+
def saxpy(x, y, out, alpha):
|
|
75
|
+
for i in range(out.shape[0]):
|
|
76
|
+
out[i] = x[i] * alpha + y[i]
|
|
77
|
+
|
|
78
|
+
x = np.arange(1_000_000, dtype=np.float32)
|
|
79
|
+
out = np.zeros_like(x)
|
|
80
|
+
|
|
81
|
+
saxpy(x, x, out, 2.0) # no backend given: probe cuda -> hip -> opencl, take the first available
|
|
82
|
+
saxpy["cuda"](x, x, out, 2.0) # bracket switches the backend
|
|
83
|
+
saxpy["hip:gfx1036"](x, x, out, 2.0) # backend:device
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
No C code to write, no build system to configure; the first call translates, compiles and caches, every later call is free. Existing handwritten kernels are fine too — `.cl`/`.cu`/`.hip` files can be `import`ed like Python modules.
|
|
87
|
+
|
|
88
|
+
## Features
|
|
89
|
+
|
|
90
|
+
- **`@kernel` decorator** — decorate a Python function directly (class methods and static methods included); at call time it is specialized per argument type, translated to backend source and compiled (monomorphization).
|
|
91
|
+
- **Plain-Python helper functions** — a helper called from a kernel needs no decorator and no type annotations: it is translated into a device function and monomorphized from the call site, recursively for helpers that call helpers.
|
|
92
|
+
- **All three backends in one process** — the bracket chooses the backend per call, so a single process (and even a single kernel object) can mix OpenCL, CUDA and HIP; each backend/device pair is specialized and cached separately.
|
|
93
|
+
- **Handwritten kernel file import** — `.cl` / `.cu` / `.hip` files import like Python modules: kernels and struct types become module attributes, and a `.pyi` type stub is generated automatically.
|
|
94
|
+
- **Low-level OOP API** — Device/Context/Buffer/Program/Kernel, for when you need full control.
|
|
95
|
+
- **One bracket syntax** for backend/device/work size (identical to handwritten kernels, order does not matter):
|
|
96
|
+
```python
|
|
97
|
+
k(args) # fully automatic
|
|
98
|
+
k["cuda"](args) # backend (opencl/cuda/hip, aliases ocl/cu/rocm/amd)
|
|
99
|
+
k["opencl:gfx1036"](args) # backend:device
|
|
100
|
+
k[(1024, 256)](args) # work size: (total, per group), None = automatic
|
|
101
|
+
k["cuda"][(1024, 256)](args) # combined
|
|
102
|
+
```
|
|
103
|
+
- **Total-work semantics** (OpenCL/SYCL style): in `(global, local)`, `global` is the **total number of work items**; CUDA/HIP grid dimensions are derived as `global / local`, so all three backends behave exactly the same.
|
|
104
|
+
- **Static read/write analysis**: the kernel body is parsed to infer whether each pointer argument is read-only, write-only or read-write — write-only arguments skip the upload, read-only arguments skip the read-back, and data stays on the device across calls (zero intermediate copies for gnp arrays).
|
|
105
|
+
- **Vector types**: 50 vector types (float4/int3/...) with `.x/.y/.z/.w` members, swizzles, construction, arithmetic (scalar broadcast), comparisons and component-wise math.
|
|
106
|
+
- **Dual-sided function library** `pygpgpu.funcs` (aka `pygpgpu.vec_types.funcs`): `dot/cross/normalize/clamp/...` run as-is in host Python and are translated to device builtins inside `@kernel`.
|
|
107
|
+
- **Device builtin namespace** `gpu.*`: `get_global_id/barrier/atomic_add/dot/...` covers GPU builtins that have no Python counterpart, mapped per backend.
|
|
108
|
+
- **Multi-dimensional iteration**: `np.ndindex(shape)` / `np.ndenumerate(arr)` magic loops (2D/3D), `enumerate(arr)` for a 1D index plus value snapshot.
|
|
109
|
+
- **Three cache layers**: parsed metadata / compiled artifacts / generated sources, all invalidated by mtime — unchanged sources mean zero recompilation.
|
|
110
|
+
|
|
111
|
+
## Installation
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pip install -e .
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Python ≥ 3.12. Bring your own GPU runtime (any one of them is enough):
|
|
118
|
+
|
|
119
|
+
| Backend | What you need | Notes |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| OpenCL | GPU driver (usually already installed) | Nothing extra to install; works across NVIDIA/AMD/Intel |
|
|
122
|
+
| CUDA | NVIDIA driver (includes NVRTC) | The Toolkit is not required — the driver-provided nvrtc is enough |
|
|
123
|
+
| HIP | AMD HIP SDK | On Windows compilation runs through the SDK's clang; if MSVC/Windows SDK headers are not on the default paths, point `PYGPGPU_HIP_INCLUDES` at the include directories (os.pathsep-separated) |
|
|
124
|
+
|
|
125
|
+
When `@kernel` has no explicit `backend`, backends are probed in **cuda -> hip -> opencl** order and the first one that enumerates a device wins.
|
|
126
|
+
|
|
127
|
+
## Quick start
|
|
128
|
+
|
|
129
|
+
Every commonly used API is importable straight from the `pygpgpu` top level — no need to remember submodule names:
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from pygpgpu import kernel, gpu, funcs, float4 # @kernel / device builtins / dual-sided funcs / vector types
|
|
133
|
+
from pygpgpu import available_devices, get_device
|
|
134
|
+
from pygpgpu import climport, cuimport, hipimport # import hooks for handwritten .cl/.cu/.hip files
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The submodule paths (`pygpgpu.kernel` / `pygpgpu.vec_types` / `pygpgpu.opencl` / ...) still work. Note that top-level `pygpgpu.kernel` is the `@kernel` decorator; to reach things inside the submodule write `from pygpgpu.kernel import ...`.
|
|
138
|
+
|
|
139
|
+
The three import hooks load lazily: the corresponding backend is only loaded when you actually use the hook, so `import pygpgpu` itself needs no GPU runtime at all.
|
|
140
|
+
|
|
141
|
+
### The @kernel decorator
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
import math
|
|
145
|
+
import numpy as np
|
|
146
|
+
from pygpgpu import kernel, gpu, funcs, float4
|
|
147
|
+
|
|
148
|
+
def norm2(v):
|
|
149
|
+
return funcs.dot(v, v)
|
|
150
|
+
|
|
151
|
+
@kernel
|
|
152
|
+
def normalize_all(vecs, out):
|
|
153
|
+
for i, v in enumerate(vecs): # 1D: index + float4 value snapshot
|
|
154
|
+
out[i] = funcs.normalize(v) # expanded component-wise on device
|
|
155
|
+
|
|
156
|
+
@kernel
|
|
157
|
+
def matrix_scale(m, out, k):
|
|
158
|
+
for y, x in np.ndindex(out.shape): # 2D NDRange
|
|
159
|
+
out[y, x] = m[y, x] * k
|
|
160
|
+
|
|
161
|
+
@kernel(backend="cuda")
|
|
162
|
+
def histogram(data, counts):
|
|
163
|
+
gpu.work_size(data) # iteration domain for a gid-style kernel
|
|
164
|
+
i = gpu.get_global_id(0)
|
|
165
|
+
gpu.atomic_add(counts, data[i], 1) # atomics, results read back automatically
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Supported: scalar/array/vector arguments, if/while/for-range, arithmetic/comparison/bit ops, `math.*` and `np.*` math functions, class methods (`self.xxx` attributes become arguments automatically), static methods. Unsupported syntax raises a `SyntaxError` carrying the line number.
|
|
169
|
+
|
|
170
|
+
A kernel needs an iteration domain for its work size to be derived. Either use a magic loop (`for i in range(x.shape[0])`, whose bound is the domain) or, when dispatching on `gpu.get_global_id`, declare `gpu.work_size(x)` — that statement is host-side only, erased by the translator, and contributes all of `x`'s dimensions. A `k[(total, local)]` bracket also works. Without any of these the call raises instead of guessing.
|
|
171
|
+
|
|
172
|
+
### Handwritten kernel files
|
|
173
|
+
|
|
174
|
+
Already have C-style kernels? `.cl` / `.cu` / `.hip` files (native syntax of the matching backend) import like Python modules. Write a `vecadd.cl`:
|
|
175
|
+
|
|
176
|
+
```c
|
|
177
|
+
__kernel void vecadd(__global const float* a, __global const float* b,
|
|
178
|
+
__global float* out, const int n)
|
|
179
|
+
{
|
|
180
|
+
int i = get_global_id(0);
|
|
181
|
+
if (i >= n) return;
|
|
182
|
+
out[i] = a[i] + b[i];
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
from pygpgpu import climport # cuimport / hipimport work the same way
|
|
188
|
+
import numpy as np
|
|
189
|
+
import vecadd # just like importing a Python module
|
|
190
|
+
|
|
191
|
+
a = np.random.rand(1_000_000).astype(np.float32)
|
|
192
|
+
out = np.zeros_like(a)
|
|
193
|
+
vecadd.vecadd(a, a, out, np.int32(len(a))) # work size inferred
|
|
194
|
+
vecadd.vecadd[(1_000_192, 256)](a, a, out, np.int32(len(a))) # explicit (total, per group)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Note the `n` argument: a handwritten kernel must clamp against the real element count, because the
|
|
198
|
+
launch size is rounded up to a multiple of the local size. `get_global_size(0)` reports that rounded
|
|
199
|
+
size, not the buffer length, so it is not a usable bound.
|
|
200
|
+
|
|
201
|
+
Struct definitions map to ctypes types; a `.pyi` stub is generated next to the kernel so IDE completion works.
|
|
202
|
+
|
|
203
|
+
### Class methods
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
class Model:
|
|
207
|
+
def __init__(self):
|
|
208
|
+
self.weights = np.random.rand(1024).astype(np.float32)
|
|
209
|
+
self.lr = 0.01
|
|
210
|
+
|
|
211
|
+
@kernel
|
|
212
|
+
def apply(self, x, out):
|
|
213
|
+
for i in range(out.shape[0]):
|
|
214
|
+
out[i] = x[i] * self.weights[i] + self.lr
|
|
215
|
+
|
|
216
|
+
m = Model()
|
|
217
|
+
m.apply(x, out) # self.weights/self.lr are passed as kernel arguments
|
|
218
|
+
m.apply["cuda"](x, out) # brackets still available
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Copy optimization
|
|
222
|
+
|
|
223
|
+
Each pointer argument goes through function-body-level static analysis (`points[i] = ...` is a write, `x = a[i]` is a read, plus pointer-alias propagation and interprocedural analysis across functions):
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
@kernel
|
|
227
|
+
def k(a, b, out):
|
|
228
|
+
for i in range(out.shape[0]):
|
|
229
|
+
out[i] = a[i] + b[i] * 2.0 # a read-only, b read-only, out write-only
|
|
230
|
+
# at runtime: a/b skip the read-back after upload, out skips the upload and only reads back
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Combined with `pygpgpu.numpy` (gnp) arrays, data stays entirely on the device between consecutive kernel calls and is synchronized only when the host touches it.
|
|
234
|
+
|
|
235
|
+
## How it compares
|
|
236
|
+
|
|
237
|
+
The same computation, written in this library and in three other GPU-from-Python projects
|
|
238
|
+
([Taichi](https://www.taichi-lang.org/), [Numba](https://numba.pydata.org/),
|
|
239
|
+
[NVIDIA Warp](https://github.com/NVIDIA/warp)). Snippets are cut down to the parts that
|
|
240
|
+
differ — check each project's docs for exact syntax. The examples also show a shared helper
|
|
241
|
+
function, which is where the API gap is widest: here it stays ordinary Python, while the
|
|
242
|
+
others need a second decorator and typed signatures.
|
|
243
|
+
|
|
244
|
+
**PyGPGPU** — arrays in, arrays out; no launch geometry, no buffer management, and helper
|
|
245
|
+
functions need no decorator at all:
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
from pygpgpu import kernel
|
|
249
|
+
|
|
250
|
+
def square(v): # plain Python: no decorator, no annotations
|
|
251
|
+
return v * v
|
|
252
|
+
|
|
253
|
+
def clamp01(v):
|
|
254
|
+
if v < 0.0:
|
|
255
|
+
return 0.0
|
|
256
|
+
if v > 1.0:
|
|
257
|
+
return 1.0
|
|
258
|
+
return v
|
|
259
|
+
|
|
260
|
+
def weight(v): # helpers may call other helpers
|
|
261
|
+
return clamp01(square(v)) * 0.5 + 0.25
|
|
262
|
+
|
|
263
|
+
@kernel
|
|
264
|
+
def apply_all(x, out):
|
|
265
|
+
for i in range(out.shape[0]): # loop bound = work size
|
|
266
|
+
out[i] = weight(x[i])
|
|
267
|
+
|
|
268
|
+
apply_all(x, out) # numpy arrays as-is
|
|
269
|
+
apply_all["hip"](x, out) # the same function, another backend
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Taichi** — declare fields first, then copy data in and out by hand; a helper needs `@ti.func`
|
|
273
|
+
and every argument must be annotated:
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
import taichi as ti
|
|
277
|
+
ti.init(arch=ti.gpu)
|
|
278
|
+
|
|
279
|
+
x = ti.field(ti.f32, n)
|
|
280
|
+
y = ti.field(ti.f32, n)
|
|
281
|
+
out = ti.field(ti.f32, n)
|
|
282
|
+
x.from_numpy(nx)
|
|
283
|
+
y.from_numpy(ny)
|
|
284
|
+
|
|
285
|
+
@ti.func # helpers need their own decorator
|
|
286
|
+
def weight(v: ti.f32) -> ti.f32:
|
|
287
|
+
return ti.max(0.0, ti.min(1.0, v * v)) * 0.5 + 0.25
|
|
288
|
+
|
|
289
|
+
@ti.kernel
|
|
290
|
+
def saxpy(a: ti.f32):
|
|
291
|
+
for i in range(n):
|
|
292
|
+
out[i] = x[i] * a + y[i] + weight(x[i])
|
|
293
|
+
|
|
294
|
+
saxpy(2.0)
|
|
295
|
+
res = out.to_numpy()
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Numba** — compute blocks/threads yourself, guard inside, manage device memory; callable helpers
|
|
299
|
+
are compiled separately with `@cuda.jit(device=True)`:
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
from numba import cuda
|
|
303
|
+
|
|
304
|
+
@cuda.jit(device=True) # helpers need device=True
|
|
305
|
+
def weight(v):
|
|
306
|
+
return min(1.0, max(0.0, v * v)) * 0.5 + 0.25
|
|
307
|
+
|
|
308
|
+
@cuda.jit
|
|
309
|
+
def saxpy(x, y, out, a):
|
|
310
|
+
i = cuda.grid(1)
|
|
311
|
+
if i < out.size: # bounds guard is your job
|
|
312
|
+
out[i] = x[i] * a + y[i] + weight(x[i])
|
|
313
|
+
|
|
314
|
+
d_x = cuda.to_device(nx)
|
|
315
|
+
d_y = cuda.to_device(ny)
|
|
316
|
+
d_out = cuda.device_array_like(nx)
|
|
317
|
+
threads = 256
|
|
318
|
+
saxpy[(n + threads - 1) // threads, threads](d_x, d_y, d_out, 2.0)
|
|
319
|
+
res = d_out.copy_to_host()
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Warp** — typed array parameters, the launch size is passed explicitly, and helpers need `@wp.func`:
|
|
323
|
+
|
|
324
|
+
```python
|
|
325
|
+
import warp as wp
|
|
326
|
+
wp.init()
|
|
327
|
+
|
|
328
|
+
@wp.func # helpers need their own decorator
|
|
329
|
+
def weight(v: float) -> float:
|
|
330
|
+
return wp.min(1.0, wp.max(0.0, v * v)) * 0.5 + 0.25
|
|
331
|
+
|
|
332
|
+
@wp.kernel
|
|
333
|
+
def saxpy(x: wp.array(dtype=float), y: wp.array(dtype=float),
|
|
334
|
+
out: wp.array(dtype=float), a: float):
|
|
335
|
+
i = wp.tid()
|
|
336
|
+
out[i] = x[i] * a + y[i] + weight(x[i])
|
|
337
|
+
|
|
338
|
+
wp.launch(saxpy, dim=n, inputs=[x, y, out, 2.0])
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
| | PyGPGPU | Taichi | Numba | Warp |
|
|
342
|
+
|---|---|---|---|---|
|
|
343
|
+
| Input data | numpy arrays directly | wrap in `ti.field`, explicit `from_numpy`/`to_numpy` | `cuda.to_device` + `copy_to_host` by hand | wrap in `wp.array` |
|
|
344
|
+
| Helper functions | **plain Python — no decorator, no annotations** | `@ti.func` + annotated args | `@cuda.jit(device=True)` | `@wp.func` + annotated args |
|
|
345
|
+
| Backends in one process | **all three, mixed freely** | one, fixed by `ti.init(arch=...)` | CUDA only | CUDA only |
|
|
346
|
+
| Launch size | inferred from the loop bound (or `gpu.work_size(x)` / a bracket) | inferred from `range` | blocks × threads by hand, plus a guard | pass `dim=` |
|
|
347
|
+
| Bounds guard | emitted for you | emitted for you | you write it | you write it |
|
|
348
|
+
| Backends | OpenCL, CUDA, HIP | CPU, CUDA, Vulkan and others | CPU, CUDA | CPU, CUDA |
|
|
349
|
+
| AMD GPU | HIP (native AMD codegen) and OpenCL | via Vulkan | no | no |
|
|
350
|
+
| Switching backend | bracket `k["hip"]`, same source | `ti.init(arch=...)`, same source | not applicable | not applicable |
|
|
351
|
+
| Install footprint | Python + ctypes only: no LLVM, no CUDA Toolkit | ships its own runtime | needs LLVM | needs the CUDA Toolkit |
|
|
352
|
+
| Handwritten `.cl`/`.cu`/`.hip` | imported as Python modules, `.pyi` generated | no | via the `cuda` module's PTX/cubin path | no |
|
|
353
|
+
| Static read/write analysis | yes — uploads/read-backs skipped per argument | no | no | no |
|
|
354
|
+
|
|
355
|
+
### Several backends at the same time
|
|
356
|
+
|
|
357
|
+
Taichi fixes its backend once, at `ti.init(arch=...)`; Numba and Warp only target CUDA. Here the
|
|
358
|
+
bracket picks the backend per call, so one process — and even one kernel object — can use every
|
|
359
|
+
backend the machine has:
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
@kernel
|
|
363
|
+
def apply_all(x, out):
|
|
364
|
+
for i in range(out.shape[0]):
|
|
365
|
+
out[i] = square(x[i]) + 1.0
|
|
366
|
+
|
|
367
|
+
apply_all["cuda"](x, out) # NVIDIA
|
|
368
|
+
apply_all["hip"](x, out) # AMD
|
|
369
|
+
apply_all["opencl"](x, out) # whichever device OpenCL enumerates
|
|
370
|
+
apply_all(x, out) # unqualified: probe cuda -> hip -> opencl
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Each backend/device pair is specialized and cached separately, so alternating between them is just
|
|
374
|
+
an extra dictionary lookup — no recompilation after the first call. This is useful for comparing a
|
|
375
|
+
kernel across vendors on one machine (`examples/08_compare_backends.py`), or for falling back to a
|
|
376
|
+
second GPU when the first is busy.
|
|
377
|
+
|
|
378
|
+
Where the others are ahead — worth knowing before you pick:
|
|
379
|
+
- **Automatic differentiation**: Taichi and Warp can differentiate kernels; this library cannot.
|
|
380
|
+
- **Sparse and irregular data structures**: Taichi has sparse grids and SNode trees; here you pass dense numpy arrays (or handle sparsity yourself).
|
|
381
|
+
- **CPU fallback**: all three can run on the CPU; this library needs a GPU.
|
|
382
|
+
- **Minimum interpreter version**: this library requires Python 3.12+ (it runs on 3.14); the others support a wider range of older versions.
|
|
383
|
+
|
|
384
|
+
This table was written from each project's documentation and the snippets above; their APIs move
|
|
385
|
+
fast, so confirm against current docs before relying on a specific cell.
|
|
386
|
+
|
|
387
|
+
## Device selection
|
|
388
|
+
|
|
389
|
+
Three forms of device identifier inside the brackets (same on every backend):
|
|
390
|
+
|
|
391
|
+
| Form | Meaning |
|
|
392
|
+
|---|---|
|
|
393
|
+
| `"0"`, `"1"` | index in the backend's device list (OpenCL uses flat numbering across platforms) |
|
|
394
|
+
| `"gfx1036"`, `"geforce"` | case-insensitive substring match on name/vendor/**architecture name** |
|
|
395
|
+
| `"geforce:1"` | when a name matches several devices, take the n-th one |
|
|
396
|
+
|
|
397
|
+
Helpers:
|
|
398
|
+
|
|
399
|
+
```python
|
|
400
|
+
from pygpgpu import available_devices, get_device
|
|
401
|
+
|
|
402
|
+
available_devices() # every available "backend:device" string, e.g. ['cuda:0', 'hip:0', 'opencl:0']
|
|
403
|
+
dev = get_device("cuda:0") # the Device object of that backend, directly
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Caching
|
|
407
|
+
|
|
408
|
+
| Backend | Directory | Contents |
|
|
409
|
+
|---|---|---|
|
|
410
|
+
| OpenCL | `__clcache__/` | parsed meta + per-device binaries |
|
|
411
|
+
| CUDA | `__cucache__/` | parsed meta + per-device cubin/ptx |
|
|
412
|
+
| HIP | `__hipcache__/` | parsed meta + per-device code objects |
|
|
413
|
+
|
|
414
|
+
Caches are invalidated by the mtime of the source file (and every `#include`); sources generated by `@kernel` are keyed by a hash of the Python source. These directories should be in `.gitignore`.
|
|
415
|
+
|
|
416
|
+
## Known limitations
|
|
417
|
+
|
|
418
|
+
- `@kernel` does not support: strings/lists/dicts, closures, recursion, kernel return values, dynamic multi-dimensional shape indexing;
|
|
419
|
+
- vector comparison, writing through a swizzle, and nesting beyond three operands are restricted in favour of cross-backend consistency (the error message suggests a workaround);
|
|
420
|
+
- fp16 (`np.float16`) arguments are unavailable on the CUDA/HIP backends (use float32);
|
|
421
|
+
- the HIP backend compiles with the clang shipped by the AMD HIP SDK; hipRTC on this machine (ROCm 7.2 Windows) fails on any input, so it is not used.
|
|
422
|
+
|
|
423
|
+
## License
|
|
424
|
+
|
|
425
|
+
MIT
|