Monday 9 November 2020

Numba data type error: Cannot unify array

I am using Numba to speed up a series of functions as shown below. if I set the step_size variable in function PosMomentSingle to a float (e.g. step_size = 0.5), instead of an integer (e.g step_size = 1.0), I get the following error:

Cannot unify array(float32, 1d, C) and array(float64, 1d, C) for 'axle_coords.2', defined at <ipython-input-182-37c789ca2187> (12)

File "<ipython-input-182-37c789ca2187>", line 12:
def nbSimpleSpanMoment(L, axles, spacings, step_size):
    <source elided>
    
    while np.min(axle_coords) < L:

I found it quite hard to understand what the problem is, but my guess is there is an issue with the function after @jit (nbSimpleSpanMoment), with some kind of a datatype mismatch. I tried setting all variables to float32, then to float64 (e.g. L = np.float32(L)) but whatever I try creates a new set of errors. Since the error message is quite cryptic, I am unable to debug the issue. Can someone with numba experience explain what I am doing wrong here?

I placed my code below to recreate the problem.

Thank you for the help!

import numba as nb
import numpy as np

@nb.vectorize(nopython=True)
def nbvectMoment(L,x):
    if x<L/2.0:
        return 0.5*x
    else:
        return 0.5*(L-x)

@nb.jit(nopython=True)
def nbSimpleSpanMoment(L, axles, spacings, step_size):
    travel = L + np.sum(spacings)
    maxmoment = 0
    axle_coords = -np.cumsum(spacings)
    moment_inf = np.empty_like(axles)
    while np.min(axle_coords) < L:
        axle_coords = axle_coords + step_size
        y = nbvectMoment(L,axle_coords)
        for k in range(y.shape[0]):
            if axle_coords[k] >=0 and axle_coords[k] <= L:
                moment_inf[k] = y[k]
            else:
                moment_inf[k] = 0.0   
        moment = np.sum(moment_inf * axles)
        if maxmoment < moment:
            maxmoment = moment
    return np.around(maxmoment,1)

def PosMomentSingle(current_axles, current_spacings):
    data_list = []
    for L in range (1,201):
        L=float(L)        
        if L <= 40:
            step_size = 0.5
        else:
            step_size = 0.5            
        axles = np.array(current_axles, dtype='f')
        spacings = np.array(current_spacings, dtype='f')            
        axles_inv = axles[::-1]
        spacings_inv = spacings[::-1]           
        spacings = np.insert(spacings,0,0)
        spacings_inv = np.insert(spacings_inv,0,0)            
        left_to_right = nbSimpleSpanMoment(L, axles, spacings, step_size)
        right_to_left = nbSimpleSpanMoment(L, axles_inv, spacings_inv, step_size)            
        data_list.append(max(left_to_right, right_to_left))
    return data_list

load_effects = []
for v in range(14,31):
    load_effects.append(PosMomentSingle([8, 32, 32], [14, v]))
load_effects = np.array(load_effects)


from Numba data type error: Cannot unify array

No comments:

Post a Comment