2016-07-20 2 views
1

de code suivantlogique de décalage à droite dans numba

@jit(uint32(uint32)) 
def foo(x): 
    return (x >> 6) 

print(hex(foo(0xffffffff))) 

sorties

0xffffffff 

parce numba utilise décalage droit arithmétique malgré le fait que l'opérande est définie comme étant non signé.

Y a-t-il un moyen de le transmettre pour utiliser le décalage logique? En fait, à partir de la réponse de JoshAdel ci-dessous, j'ai appris une solution de contournement - en utilisant une variable interne de 64 bits pour laquelle les décalages logiques et arithmétiques ne différeront pas. Comme ceci:

@jit(uint32(uint32), locals = {'t': uint64}) 
def foo1(x): 
    t = x 
    return t << 8 

@jit(uint32(uint32), locals = {'t': uint64}) 
def foo2(x): 
    t = x 
    return t >> 8 

print(hex(foo1(0xffffffff))) 
print(hex(foo2(0xffffffff))) 

qui imprime

0xffffff00 
0xffffff 

Mais un compilateur décent doit comprendre que >> appliqué à un nombre unsigned entraînera un changement logique.

+0

Si la réponse de JoshAdel ne vous conduit pas à une solution, vous pouvez essayer 'x/(1 << 6)' à la place et voir si la gigue l'optimise pour un décalage logique vers la droite. –

+0

L'ai essayé. La division reste dans l'assemblée. Dommage. –

+0

Pouvez-vous contraindre '(1 << 6)' à un type non signé (de sorte que les deux côtés de la division ne soient pas signés) et vérifier l'assemblage résultant? Je suggère qu'il y a une chance que s'il voit 'uint/uint' il l'optimisera, par opposition à' uint/int'. –

Répondre

0

je reçois la même réponse du python pur et Numba versions jitted utilisant Numba 0.27:

import numba as nb 

def foo(x): 
    return (x >> 6) 

foo_nb = nb.jit()(foo) 

print(hex(foo(0xffffffff))) 
print(hex(foo_nb(0xffffffff))) 

résultats dans:

0x3ffffff 
0x3ffffff 

Ce qui suit produit également le même résultat (pour nous assurer que nous n'êtes pas retomber en mode objet et en utilisant effectivement la pleine JIT):

foo_nb2 = nb.jit('uint(uint)', nopython=True)(foo) 
print(hex(foo_nb2(0xffffffff))) 

# prints 0x3ffffff 

W la version chapeau de Numba utilisez-vous?

+0

'foo_nb.inspect_types()' montre qu'effectivement ** numba ** utilise des changements arithmétiques et int64. Cela ne résout pas le problème, mais le cache seulement jusqu'à ce que les décalages de gauche poussent un nombre de sorte que le bit MS d'un nombre de 64 bits devienne 1. Ensuite, il donnera des résultats inattendus. –

+0

Hmm ... en regardant 'foo_nb2.inspect_types()', il semble utiliser 'unint64' comme type d'entrée, en passant à' int64' puis en retournant 'uint64' à la fin. Je souleverais un problème sur le traqueur de problème de Numba si vous pensez que le code est traduit incorrectement. Ils sont généralement très réactifs. – JoshAdel

+0

Pourrait-il être une régression à [Bugs de l'opérateur de décalage de bits # 191] (https://github.com/numba/numba/issues/191)? –