Numba CUDA-Code stürzt aufgrund eines unbekannten Fehlers ab, der durch das Hinzufügen einer leeren Druckanweisung in jePython

Python-Programme
Anonymous
 Numba CUDA-Code stürzt aufgrund eines unbekannten Fehlers ab, der durch das Hinzufügen einer leeren Druckanweisung in je

Post by Anonymous »

Ich schreibe einen Hamiltonschen Evolutionscode, der stark auf der Matrixmultiplikation basiert, deshalb habe ich versucht, etwas über die Entwicklung für eine GPU mit Python zu lernen.
Wenn ich diese Codezeilen jedoch in meiner Time-Evolution-Wrapper-Funktion ausführe:

Code: Select all

momentum_update_kernel[blocks, threads_per_block](config, dt / 2, staple_gpu, Barray_gpu, V2Barray_gpu, g_in)
cuda.synchronize()
print("momentum updated")
link_update_kernel[blocks, threads_per_block](config, dt, lie_gens)
Ich bekam in der Zeile cuda.synchronize() einen „Fehler 700“.
Als ich versuchte, dies mithilfe von Druckanweisungen zu debuggen, bemerkte ich, dass der Code erfolgreich kompiliert wurde und auch plausible Antworten lieferte, was darauf hindeutet, dass er ordnungsgemäß ausgeführt wird, wenn dem Code eine Druckanweisung hinzugefügt wird. Dies lässt mich vermuten, dass es ein Problem mit der Thread-Synchronisierung gibt und die kompilierte Version mit der print-Anweisung dies irgendwie vermeidet. Der momentum_update-Code lautet wie folgt:

Code: Select all

def momentum_update(config, dt, staple_index_array, Barray, V2Barray, idx, out, g):

links = config[0]
momentum = config[1]
inshape = links.shape

numnodes = inshape[0]
numdims = inshape[1]

total_matricies = numnodes * numdims

if idx >= total_matricies:
return

nodeindex = idx // numdims
direction = idx % numdims

if idx == 0:
print("") #there for debug reasons, not entirely sure what's happening here

#making the staple

temp = cuda.local.array((2, 2), dtype=complex128)
temp2 = cuda.local.array((2, 2), dtype=complex128)
Vdirection = cuda.local.array((2,2), dtype=complex128)

Vdirection[0,0] = 0
Vdirection[0, 1] = 0
Vdirection[1, 0] = 0
Vdirection[1, 1] = 0

for i in range(numdims):
idx_tuple_1 = staple_index_array[nodeindex, direction,i, 0, 0]
idx_tuple_2 = staple_index_array[nodeindex, direction, i, 0, 1]
idx_tuple_3 = staple_index_array[nodeindex, direction, i, 0, 2]
idx_tuple_4 = staple_index_array[nodeindex, direction, i, 1, 0]
idx_tuple_5 = staple_index_array[nodeindex, direction, i, 1, 1]
idx_tuple_6 = staple_index_array[nodeindex, direction, i, 1, 2]

staple_matrix_1 = links[idx_tuple_1[0], idx_tuple_1[1]]
staple_matrix_2 = links[idx_tuple_2[0], idx_tuple_2[1]]
staple_matrix_3 = links[idx_tuple_3[0], idx_tuple_3[1]]

staple_matrix_4 = links[idx_tuple_4[0], idx_tuple_4[1]]
staple_matrix_5 = links[idx_tuple_5[0], idx_tuple_5[1]]
staple_matrix_6 = links[idx_tuple_6[0], idx_tuple_6[1]]

Bval = Barray[nodeindex, direction, i]
V2Bval = V2Barray[nodeindex, direction, i]

#calculating first staple
dagger_2x2_cuda(staple_matrix_2, temp)

matmul_2x2_cuda(staple_matrix_1, temp, temp2)

dagger_2x2_cuda(staple_matrix_3, temp)

matmul_2x2_cuda(temp2, temp, temp2)

scale_2x2_cuda(temp2, Bval, temp2)
add_2x2_cuda(temp2, Vdirection, Vdirection)

# calculating second staple
dagger_2x2_cuda(staple_matrix_4, temp)
dagger_2x2_cuda(staple_matrix_5, temp2)
matmul_2x2_cuda(temp, temp2, temp2)
matmul_2x2_cuda(temp2, staple_matrix_6, temp2)
scale_2x2_cuda(temp2, V2Bval, temp2)
add_2x2_cuda(temp2, Vdirection, Vdirection)

#calculating staple contribution
matmul_2x2_cuda(links[nodeindex, direction], Vdirection, temp)

dagger_2x2_cuda(temp, temp2)

scale_2x2_cuda(temp, -1, temp)
add_2x2_cuda(temp2, temp, temp)

scale_2x2_cuda(temp, 1/g**2, temp)
scale_2x2_cuda(temp, dt, temp)

#calculating new momentum
add_2x2_cuda(momentum[nodeindex, direction], temp, temp2)
for i in range(2):
for j in range(2):
config[1][nodeindex, direction,i,j] = temp2[i,j]

Der eigentliche momentum_update_kernel-Code ist nicht besonders interessant und definiert im Wesentlichen nur idx und ruft momentum_update auf, daher habe ich ihn hier nicht aufgenommen.
Ein mögliches Problem ist nun eine Art Race Condition, da momentum_update sowohl in die Konfiguration liest als auch aus ihr schreibt. Ich vermute jedoch, dass dies nicht der Fall ist. config ist ein (2, N, d, 2, 2)-Array, und jeder Thread in der Momentum-Aktualisierung sollte nur lesen aus:
  • Link-Array, dem in config[0] gespeicherten (N, d, 2, 2)-Array und
  • dem spezifischen Momentum-Wert, den es aktualisiert.
Es können also mehrere Threads aus demselben lesen sein Speicher auf einmal, aber es sollte nichts von etwas gelesen werden, in das von einem anderen Thread geschrieben wird.
Wenn ich die Größe der Simulation auf die Größe vergrößere, mit der ich sie tatsächlich ausführen möchte, stürzt sie ab, unabhängig davon, ob die Druckanweisung vorhanden ist, sodass ich die Druckanweisung nicht einfach als Hacky-Fix belassen kann.
Gibt es zumindest eine Möglichkeit, das zu debuggen? Offensichtlich ruft momentum_update mehrere andere Funktionen auf, aber wenn es sich um einen Fehler bei den anderen Funktionen handeln würde, würde ich erwarten, dass die hamiltonsche Evolution anfängt, mir falsche Antworten zu geben (ich hatte früher beispielsweise Fehler in matmul_2x2_cuda, die dazu führten, dass es nicht richtig funktionierte, wenn das Ausgabearray mit einem der Eingaben übereinstimmte, aber ich konnte es erkennen, weil die Simulation plötzlich numerisch instabil wurde), was nicht zu passieren scheint.
Ich laufe Dies auf der GTX1060 in meinem Desktop, aber der Fehler ist beispielsweise auch auf den GPU-Knoten von ComputeCanada vorhanden (und tatsächlich funktioniert der Print-Anweisungs-Hack dort nicht).

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post