2017-12-26 13 views
-2

Ich habe einen Artikel über Parallel Seam Carving CPU-GPU gefunden und versuche den Prozess zu verfolgen. CPU-GPU Hybrid and Concurrency method for seam carving. Ich habe bereits die 2 Streams erstellen. Aber ich habe ein Problem, wenn ich versuche, eine asynchrone Kopie der indexMap von Gerät zu Host zu erstellen. Es scheint, als ob die Daten in der indexMap nicht aktualisiert werden. Ich habe immer Nullen Array als die Initialisierung.Cuda Streams mit Pycuda

Hier finden Sie meinen Code.

import pycuda.driver as cuda 
import pycuda.autoinit 
import pycuda.gpuarray as gpuarray 
from pycuda.compiler import SourceModule 
import numpy 

stream1 = cuda.Stream() 
stream2 = cuda.Stream() 

energyMap = numpy.random.randn(4,4).astype(numpy.float32) 
indexMap = numpy.zeros((3,4)).astype(numpy.float32) 
sumMap = numpy.zeros((3,4)).astype(numpy.float32) 

energyMap_gpu = gpuarray.to_gpu_async(energyMap, stream = stream2) 
indexMap_gpu = cuda.mem_alloc(indexMap.nbytes) 
sumMap_gpu = gpuarray.to_gpu_async(sumMap, stream = stream2) 

cuda.memcpy_htod(indexMap_gpu, indexMap) 

mod = SourceModule(""" 
__global__ void getIndexMap(float *energyMap, float *indexMap){ 
     some code.... 
} 


__global__ void getSumMap(float *indexMap, float *sumMap){ 
     some code.... 
} 
""") 

getIndexMap = mod.get_function("getIndexMap") 
getSumMap = mod.get_function("getSumMap") 

getIndexMap(energyMap_gpu, indexMap_gpu, block=(4,4,1), stream=stream2) 
cuda.memcpy_dtoh_async(indexMap, indexMap_gpu, stream=stream1) 
getSumMap(sumMap_gpu, indexMap_gpu, block=(4,4,1), stream=stream2) 

print(energyMap) 
print(indexMap) 

Als ich cuda.memcpy_dtoh_async (indexMap, indexMap_gpu, Strom = stream1) von cuda.memcpy_dtoh (indexMap, indexMap_gpu) ändern bekomme ich das gute Ergebnis.

Soll ich das CudaWaitEvent verwenden? Wenn ja, wie sollte ich es benutzen? Danke!

+1

On-Stack-Überlauf, wenn Sie eine Frage der Form "Warum funktioniert das nicht?" du solltest ein [mcve] bereitstellen. Lesen Sie Punkt 1 [hier] (https://stackoverflow.com/help/on-topic) (<- klicken Sie hier und lesen Sie) –

+0

Problem scheint auf Cross-Posting [hier] (https: // devtalk. nvidia.com/default/topic/1028026/cuda-programming-and-performance/-cuda-streams-with-pycuda/). –

+0

Problem gelöst dank Nvidias Forum. https://devtalk.nvidia.com/default/topic/1028026/cuda-programming-and-performance/-cuda-streams-with-pycuda/ – Hadji

Antwort

0

Auf den Punkt gebracht, OP wurde nach einem Verfahren zu fragen diese async dtoh geschieht kopieren zu verhindern:

cuda.memcpy_dtoh_async(indexMap, indexMap_gpu, stream=stream1) 

bis dieser Kernel-Aufruf abgeschlossen war:

getIndexMap(energyMap_gpu, indexMap_gpu, block=(4,4,1), stream=stream2) 

, da sie ins Leben gerufen werden nicht in der gleiche Stream, die CUDA-Stream-Syntax wird das nicht garantieren. Es gibt eine Reihe von möglichen Ansätzen, um dies zu beheben, aber letztendlich wollte OP ein Ereignis in stream2 verwenden und veranlassen, dass stream1 auf dieses Ereignis wartet. Etwas wie dieses:

event1 = cuda.Event() 
... 
getIndexMap(energyMap_gpu, indexMap_gpu, block=(4,4,1), stream=stream2) 
event1.record(stream2) 
stream1.wait_for_event(event1) 
cuda.memcpy_dtoh_async(indexMap, indexMap_gpu, stream=stream1) 
... 

wie beschrieben here.

Ferner kann selbst mit dem oben mod, wenn es gewünscht ist, dass die Ergebnisse ausgedruckt hier aus:

print(indexMap) 

reflektierend der eingangs genannten dtoh async kopieren, dann wird es für einen weiteren Strom Synchronisieren notwendig sein (auf stream1) zu verwenden, vor dem print Anruf.

Verwandte Themen