python - pyCuda,发送多个单变量参数的问题

标签 python python-3.x cuda pycuda

我这里有一个 pycuda 程序,它从命令行读取图像并保存反转颜色的版本:

import pycuda.autoinit
import pycuda.driver as device
from pycuda.compiler import SourceModule as cpp

import numpy as np
import sys
import cv2

modify_image = cpp("""
__global__ void modify_image(int pixelcount, unsigned char* inputimage, unsigned char* outputimage)
{
  int id = threadIdx.x + blockIdx.x * blockDim.x;
  if (id >= pixelcount)
    return;

  outputimage[id] = 255 - inputimage[id];
}
""").get_function("modify_image")

print("Loading image")

image = cv2.imread(sys.argv[1], cv2.IMREAD_UNCHANGED).astype(np.uint8)

print("Processing image")

pixels = image.shape[0] * image.shape[1]
newchannels = []
for channel in cv2.split(image):
  output = np.zeros_like(channel)
  modify_image(
    device.In(np.int32(pixels)),
    device.In(channel),
    device.Out(output),
    block=(1024,1,1), grid=(pixels // 1024 + 1, 1))
  newchannels.append(output)
finalimage = cv2.merge(newchannels)

print("Saving image")

cv2.imwrite("processed.png", finalimage)

print("Done")

即使在较大的图像上,它也能正常工作。然而,在尝试扩展程序的功能时,我遇到了一个非常奇怪的问题,其中向内核添加第二个变量参数会导致程序完全失败,只是保存一个完全黑色的图像。以下代码不起作用;

import pycuda.autoinit
import pycuda.driver as device
from pycuda.compiler import SourceModule as cpp

import numpy as np
import sys
import cv2

modify_image = cpp("""
__global__ void modify_image(int pixelcount, int width, unsigned char* inputimage, unsigned char* outputimage)
{
  int id = threadIdx.x + blockIdx.x * blockDim.x;
  if (id >= pixelcount)
    return;

  outputimage[id] = 255 - inputimage[id];
}
""").get_function("modify_image")

print("Loading image")

image = cv2.imread(sys.argv[1], cv2.IMREAD_UNCHANGED).astype(np.uint8)

print("Processing image")

pixels = image.shape[0] * image.shape[1]
newchannels = []
for channel in cv2.split(image):
  output = np.zeros_like(channel)
  modify_image(
    device.In(np.int32(pixels)),
    device.In(np.int32(image.shape[0])),
    device.In(channel),
    device.Out(output),
    block=(1024,1,1), grid=(pixels // 1024 + 1, 1))
  newchannels.append(output)
finalimage = cv2.merge(newchannels)

print("Saving image")

cv2.imwrite("processed.png", finalimage)

print("Done")

唯一的区别是两行,内核头和它的调用。内核本身的实际代码没有改变,但这个小小的添加却完全破坏了程序。编译器和解释器都不会抛出任何错误。我不知道如何开始调试它,并且完全困惑。

最佳答案

device.In 及其相关项设计用于支持 Python 缓冲区协议(protocol)(如 numpy 数组)的对象。问题的根源是使用它们传输非缓冲区对象。

只需将具有正确 numpy 数据类型的标量直接传递给内核调用即可。不要使用device.In。事实上,这在最初的案例中起作用完全是一个意外

关于python - pyCuda,发送多个单变量参数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44125164/

相关文章:

python - Windows:获取默认麦克风名称

python - 列出预训练模型中 spaCy 中最相似的词

python - 使用 Python 从双指针 C++ 函数中读取字符串

memory - Cuda 合并内存加载行为

python - 如何检查两个值之间的变化(百分比)?

Python,用 "with"语句包装函数的装饰器

python - Pandas合并两个excel中的数据

cuda vs2013 v120xp 编译错误

CUDA随机数生成

python - 使用 json.dump 引发 JSONDecodeError ("Extra data", s, end)