printf with PyCUDA(使用Kepler GPU)

时间:2016-08-11 15:08:28

标签: python-3.x cuda printf pycuda

我在pycuda内核中打印时遇到问题:printf()函数什么都没打印。

@ username_4567发布了一个类似的问题here,还有here给出的例子,@harrism在答案中指出了这个问题。但是,我已在pycuda example中实现了代码,并且没有打印任何内容(尽管没有错误)。我猜测问题是我使用的是Kepler GPU,该示例指出它仅适用于Fermi设备。

有人知道如何使用我的Kepler GPU从pycuda内核中打印信息吗?可能是我可以设计的解决方法,它将我要打印的任何数据复制到CPU然后通过Python进行打印,但我更愿意避免这种情况!

我在网上搜索了有同样问题的人,但我一无所获。

我使用的是Python 3.5(Anaconda版本),Spyder作为IDE(从终端推出)和带有El Capitan的iMac。 GPU是GeForce GT 755M。

1 个答案:

答案 0 :(得分:3)

您尝试使用的示例中的代码没有任何问题,它非常适合在Kepler 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()

或者,如果添加shebang行并从命令提示符运行未修改的代码:

$ 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模块触发的上下文清理,它自动刷新缓冲区。