1

I'm trying to create an array inside a function using @vectorize, I don't know why I keep receiving this error:

Unknown attribute 'array' of type Module( < module 'numpy' from 'filename.... /lib/python3.6/site-packages/numpy/ __ init __ .py'>)

Code:

from numba import vectorize, float32
import numpy as np

@vectorize([float32(float32[:,:], float32[:])], target='cuda')
def fitness(vrp_data, individual):
    # The first distance is from depot to the first node of the first route
    depot = np.array([0.0, 0.0, 30.0, 40.0], dtype=np.float32)
    firstnode = np.array([0.0, 0.0, 0.0, 0.0], dtype=np.float32)
    firstnode = vrp_data[vrp_data[:,0] == individual[0]][0] if 
individual[0] !=0 else depot

    x1 = depot[2]
    x2 = firstnode[2]
    y1 = depot[3]
    y2 = firstnode[3]

    dx = x1 - x2
    dy = y1 - y2
    totaldist = math.sqrt(dx * dx + dy * dy)

    return totaldist

The code works fine without the function decoration.

9
  • What have you tried? What kind of works and what doesn’t? See How to Ask in the help center for more information. Commented Dec 20, 2018 at 21:33
  • Thanks Ethan for the hint. I think my question is clear and the code is available, you can find answers if you just tried to run the code. Commented Dec 20, 2018 at 21:48
  • I do not have a python interpreter that I can use at the moment. But I know that error means that Module.array does not exist. Do you call variable.array somewhere in your code? Commented Dec 20, 2018 at 21:50
  • 1
    np.Array, not np.array Commented Dec 20, 2018 at 21:54
  • 1
    Possible duplicate of Using numpy 'module' object has no attribute 'array' Commented Dec 20, 2018 at 22:42

1 Answer 1

2

The problem

numpy.array is not supported by Numba. Numba only supports a subset of the Numpy top-level functions (ie any function you call like numpy.foo). Here's an identical issue from the Numba bug tracker.

The "solution"

Here's the list of Numpy functions that Numba actually supports. numpy.zeros is supported, so in an ideal world you could just change the lines in your code that use np.array to:

depot = np.zeros(4, dtype=np.float32)
depot[2:] = [30, 40]
firstnode = np.zeros(4, dtype=np.float32)

and it would work. However, when targeting cuda all Numpy functions that allocate memory (including np.zeros) are disabled. So you'll have to come up with a solution that doesn't involve any array allocation.

Issues with use of vectorize

Also, it looks like vectorize is not the wrapper function you should be using. Instead, a function like the one you've written requires the use of guvectorize. Here's the closest thing to your original code that I was able to get to work:

import math
from numba import guvectorize, float32
import numpy as np

@guvectorize([(float32[:,:], float32[:], float32[:])], '(m,n),(p)->()')
def fitness(vrp_data, individual, totaldist):
    # The first distance is from depot to the first node of the first route
    depot = np.zeros(4, dtype=np.float32)
    depot[2:] = [30, 40]
    firstnode = np.zeros(4, dtype=np.float32)
    firstnode = vrp_data[vrp_data[:,0] == individual[0]][0] if individual[0] !=0 else depot

    x1 = depot[2]
    x2 = firstnode[2]
    y1 = depot[3]
    y2 = firstnode[3]

    dx = x1 - x2
    dy = y1 - y2
    totaldist[0] = math.sqrt(dx * dx + dy * dy)

The third argument in the signature is actually the return value, so you call the function like:

vrp_data = np.arange(100, 100 + 4*4, dtype=np.float32).reshape(4,4)
individual = np.arange(100, 104, dtype=np.float32)

fitness(vrp_data, individual)

Output:

95.67131

Better error message in latest Numba

You should probably upgrade your version of Numba. In the current version, your original code raises a somewhat more specific error message:

TypingError: Failed in nopython mode pipeline (step: nopython frontend). Use of unsupported NumPy function 'numpy.array' or unsupported use of the function.
Sign up to request clarification or add additional context in comments.

4 Comments

Wow! this is really beyond my expectations. Very neat, very detailed with example. Thank you very much. * Can you please explain to me the meaning of: '(m,n),(p)->()' in the decoration line? * There is no 'target' argument for guvector ? I think I will give up Anaconda since it does not upgrade numba over 0.39
Translated to plain english, '(m,n),(p)->()' as the second arg of guvectorize means: "This is a function that takes one array of shape (m,n) and one array of shape (p) and returns a scalar". guvectorize requires this second argument since the function being wrapped cannot have an explicit return value.
Thanks again @tel. One more question please, * There is no 'target='cuda'' argument for guvector ?
There is, but as I said in the answer when you have that flag set, all of the array creation functions will be disabled. You'll have to change the algorithm of your fitness function to deal with that. Either pass in pre-made versions of depot and firstnode, or make them plain lists.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.