How do I make a dummy do-nothing @jit decorator?
Asked Answered
S

3

9

I want numba to be an optional dependency, so that it's fast if installed or slow if not. So when numba is not installed, I want @njit to be a dummy decorator that does nothing.

If I follow these directions and use:

def njit(func):
    return func

Then when the decorator is called like @njit(cache=True, nogil=True) I get errors about:

TypeError: njit() got an unexpected keyword argument 'cache'

If I try to catch the args and ignore them using

    def njit(func, *args, **kwargs):
        return func

then I get:

missing 1 required positional argument: 'func'

How do I just make a dummy decorator that does nothing and ignores kwargs?

Shakhty answered 3/9, 2019 at 15:12 Comment(1)
Possible duplicate of Decorators with parameters?Adrenalin
P
11

Think of decorators with arguments as decorator factory, they return a decorator. This way

def decorator(func):
    return func

The above is a decorator, now with arguments

def decorator_factory(a,b,c):
    def decorator(func):
        return func
    return decorator

The inner decorator has access to the a,b,c arguments because it is a closure. I hope that helps


So it can be defined as:

def njit(cache, nogil):
    def decorator(func):
        return func 
    return decorator
Punjabi answered 3/9, 2019 at 15:19 Comment(2)
Yep that fixes it. def njit(*args, **kwargs): def decorator(func): return func return decoratorShakhty
@endolith: Only if you always do @njit() and never @njit. It will silently do the wrong thing if you ever do @njit.Chaparajos
S
3

If you want to save some time and be able to do the same with all numba decorators, try numbasub. It provides exactly what you are asking for, and you can apply it to any project you want.

Saretta answered 3/9, 2019 at 15:59 Comment(2)
that would just be another dependency, though?Shakhty
true. it's a very light dependency though since it has no dependencies itself. Plus it covers a lot of cases that are annoying to address one by one, e.g. if numba types are imported somewhere in the code you would have to mock them one by one. But if one only needs to create dummies for a couple of decorators, it might be overkill (it's even mentioned in the readme file).Saretta
V
2

Expanding on geckos' answer, we can adapt it to be compatible with @njit as well.

The code for jit can be found in https://github.com/numba/numba/blob/main/numba/core/decorators.py

What we need to do is to make jit act as a factory decorator when used as @jit() and as a simple decorator when used as @jit.

def njit(f=None, *args, **kwargs):
    def decorator(func):
        return func 

    if callable(f):
        return f
    else:
        return decorator

This should work in both cases.

Varied answered 8/8, 2022 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.