# Cache njit function at import or install

**URL:** <https://numba.discourse.group/t/cache-njit-function-at-import-or-install/199>\
**Category:** Support: How do I do ...?\
**Created:** [August 28, 2020, 12:33pm UTC](https://numba.discourse.group/t/cache-njit-function-at-import-or-install/199 "2020-08-28T12:33:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![seanlaw](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/seanlaw/32/506_2.png) [@seanlaw](https://numba.discourse.group/u/seanlaw)\
**Post date:** [August 28, 2020, 12:33pm UTC](https://numba.discourse.group/t/cache-njit-function-at-import-or-install/199/1 "2020-08-28T12:33:45Z")

</div>

I have a package that contains many public njit functions. Of course, these functions are only compiled just-in-time as needed but I was wondering if there was a way to compile these functions either at installation OR at import? Is there a standard approach for this? I know that there is a `cache=True` option but this still requires the function to be called at least one time by the user. I was thinking that I could sneak this into ` __init__.py` by calling the functions there but any suggestions would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![rpopovici](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/rpopovici/32/86_2.png) [@rpopovici](https://numba.discourse.group/u/rpopovici)\
**Post date:** [August 28, 2020, 2:58pm UTC](https://numba.discourse.group/t/cache-njit-function-at-import-or-install/199/2 "2020-08-28T14:58:17Z")

</div>

@seanlaw I would like to know that as well. I think the only way right now to do that is to use AOT compilation [https://numba.pydata.org/numba-doc/dev/user/pycc.html](https://numba.pydata.org/numba-doc/dev/user/pycc.html)

I was thinking: if calling those njit functions from a background thread will it work for the first time, in order to do not freeze the app at startup?

---

<div class="post-metadata">

**Author:** ![seanlaw](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/seanlaw/32/506_2.png) [@seanlaw](https://numba.discourse.group/u/seanlaw)\
**Post date:** [August 28, 2020, 3:18pm UTC](https://numba.discourse.group/t/cache-njit-function-at-import-or-install/199/3 "2020-08-28T15:18:54Z")

</div>

@rpopovici Yes, I’ve read that too but AOT sounds like a worse option as it is not optimized for the local machine and the code is pretty ugly from a maintenance perspective. I think performing the JIT compilation and placing the function call inside if ` __init__.py` is another option. This means that import time may be high as it will include compile time but, for a data science workflow (i.e., a Jupyter notebook where import happens once), this might be fine but the solution needs to be easily portable as it is not just for me and my machine.

---

<div class="post-metadata">

**Author:** ![gmarkall](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/gmarkall/32/42_2.png) [@gmarkall](https://numba.discourse.group/u/gmarkall)\
**Post date:** [November 11, 2021, 11:27am UTC](https://numba.discourse.group/t/cache-njit-function-at-import-or-install/199/4 "2021-11-11T11:27:12Z")

</div>

I recently became aware of the approach used by Qibo to force compilation at install time. Each decorator has a signature and `cache=True`, e.g.

```python
@njit("int64(int64, int32[:])",
      cache=True)
def multicontrol_index(g, qubits):

```

(from [`gates.py`](https://github.com/qiboteam/qibojit/blob/4c41a1d8b540c4d7f7c15bff8dfa053a08d52eca/src/qibojit/custom_operators/gates.py#L5))

Then after installation in [`setup.py`](https://github.com/qiboteam/qibojit/blob/4c41a1d8b540c4d7f7c15bff8dfa053a08d52eca/setup.py#L29), the library is imported:

```python
class CustomInstall(install):
    def run(self):
        install.run(self)
        from qibo import K

```

This forces the compilation and caching of all functions.

Note that this will break binary distribution when you do `python setup.py bdist`, so Qibo uploads sdists to PyPI instead, creating them with `python setup.py sdist`.

(Many thanks to Stefano Carrazza for pointing me to this approach).
