2016-08-11 81 views
1

我遇到了從pycuda內核打印的問題:printf()函數什麼都不打印。printf與PyCUDA(使用開普勒GPU)

還有一個類似的問題發佈在@ username_4567 here,也給出了一個例子here,@harrism在他的答案中指出。但是,我已經實現了pycuda example中的代碼,並且沒有打印(儘管沒有錯誤)。我猜測問題在於我使用的是Kepler GPU,並且該示例指定它僅適用於Fermi設備。

是否有人知道如何使用我的Kepler GPU從pycuda內核打印信息?我可能設計了一個解決方法,它將要打印的任何數據複製到CPU上,然後通過Python進行打印,但我更願意避免這種情況!

我在網上搜索過任何有同樣問題的人,但是我什麼也沒找到。

我正在使用Python 3.5(Anaconda build),Spyder作爲IDE(從終端啓動)和帶有El Capitan的iMac。 GPU是GeForce GT 755M。

回答

2

您嘗試使用的示例中的代碼沒有任何問題,它非常適合在開普勒GPU上使用。問題在於CUDA運行時使用緩衝區來輸出printf,該輸出僅由驅動程序定期刷新,並且需要由幾個API調用中的任何一個觸發。

我猜你正在交互式python shell中測試這個。在這種情況下,你應該添加一個明確的同步調用代碼:

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

mod = SourceModule(""" 
    #include <stdio.h> 

    __global__ void say_hi() 
    { 
     printf("I am %d.%d\\n", threadIdx.x, threadIdx.y); 
    } 
    """) 

func = mod.get_function("say_hi") 
func(block=(4,4,1)) 

# Flush context printf buffer 
cuda.Context.synchronize() 

另外,如果添加認領線運行在命令提示符下未修改代碼:

$ cat hello_cuda.py 
#!/usr/bin/env python 
import pycuda.driver as cuda 
import pycuda.autoinit 
from pycuda.compiler import SourceModule 

mod = SourceModule(""" 
    #include <stdio.h> 

    __global__ void say_hi() 
    { 
     printf("I am %d.%d\\n", threadIdx.x, threadIdx.y); 
    } 
    """) 

func = mod.get_function("say_hi") 
func(block=(4,4,1)) 

$ ./hello_cuda.py 
I am 0.0 
I am 1.0 
I am 2.0 
I am 3.0 
I am 0.1 
I am 1.1 
I am 2.1 
I am 3.1 
I am 0.2 
I am 1.2 
I am 2.2 
I am 3.2 
I am 0.3 
I am 1.3 
I am 2.3 
I am 3.3 

它也將工作。在後一種情況下,它是由pycuda.autoinit模塊觸發的上下文清理,該模塊自動刷新緩衝區。

+0

嗨@talonmies,非常感謝您花時間回覆。 我運行了上面的第一塊代碼 - 應用了cuda.Context.synchronize()這一行的例子 - 但我仍然沒有打印出任何東西。 但是,當我從終端運行相同的代碼時,它從內核打印出來 - 上面第二個塊中的「我是x.y」行。 –

+0

關於進一步調查,我的iPython和Python控制檯出現了一些奇怪的事情:如果我在Python shell(包括「cuda.Context.synchronize()」)中運行示例代碼,它會按照它應該打印出來。但是,當我在iPython shell中運行它時,它會將輸出發送到「Kernel 1」(控制檯窗口中的一個選項卡,而不是iPython shell中),我認爲它與iPython shell相關聯。 所以這看起來更像是一個iPython問題。如果你有更多的想法,我很樂意聽到他們,否則我會切換到使用Python shell而不是iPython。 –