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

update AST inspection to allow disabling certain tabs. Add a note on cupy.

parent 7308f616
No related branches found
No related tags found
1 merge request!430Jupyter Inspection Framework, Book Theme, and Initial Drafts for Codegen Reference Guides
Pipeline #70937 passed
...@@ -58,10 +58,22 @@ property, which tells us how many threads the kernel is expecting to be executed ...@@ -58,10 +58,22 @@ property, which tells us how many threads the kernel is expecting to be executed
kernel.threads_range kernel.threads_range
``` ```
If a GPU is available and [cupy] is installed in the current environment, If a GPU is available and [CuPy][cupy] is installed in the current environment,
the kernel can be compiled and run immediately. the kernel can be compiled and run immediately.
To execute the kernel, a {any}`cupy.ndarray` has to be passed for each field; To execute the kernel, a {any}`cupy.ndarray` has to be passed for each field.
this is the GPU analogue to {any}`numpy.ndarray`:
:::{note}
[CuPy][cupy] is a Python library for numerical computations on GPU arrays,
which operates much in the same way that [NumPy][numpy] works on CPU arrays.
Cupy and NumPy expose nearly the same APIs for array operations;
the difference being that CuPy allocates all its arrays on the GPU
and performs its operations as CUDA kernels.
Also, CuPy exposes a just-in-time-compiler for GPU kernels, which internally calls [nvcc].
In pystencils, we use CuPy both to compile and provide executable kernels on-demand from within Python code,
and to allocate and manage the data these kernels can be executed on.
For more information on CuPy, refer to [their documentation][cupy-docs].
:::
```{code-cell} ipython3 ```{code-cell} ipython3
:tags: [raises-exception] :tags: [raises-exception]
...@@ -212,3 +224,6 @@ only a part of the triangle is being processed. ...@@ -212,3 +224,6 @@ only a part of the triangle is being processed.
[cupy]: https://cupy.dev "CuPy Homepage" [cupy]: https://cupy.dev "CuPy Homepage"
[numpy]: https://numpy.org "NumPy Homepage"
[nvcc]: https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html "NVIDIA CUDA Compiler Driver"
[cupy-docs]: https://docs.cupy.dev/en/stable/overview.html "CuPy Documentation"
\ No newline at end of file
...@@ -178,7 +178,7 @@ are using the `int32` data type, as specified in {py:data}`index_dtype <CreateKe ...@@ -178,7 +178,7 @@ are using the `int32` data type, as specified in {py:data}`index_dtype <CreateKe
driver = ps.kernelcreation.get_driver(cfg, retain_intermediates=True) driver = ps.kernelcreation.get_driver(cfg, retain_intermediates=True)
kernel = driver(assignments) kernel = driver(assignments)
ps.inspect(driver.intermediates.materialized_ispace) ps.inspect(driver.intermediates.materialized_ispace, show_cpp=False)
``` ```
:::{note} :::{note}
......
...@@ -102,20 +102,31 @@ class AstInspection(CodeInspectionBase): ...@@ -102,20 +102,31 @@ class AstInspection(CodeInspectionBase):
explore an abstract syntax tree. explore an abstract syntax tree.
""" """
def __init__(self, ast: PsAstNode): def __init__(
self,
ast: PsAstNode,
show_ir: bool = True,
show_cpp: bool = True,
show_graph: bool = True,
):
super().__init__() super().__init__()
self._ast = ast self._ast = ast
self._show_ir = show_ir
self._show_cpp = show_cpp
self._show_graph = show_graph
def _widget(self): def _widget(self):
import ipywidgets as widgets import ipywidgets as widgets
tabs = widgets.Tab( tabs = []
children=[ if self._show_ir:
self._ir_tab(self._ast), tabs.append(self._ir_tab(self._ast))
self._cpp_tab(self._ast), if self._show_cpp:
self._graphviz_tab(self._ast), tabs.append(self._cpp_tab(self._ast))
] if self._show_graph:
) tabs.append(self._graphviz_tab(self._ast))
tabs = widgets.Tab(children=tabs)
tabs.titles = ["IR Code", "C Code", "AST Visualization"] tabs.titles = ["IR Code", "C Code", "AST Visualization"]
tabs.layout.height = "250pt" tabs.layout.height = "250pt"
...@@ -124,20 +135,31 @@ class AstInspection(CodeInspectionBase): ...@@ -124,20 +135,31 @@ class AstInspection(CodeInspectionBase):
class KernelInspection(CodeInspectionBase): class KernelInspection(CodeInspectionBase):
def __init__(self, kernel: KernelFunction) -> None: def __init__(
self,
kernel: KernelFunction,
show_ir: bool = True,
show_cpp: bool = True,
show_graph: bool = True,
) -> None:
super().__init__() super().__init__()
self._kernel = kernel self._kernel = kernel
self._show_ir = show_ir
self._show_cpp = show_cpp
self._show_graph = show_graph
def _widget(self): def _widget(self):
import ipywidgets as widgets import ipywidgets as widgets
tabs = widgets.Tab( tabs = []
children=[ if self._show_ir:
self._ir_tab(self._kernel), tabs.append(self._ir_tab(self._kernel))
self._cpp_tab(self._kernel), if self._show_cpp:
self._graphviz_tab(self._kernel), tabs.append(self._cpp_tab(self._kernel))
] if self._show_graph:
) tabs.append(self._graphviz_tab(self._kernel))
tabs = widgets.Tab(children=tabs)
tabs.titles = ["IR Code", "C Code", "AST Visualization"] tabs.titles = ["IR Code", "C Code", "AST Visualization"]
tabs.layout.height = "250pt" tabs.layout.height = "250pt"
...@@ -146,8 +168,17 @@ class KernelInspection(CodeInspectionBase): ...@@ -146,8 +168,17 @@ class KernelInspection(CodeInspectionBase):
class IntermediatesInspection: class IntermediatesInspection:
def __init__(self, intermediates: CodegenIntermediates): def __init__(
self,
intermediates: CodegenIntermediates,
show_ir: bool = True,
show_cpp: bool = True,
show_graph: bool = True,
):
self._intermediates = intermediates self._intermediates = intermediates
self._show_ir = show_ir
self._show_cpp = show_cpp
self._show_graph = show_graph
def _ipython_display_(self): def _ipython_display_(self):
from IPython.display import display from IPython.display import display
...@@ -155,7 +186,15 @@ class IntermediatesInspection: ...@@ -155,7 +186,15 @@ class IntermediatesInspection:
stages = self._intermediates.available_stages stages = self._intermediates.available_stages
previews: list[AstInspection] = [AstInspection(stage.ast) for stage in stages] previews: list[AstInspection] = [
AstInspection(
stage.ast,
show_ir=self._show_ir,
show_cpp=self._show_cpp,
show_graph=self._show_graph,
)
for stage in stages
]
labels: list[str] = [stage.label for stage in stages] labels: list[str] = [stage.label for stage in stages]
code_views = [p._widget() for p in previews] code_views = [p._widget() for p in previews]
...@@ -201,9 +240,9 @@ def inspect(obj: StageResult): ... ...@@ -201,9 +240,9 @@ def inspect(obj: StageResult): ...
def inspect(obj: CodegenIntermediates): ... def inspect(obj: CodegenIntermediates): ...
def inspect(obj): def inspect(obj, show_ir: bool = True, show_cpp: bool = True, show_graph: bool = True):
"""Interactively inspect various products of the code generator. """Interactively inspect various products of the code generator.
When run inside a Jupyter notebook, this function displays an inspection widget When run inside a Jupyter notebook, this function displays an inspection widget
for the following types of objects: for the following types of objects:
- `PsAstNode` - `PsAstNode`
...@@ -216,13 +255,21 @@ def inspect(obj): ...@@ -216,13 +255,21 @@ def inspect(obj):
match obj: match obj:
case PsAstNode(): case PsAstNode():
preview = AstInspection(obj) preview = AstInspection(
obj, show_ir=show_ir, show_cpp=show_cpp, show_graph=show_cpp
)
case KernelFunction(): case KernelFunction():
preview = KernelInspection(obj) preview = KernelInspection(
obj, show_ir=show_ir, show_cpp=show_cpp, show_graph=show_cpp
)
case StageResult(ast, _): case StageResult(ast, _):
preview = AstInspection(ast) preview = AstInspection(
ast, show_ir=show_ir, show_cpp=show_cpp, show_graph=show_cpp
)
case CodegenIntermediates(): case CodegenIntermediates():
preview = IntermediatesInspection(obj) preview = IntermediatesInspection(
obj, show_ir=show_ir, show_cpp=show_cpp, show_graph=show_cpp
)
case _: case _:
raise ValueError(f"Cannot inspect object of type {type(obj)}") raise ValueError(f"Cannot inspect object of type {type(obj)}")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment