Skip to content
Snippets Groups Projects
Commit c8c1a548 authored by Frederik Hennig's avatar Frederik Hennig
Browse files

Use newly introduced `HIP` target.

 - remove `sfg.use_cuda` and `sfg.use_hip`; infer API from kernel target instead
 - Adapt test cases
 - Adapt composer user guide
parent 28941cae
No related branches found
No related tags found
1 merge request!24Extend Support for CUDA and HIP kernel invocations
Pipeline #76131 failed
......@@ -346,20 +346,13 @@ The next section explains how that is achieved in pystencils-sfg.
#### Invoking GPU Kernels
Pystencils also allows us to generate kernels for the CUDA and HIP GPU platforms.
First, we need to decide for one of the two systems by calling either
{any}`sfg.use_cuda <SfgGpuComposer.use_cuda>` or {any}`sfg.use_hip <SfgGpuComposer.use_hip>`.
Pystencils also allows us to generate kernels for the CUDA and HIP GPU programming models.
To generate a kernel targetting either of these, set the
{any}`target <pystencils.codegen.config.CreateKernelConfig.target>`
code generator option to either `Target.CUDA` or `Target.HIP`.
After registering a GPU kernel,
you can render its invocation using {any}`sfg.gpu_invoke <SfgGpuComposer.gpu_invoke>`.
Here is a basic example:
```{code-cell} ipython3
:tags: [remove-cell]
f, g = ps.fields("f, g: double[2D]")
asm = ps.Assignment(f(0), g(0))
```
its invocation can be rendered using {any}`sfg.gpu_invoke <SfgGpuComposer.gpu_invoke>`.
Here is an example using CUDA:
```{code-cell} ipython3
from pystencilssfg import SfgConfig
......@@ -367,12 +360,14 @@ sfg_config = SfgConfig()
sfg_config.extensions.impl = "cu"
with SourceFileGenerator(sfg_config) as sfg:
# Activate CUDA
sfg.use_cuda()
# Configure the code generator to use CUDA
cfg = ps.CreateKernelConfig(target=ps.Target.CUDA)
# Create fields, assemble assignments
f, g = ps.fields("f, g: double[2D]")
asm = ps.Assignment(f(0), g(0))
# Register the GPU kernel
cfg = ps.CreateKernelConfig()
cfg.target = ps.Target.CUDA
# Register kernel
khandle = sfg.kernels.create(asm, "gpu_kernel", cfg)
# Invoke it
......@@ -442,8 +437,8 @@ with SourceFileGenerator() as sfg:
:::{admonition} To Do
- Creating and calling kernels
- Invoking GPU kernels and the CUDA API Mirror
- Modifying GPU kernel launch configs
- GPU API Reflections
- Defining classes, their fields constructors, and methods
:::
......
......@@ -2,7 +2,7 @@ from __future__ import annotations
from typing import overload
from pystencils.codegen import GpuKernel
from pystencils.codegen import GpuKernel, Target
from pystencils.codegen.gpu_indexing import (
ManualLaunchConfiguration,
AutomaticLaunchConfiguration,
......@@ -20,7 +20,7 @@ from ..ir import (
SfgSequence,
)
from ..lang import ExprLike, AugExpr
from ..lang.gpu import ProvidesGpuRuntimeAPI
from ..lang.gpu import CudaAPI, HipAPI, ProvidesGpuRuntimeAPI
class SfgGpuComposer(SfgComposerMixIn):
......@@ -69,40 +69,6 @@ class SfgGpuComposer(SfgComposerMixIn):
.. _Launch Configurations in HIP: https://rocmdocs.amd.com/projects/HIP/en/latest/how-to/hip_cpp_language_extensions.html#calling-global-functions
""" # NOQA: E501
def __init__(self) -> None:
self._gpu_api_provider: ProvidesGpuRuntimeAPI | None = None
def use_cuda(self):
"""Instruct the GPU composer to use the CUDA runtime API"""
from ..lang.gpu import CudaAPI
self._gpu_api_provider = CudaAPI()
def use_hip(self):
"""Instruct the GPU composer to use the HIP runtime API"""
from ..lang.gpu import HipAPI
self._gpu_api_provider = HipAPI()
@property
def gpu_api(self) -> ProvidesGpuRuntimeAPI | None:
"""GPU runtime API wrapper currently used by this GPU composer,
or `None` if none was selected."""
return self._gpu_api_provider
def get_gpu_api(self) -> ProvidesGpuRuntimeAPI:
"""GPU runtime API provider currently used by this GPU composer.
Raises:
AttributeError: If no runtime API was set yet (see `use_cuda`, `use_hip`)
"""
if self._gpu_api_provider is None:
raise AttributeError(
"No GPU API was selected - call `use_cuda()` or `use_hip()` first."
)
return self._gpu_api_provider
@overload
def gpu_invoke(
self,
......@@ -145,7 +111,16 @@ class SfgGpuComposer(SfgComposerMixIn):
launch_config = ker.get_launch_configuration()
dim3 = self.get_gpu_api().dim3
gpu_api: type[ProvidesGpuRuntimeAPI]
match ker.target:
case Target.CUDA:
gpu_api = CudaAPI
case Target.HIP:
gpu_api = HipAPI
case _:
assert False, "unexpected GPU target"
dim3 = gpu_api.dim3
grid_size: ExprLike
block_size: ExprLike
......
......@@ -55,6 +55,10 @@ class CudaAPI(ProvidesGpuRuntimeAPI):
template = cpptype("cudaStream_t", "<cuda_runtime.h>")
cuda = CudaAPI
"""Reflection of the CUDA runtime API"""
class HipAPI(ProvidesGpuRuntimeAPI):
"""Reflection of the HIP runtime API"""
......@@ -65,3 +69,7 @@ class HipAPI(ProvidesGpuRuntimeAPI):
class stream_t(CppClass):
template = cpptype("hipStream_t", "<hip/hip_runtime.h>")
hip = HipAPI
"""Reflection of the HIP runtime API"""
from pystencilssfg import SourceFileGenerator
from pystencilssfg.lang.cpp import std
from pystencilssfg.lang.gpu import cuda
import pystencils as ps
......@@ -11,14 +12,13 @@ asm = ps.Assignment(dst(0), 2 * src(0))
with SourceFileGenerator() as sfg:
sfg.use_cuda()
sfg.namespace("gen")
base_config = ps.CreateKernelConfig(target=ps.Target.CUDA)
block_size = sfg.gpu_api.dim3().var("blockSize")
grid_size = sfg.gpu_api.dim3().var("gridSize")
stream = sfg.gpu_api.stream_t().var("stream")
block_size = cuda.dim3().var("blockSize")
grid_size = cuda.dim3().var("gridSize")
stream = cuda.stream_t().var("stream")
with sfg.namespace("linear3d"):
cfg = base_config.copy()
......
from pystencilssfg import SourceFileGenerator
from pystencilssfg.lang.cpp import std
from pystencilssfg.lang.gpu import hip
import pystencils as ps
......@@ -11,14 +12,13 @@ asm = ps.Assignment(dst(0), 2 * src(0))
with SourceFileGenerator() as sfg:
sfg.use_hip()
sfg.namespace("gen")
base_config = ps.CreateKernelConfig(target=ps.Target.HIP)
block_size = sfg.gpu_api.dim3().var("blockSize")
grid_size = sfg.gpu_api.dim3().var("gridSize")
stream = sfg.gpu_api.stream_t().var("stream")
block_size = hip.dim3().var("blockSize")
grid_size = hip.dim3().var("gridSize")
stream = hip.stream_t().var("stream")
with sfg.namespace("linear3d"):
cfg = base_config.copy()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment