From 414d2c559fa8dcd438dc98eb409f8c3f4ff001d1 Mon Sep 17 00:00:00 2001 From: Dennis Liew Date: Mon, 15 Jun 2026 14:36:53 -0400 Subject: [PATCH 1/3] docs(faq): Add FAQ section and class methods explanation --- docs/faq/class_methods.md | 63 +++++++++++++++++++++++++++++++++++++++ docs/faq/index.md | 9 ++++++ mkdocs.yml | 3 ++ 3 files changed, 75 insertions(+) create mode 100644 docs/faq/class_methods.md create mode 100644 docs/faq/index.md diff --git a/docs/faq/class_methods.md b/docs/faq/class_methods.md new file mode 100644 index 0000000000..cbe651552a --- /dev/null +++ b/docs/faq/class_methods.md @@ -0,0 +1,63 @@ +# Calling Python Class Methods Inside a Kernel + +## The problem + +If you try to call a standard Python class method, such as +`self.get_move_kernel()`, from inside a function decorated with +`@kirin_flair.kernel` or `@kernel`, the compiler will fail. Historically, before +Kirin v0.16.8, this could appear as an `AttributeError` about `arg_names`. + +## Why this happens + +A kernel is a piece of code that describes instructions intended to run on the +target device, not on your host machine. Because of this, the Kirin compiler +cannot evaluate arbitrary Python runtime expressions, such as object attribute +lookups or dynamically calling class methods, during device execution. + +The compiler only parses global constants and already-resolved kernel functions. + +## The solution + +Resolve the Python method on the host before defining the kernel. By assigning +the result to a local variable, the inner kernel can cleanly capture that +variable as a constant. + +### Incorrect + +This tries to evaluate the method inside the device kernel. + +```python +class Foo: + def get_move_buffer_kernel(self): + + @kernel + def get_move_buffer(): + # ERROR: Kirin cannot evaluate arbitrary Python class methods. + move_kernel = self.get_move_kernel() + move_sequence = move_kernel() + # ... + return bufr + + return get_move_buffer +``` + +### Correct + +Resolve the method on the host side, then capture it in the kernel closure. + +```python +class Foo: + def get_move_buffer_kernel(self): + # 1. Resolve the method in host Python code. + move_kernel = self.get_move_kernel() + + # 2. Define the device kernel. + @kernel + def get_move_buffer(a, b, c): + # 3. Call the captured constant inside the kernel. + move_kernel(a, b, c) + # ... + return bufr + + return get_move_buffer +``` diff --git a/docs/faq/index.md b/docs/faq/index.md new file mode 100644 index 0000000000..d0f0628b74 --- /dev/null +++ b/docs/faq/index.md @@ -0,0 +1,9 @@ +# FAQ + +This page collects common questions with a short answer and a link to a deeper explanation. + +## Kernel authoring + +| Question | Short answer | +| --- | --- | +| [Why do I get an `AttributeError` when calling a class method inside a kernel?](class_methods.md) | Resolve the Python method on the host side before defining the kernel, then capture it as a constant. | diff --git a/mkdocs.yml b/mkdocs.yml index 61edc46f09..db93513444 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -26,6 +26,9 @@ nav: - Structural Control Flow: dialects/scf.md - Immutable List: dialects/ilist.md - Compiler 101: 101.md + - FAQ: + - faq/index.md + - Class methods in kernels: faq/class_methods.md # - Comparison: comparison.md - Contributing: contrib.md - Cookbook: From df0bf0945f90e53a2a45eaca60d0f00d58f8df5e Mon Sep 17 00:00:00 2001 From: Dennis Liew Date: Tue, 16 Jun 2026 19:05:18 -0400 Subject: [PATCH 2/3] docs(faq): Update class methods example to use @basic --- docs/faq/class_methods.md | 56 ++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/docs/faq/class_methods.md b/docs/faq/class_methods.md index cbe651552a..205d0a96bf 100644 --- a/docs/faq/class_methods.md +++ b/docs/faq/class_methods.md @@ -4,8 +4,8 @@ If you try to call a standard Python class method, such as `self.get_move_kernel()`, from inside a function decorated with -`@kirin_flair.kernel` or `@kernel`, the compiler will fail. Historically, before -Kirin v0.16.8, this could appear as an `AttributeError` about `arg_names`. +`@basic` or `@structural`, the compiler will fail. Historically, before Kirin +v0.16.8, this could appear as an `AttributeError` about `arg_names`. ## Why this happens @@ -27,18 +27,23 @@ variable as a constant. This tries to evaluate the method inside the device kernel. ```python -class Foo: - def get_move_buffer_kernel(self): +from kirin.prelude import basic - @kernel - def get_move_buffer(): + +class Offset: + def __init__(self, value: int): + self.value = value + + def get_value(self) -> int: + return self.value + + def bad_method(self): + @basic + def add_offset(x: int) -> int: # ERROR: Kirin cannot evaluate arbitrary Python class methods. - move_kernel = self.get_move_kernel() - move_sequence = move_kernel() - # ... - return bufr + return x + self.get_value() - return get_move_buffer + return add_offset ``` ### Correct @@ -46,18 +51,25 @@ class Foo: Resolve the method on the host side, then capture it in the kernel closure. ```python -class Foo: - def get_move_buffer_kernel(self): +from kirin.prelude import basic + + +class Offset: + def __init__(self, value: int): + self.value = value + + def get_value(self) -> int: + return self.value + + def method(self): # 1. Resolve the method in host Python code. - move_kernel = self.get_move_kernel() + offset = self.get_value() # 2. Define the device kernel. - @kernel - def get_move_buffer(a, b, c): - # 3. Call the captured constant inside the kernel. - move_kernel(a, b, c) - # ... - return bufr - - return get_move_buffer + @basic + def add_offset(x: int) -> int: + # 3. Use the captured constant inside the kernel. + return x + offset + + return add_offset ``` From be8dd08f5a464e90a93f3d7c3f42b7ec6e843852 Mon Sep 17 00:00:00 2001 From: Dennis Liew Date: Tue, 16 Jun 2026 19:07:39 -0400 Subject: [PATCH 3/3] docs(faq): Correct method name in class methods example --- docs/faq/class_methods.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq/class_methods.md b/docs/faq/class_methods.md index 205d0a96bf..e8f7178220 100644 --- a/docs/faq/class_methods.md +++ b/docs/faq/class_methods.md @@ -3,7 +3,7 @@ ## The problem If you try to call a standard Python class method, such as -`self.get_move_kernel()`, from inside a function decorated with +`self.get_value()`, from inside a function decorated with `@basic` or `@structural`, the compiler will fail. Historically, before Kirin v0.16.8, this could appear as an `AttributeError` about `arg_names`.