2017-10-21 27 views
-1

J'essaye d'écrire certaines fonctions en numba que je peux utiliser de manière interchangeable pour différentes cibles (cpu, cuda, parallel). Le gros problème que je vais avoir est l'attribution d'un nouveau tableau est différent pour le code de l'appareil cuda, par exemple:Attribution de tableau pour les fonctions CPU et GPU dans NUMBA

cuda.local.array(shape, dtype) 

vs faire quelque chose de similaire pour une fonction CPU, à savoir

np.empty(shape, dtype) 

Y at-il un manière intelligente comment faire face à cela sans avoir à écrire des fonctions séparées?

+0

Ne pourriez-vous tester pour taper dans votre fonction? – 0TTT0

+0

le problème est que je ne peux avoir aucune instruction dans mes fonctions qui ne fonctionne pas, car numba compile le code et panique. Sinon je ferais un simple si/sinon ou tel. La façon naturelle de gérer cela serait des directives de préprocesseur en C pour cela, mais il n'y a rien de tel pour python –

Répondre

0

J'ai trouvé une solution de contournement sale pour le problème. C'est le seul moyen de le faire fonctionner. Utilisez le décorateur @myjit au lieu de @jit et @cuda.jit et attribuez tous les tableaux sous la forme cuda.local.array.

def myjit(f): 
''' 
f : function 
Decorator to assign the right jit for different targets 
In case of non-cuda targets, all instances of `cuda.local.array` 
are replaced by `np.empty`. This is a dirty fix, hopefully in the 
near future numba will support numpy array allocation and this will 
not be necessary anymore 
''' 
if target == 'cuda': 
    return cuda.jit(f, device=True) 
else: 
    source = inspect.getsource(f).splitlines() 
    assert '@myjit' in source[0] 
    source = '\n'.join(source[1:]) + '\n' 
    source = source.replace('cuda.local.array', 'np.empty') 
    exec(source) 
    fun = eval(f.__name__) 
    newfun = jit(fun, nopython=True) 
    # needs to be exported to globals 
    globals()[f.__name__] = newfun 
    return newfun