6

The code is here:

import numba as nb
import numpy as np

@nb.njit
def func(size):
    ary = np.array([np.arange(size),np.arange(size)+1,np.arange(size)-1]).T
    X = np.array([ary[1:,0] - ary[:-1,2],
                  ary[1:,1] - ary[:-1,2],
                  ary[1:,0] - ary[1:,1]
                  ])
    return X

Z = func(10**9)

When I run the code, it gives me an error message and I don't really understand what's going on here. Do functions decorated by njit not support creating new arrays inside the functions? Error message is the following:

TypingError: Invalid use of Function(<built-in function array>) with argument(s) of type(s): (list(array(int64, 1d, C)))
 * parameterized
In definition 0:
    TypingError: array(int64, 1d, C) not allowed in a homogeneous sequence
    raised from C:\Users\User\Anaconda3\lib\site-packages\numba\typing\npydecl.py:459
In definition 1:
    TypingError: array(int64, 1d, C) not allowed in a homogeneous sequence
    raised from C:\Users\User\Anaconda3\lib\site-packages\numba\typing\npydecl.py:459
This error is usually caused by passing an argument of a type that is unsupported by the named function.
[1] During: resolving callee type: Function(<built-in function array>)
[2] During: typing of call at C:/Users/User/Desktop/all python file/3.2.4/nb_datatype.py (65)

EDIT: I forgot to transpose the array before edit, it should be a 10^9 by 3 array.

mathguy
  • 1,450
  • 1
  • 16
  • 33
  • Is that the full code? Do you have a longer traceback? (that one looks slightly truncated) –  Dec 20 '18 at 00:55
  • This is the only relevant part of the code to the problem. – mathguy Dec 20 '18 at 01:23
  • 1
    Well, the traceback seems to have a line so I'm not 100% certain which line is being used (I'm not sure which is 65). –  Dec 20 '18 at 01:49

2 Answers2

4

Instantiating NumPy arrays via a list of NumPy arrays, or even a list of lists, is not supported by numba.njit. Instead, use np.empty and then assign values via NumPy indexing:

@nb.njit
def func(size):
    row_count = 3
    ary = np.empty((row_count, size))
    ranger = np.arange(size)
    ary[0] = ranger
    ary[1] = ranger + 1
    ary[2] = ranger - 1

    X = np.empty((row_count, row_count - 1))
    X[0] = ary[1:,0] - ary[:-1,2]
    X[1] = ary[1:,1] - ary[:-1,2]
    X[2] = ary[1:,0] - ary[1:,1]

    return X

Z = func(10**2)

print(Z)

array([[-1., -4.],
       [ 0., -3.],
       [-1., -1.]])
jpp
  • 159,742
  • 34
  • 281
  • 339
  • sorry I forgot to transpose the array in the function. it should be a 10^9 by 3 array. – mathguy Dec 20 '18 at 01:27
  • 1
    @mathguy, Sure. As such, this doesn't change the gist of my answer. Which is `numba.njit` doesn't support what you want and you need to use indexing / assignment. – jpp Dec 20 '18 at 01:28
  • 1
    thank you for answering. I wonder if creating a numpy array using np.empty and assigning them one by one in a njit-decorated function is any faster than creating it using vectorized operation without njit? – mathguy Dec 20 '18 at 01:36
  • 1
    @mathguy, I'm not sure, you can time this yourself using `timeit`, see [this answer](https://stackoverflow.com/a/44677724/9209546) – jpp Dec 20 '18 at 01:38
  • It's interesting - it seems that this was previously supported? I just updated `numba` and began getting these errors. – Greenstick Jun 28 '19 at 23:17
0

I followed @jpp's advice and switched to np.float64 rather than float, but I also had to switch np.empty([1,2,3], np.float64) to np.empty((1,2,3), np.float64).

v0rtex20k
  • 1,041
  • 10
  • 20