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

Python pyCuda,发送多个单变量参数的问题,python,python-3.x,cuda,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 pixelco

我这里有一个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")

其中唯一的区别是在两行上,内核头和它的调用。内核本身的实际代码是不变的,但是这个小小的添加完全破坏了程序。编译器和解释器都不会抛出任何错误。我不知道如何开始调试它,我完全弄糊涂了。

好的,所以通过将变量参数更改为内核中的指针,它修复了代码,我不知道如何或为什么。这是内核的修改版本

__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];
}

代码的其余部分保持不变。如果有人想解释为什么这是一个成功的修复程序,我将不胜感激。

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


只需将带有正确numpy数据类型的标量直接传递给内核调用。不要在中使用
设备。在最初的案例中,这是一个完全的意外

啊,好的,谢谢。这很有道理。我认为在任何情况下,打电话进来和出去都是必要的,但我想不是