【问题标题】:printf with PyCUDA (using Kepler GPU)带有 PyCUDA 的 printf(使用 Kepler GPU)
【发布时间】:2016-12-18 09:53:56
【问题描述】:

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

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

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

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

我使用 Python 3.5(Anaconda 构建)、Spyder 作为 IDE(从终端启动)和带有 El Capitan 的 iMac。 GPU 是 GeForce GT 755M。

【问题讨论】:

    标签: python-3.x cuda printf pycuda


    【解决方案1】:

    您尝试使用的示例中的代码没有任何问题,并且非常适合在 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 模块触发的上下文清理会自动刷新缓冲区。

    【讨论】:

    • 嗨@talonmies,非常感谢您抽出宝贵时间回复。我运行了上面的第一个代码块 - 应用了 cuda.Context.synchronize() 行的示例 - 但我仍然没有打印出来。但是,当我从终端运行相同的代码时,它确实从内核打印 - 上面第二个块中的“我是 x.y”行。
    • 在进一步调查中,我的 iPython 和 Python 控制台发生了一些奇怪的事情:如果我在 Python shell(包括“cuda.Context.synchronize()”)中运行示例代码,它会打印为这应该。但是,当我在 iPython shell 中运行它时,它会将输出发送到“Kernel 1”(控制台窗口中的一个选项卡,而不是 iPython shell 中的一个选项卡),我认为它与 iPython shell 相关联。所以这看起来更像是一个 iPython 问题。如果您有更多想法,我很乐意听到,否则我将改用 Python shell 而不是 iPython。
    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多