2017-10-16 4 views
2

Ich versuche, einen Gleichheitsprüfer für zwei Arrays zu erstellen, die ich mit PyCUDA auf meiner GPU ausführen kann.PyCUDA - ElementWise schlägt für die Gleichheitsüberprüfung fehl

Nach dem Beispiel auf der PyCUDA GPU Arrays documentation page versucht, meine eigene Implementierung zu schreiben. Aber während der folgende Code wie erwartet für die Arithmetik funktioniert, z.B. "z[i] = x[i] + y[i]", gibt es eine fehlerhafte Ausgabe für den Gleichheitsprüfungsoperanden "z[i] = x[i] == y[i]" zurück.

import pycuda.gpuarray as gpuarray 
import pycuda.driver as cuda 
import pycuda.autoinit 
import numpy as np 
from pycuda.elementwise import ElementwiseKernel 

matrix_size = (5,) 
a = np.random.randint(2, size=matrix_size) 
b = np.random.randint(2, size=matrix_size) 

print a 
print b 

a_gpu = gpuarray.to_gpu(a) 
b_gpu = gpuarray.to_gpu(b) 

eq_checker = ElementwiseKernel(
     "int *x, int *y, int *z", 
     "z[i] = x[i] == y[i]", 
     "equality_checker") 

c_gpu = gpuarray.empty_like(a_gpu) 
eq_checker(a_gpu, b_gpu, c_gpu) 

print c_gpu 

, die wie etwas ausdruckt:

[0 1 0 0 0] 
[0 1 1 1 0] 
[4294967297 4294967297   0   1   1] 

Hat jemand verstehen, warum dieser Fehler auftritt, oder zumindest eine Alternative PyCUDA Methode, um die gewünschte Funktion zu erreichen?

+0

Könnten Sie versuchen, Klammern hinzuzufügen 'z [i] = (x [i] == y [i])' und sehen, ob das funktioniert? Falls nicht, wenn Sie nur 0/1-Werte verwenden, sollten Sie stattdessen den Operator '&' verwenden, da dies in diesem Fall dasselbe wäre, und wahrscheinlich auch schneller. – scnerd

+0

Leider beheben die Klammern es nicht. Der '&' -Operator funktioniert gut für Binärdateien, aber letztendlich würde ich ihn gerne für nicht binäre Ganzzahlen verwenden. Ich bin mit C-Code nicht sehr vertraut, aber gibt es irgendetwas über den Gleichheitsoperator, der ihn grundlegend von arithmetischen und booleschen unterscheidet? – SLesslyTall

+0

Es könnte sich lohnen, das Ergebnis zu formulieren, um sicherzustellen, dass Sie das bekommen, was Sie erwarten: 'z [i] = (int) (x [i] == y [i])'. Ich mache auch nicht viel C in diesen Tagen, also rate ich hier, da ich nicht positiv bin, was der '== 'Operator Rückgabetyp ist – scnerd

Antwort

1

Gelöst! Das Problem bestand darin, dass numpy 64-Bit-Ganzzahlen automatisch zurückgibt, während PyCUDA nur 32-Bit-Ganzzahlen standardmäßig akzeptiert.

Dies wird deshalb durch die Angabe der Art der festen ints numpy, wie erzeugt:

a = np.random.randint(2, size=matrix_size, dtype=np.int32) 
b = np.random.randint(2, size=matrix_size, dtype=np.int32) 

wonach sie wie erwartet funktioniert.