yglukhov / nimpy

Nim - Python bridge

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to use python decorators

PriNova opened this issue · comments

I want to use the Taichi python package: https://www.taichi-lang.org/

To generate GPU kernels, I need to annotate python functions like this:

import taichi as ti
import taichi.math as tm

ti.init(arch=ti.gpu)

n = 320
pixels = ti.field(dtype=float, shape=(n * 2, n))

@ti.func
def complex_sqr(z):  # complex square of a 2D vector
    return tm.vec2(z[0] * z[0] - z[1] * z[1], 2 * z[0] * z[1])

@ti.kernel
def paint(t: float):
    for i, j in pixels:  # Parallelized over all pixels
        c = tm.vec2(-0.8, tm.cos(t) * 0.2)
        z = tm.vec2(i / n - 1, j / n - 0.5) * 2
        iterations = 0
        while z.norm() < 20 and iterations < 50:
            z = complex_sqr(z) + c
            iterations += 1
        pixels[i, j] = 1 - iterations * 0.02

gui = ti.GUI("Julia Set", res=(n * 2, n))

i = 0
while gui.running:
    paint(i * 0.03)
    gui.set_image(pixels)
    gui.show()
    i += 1

Which generate a nice fractal animation seen here: https://docs.taichi-lang.org/docs/hello_world

My question is, how to use @decorators in Nim?

Thank you in advance

Fundamentally, in python, you can use any callable object (usually a function) as a decorator.
A function decorator is a decorator which returns a function object.
So your

@ti.func
def complex_sqr(...)

is syntactic sugar for:

def complex_sqr(...):
    ...
complex_sqr = ti.func(complex_sqr)

Conceptually via nimpy, you can therefore treat any imported decorator such as ti.func as a callable that accepts a python function object, and returns you a new python function object. which is itself callable as you desire.

I hope that helps a bit