# Why Numpy array operation can not be done with Numba?

I am writing a simple code to use numpy array inside numba jit as following,

import numpy as  np
import matplotlib.pyplot as plt
import random
import time
import math
import numba
from numba import jit,prange
nx=100
p1=np.zeros([nx],dtype=float)
@jit(nopython=True)
def f(r):
p1[2]=10
return p1[2]
u3=f(2)

It shows the following error:

Compilation is falling back to object mode WITH looplifting enabled because Function "f" failed type inference due to: No implementation of function Function(<built-in function setitem>) found for signature:

setitem(readonly array(float64, 1d, C), Literal[int](2), Literal[int](10))

There are 16 candidate implementations:
- Of which 14 did not match due to:
Overload of function 'setitem': File: <numerous>: Line N/A.
With argument(s): '(readonly array(float64, 1d, C), int64, int64)':
No match.
- Of which 2 did not match due to:
Overload in function 'SetItemBuffer.generic': File: numba\core\typing\arraydecl.py: Line 176.
With argument(s): '(readonly array(float64, 1d, C), int64, int64)':
Rejected as the implementation raised a specific error:
NumbaTypeError: Cannot modify readonly array of type: readonly array(float64, 1d, C)

I have seen that the arrays work inside the function well if I do not use a special index operation like y[i]=x[i]**2. But simply y=x^2 works where x is a numpy array.

ðŸŸ¢ Solution

The type of p1 is readonly array(float64, 1d, C) which means you cannot modify it. This is why setting an items does not work: Numba cannot find a function so to set the value of a readonly array. The array is marked as readonly because it is a global variable and this is what Numba does for global variables. The usual solution in pure-Python is to use global p1 but this does not works with Numba due to the way Numba and CPython works. The solution is to pass p1 in parameter. In fact, it is a very bad practice to modify global variables in software engineering because of the non-locality (and such accesses are also often slower) so this is not a big problem.

Fixed code:

p1=np.zeros([nx],dtype=float)
@jit(nopython=True)
def f(r, p1):
p1[2]=10
return p1[2]
u3=f(2, p1)