Cudafy.NET - CUDA.NET 异常 ErrorInvalidValue
Cudafy.NET - CUDA.NET exception ErrorInvalidValue
我正在使用 Cudafy.NET 在 GPU 上执行图像处理。我已经设置了 class 以及第一个函数(CPU 上的 PerformBarrelCorrection 运行)来设置多个线程来为图像中的每个像素执行逻辑计算。
但是每次我在 GPU 上启动函数时都会抛出异常:
An exception of type 'Cudafy.Host.CudafyHostException' occurred in
Cudafy.NET.dll but was not handled in user code
Additional information: CUDA.NET exception: ErrorInvalidValue.
这里是 class 的完整注释,以显示引发异常的行。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cudafy;
using Cudafy.Host;
using Cudafy.Translator;
using System.Drawing;
using System.IO;
namespace AForgeTrial
{
class GPUProcessing
{
public CudafyModule km;
public GPGPU gpu;
public GPUProcessing() {
km = CudafyTranslator.Cudafy();
gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
}
public Bitmap PerformBarrelCorrection(Bitmap source, double strength, float zoom, int imageWidth, int imageHeight)
{
byte[] bmp = ImageToByteArray2(source);
int halfWidth = imageWidth / 2;
int halfHeight = imageHeight / 2;
double correctionRadius = Math.Sqrt(((imageWidth * imageWidth) + (imageHeight * imageHeight)) / strength);
byte[] dev_src_bmp = gpu.CopyToDevice(bmp);
byte[] dst_bmp = new byte[bmp.Length];
byte[] dev_dst_bmp = gpu.Allocate<byte>(dst_bmp);
double[] correctPass = new double[1];
correctPass[0] = correctionRadius;
double[] dev_correctionRadius = gpu.CopyToDevice<double>(correctPass);
float[] zoomPass = new float[1];
zoomPass[0] = zoom;
float[] dev_zoom = gpu.CopyToDevice<float>(zoomPass);
int[] halfWidthPass = new int[1];
halfWidthPass[0] = halfWidth;
int[] dev_halfWidth = gpu.CopyToDevice<int>(halfWidthPass);
int[] halfHeightPass = new int[1];
halfHeightPass[0] = imageHeight;
int[] dev_halfHeight = gpu.CopyToDevice<int>(halfHeightPass);
//int blksize = ((bmp.Length / 3) / 128) + 1;
// EXCEPTION HAPPENS ON THE LINE BELOW
gpu.Launch((bmp.Length / 3), 1).BarrelCorrectionSingleOperation(dev_src_bmp, dev_dst_bmp, dev_correctionRadius, dev_zoom, dev_halfWidth, dev_halfHeight);
gpu.CopyFromDevice(dev_dst_bmp, dst_bmp);
// Convert dst_bmp to Bitmap and return it
Bitmap result;
using (MemoryStream ms = new MemoryStream(dst_bmp))
{
result = new Bitmap(ms);
}
return result;
}
[Cudafy]
public static void BarrelCorrectionSingleOperation(GThread thread, byte[] src_bmp, byte[] dst_bmp, double[] correctionRadius, float[] zoom, int[] halfWidth, int[] halfHeight)
{
// Move a single byte from source to destination or fill if required
}
public static byte[] ImageToByteArray(Bitmap img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
public static byte[] ImageToByteArray2(Bitmap img)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
public void Close() {
gpu.FreeAll();
}
}
}
有人知道这件事吗??提前致谢。
为任何感兴趣的人解决了我自己的问题,尽管它非常小众,但我的代码充满了漏洞。这成功地使用 Cudafy 执行了实时镜头校正。
public void PerformBarrelCorrection(double strength, float zoom)
{
CheckIsSet();
int halfWidth = Width / 2;
int halfHeight = Height / 2;
double correctionRadius = Math.Sqrt(((Width * Width) + (Height * Height)) / strength);
_gpu.Launch(Width, Height).BarrelCorrectionSingleOperation(_gdata.SourceImage, _gdata.ResultImage, correctionRadius, zoom, halfWidth, halfHeight);
}
[Cudafy]
public static void BarrelCorrectionSingleOperation(GThread thread, byte[] src_bmp, byte[] dst_bmp, double correctionRadius, float zoom, int halfWidth, int halfHeight)
{
// Move a single byte from source to destination or fill if required
int x = thread.blockIdx.x;
int y = thread.threadIdx.x;
int newX = x - halfWidth;
int newY = y - halfHeight;
double distance = Math.Sqrt((newX * newX) + (newY * newY));
double r = distance / correctionRadius;
double theta;
if (r == 0)
{
theta = 1;
}
else
{
theta = Math.Atan(r) / r;
}
int sourceX = (int)(halfWidth + theta * newX * zoom);
int sourceY = (int)(halfHeight + theta * newY * zoom);
dst_bmp[(y * ((halfWidth * 2) * 4)) + (x * 4)] = src_bmp[(sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)];
dst_bmp[(y * (((halfWidth * 2) * 4)) + (x * 4)) + 1] = src_bmp[((sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)) + 1];
dst_bmp[(y * (((halfWidth * 2) * 4)) + (x * 4)) + 2] = src_bmp[((sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)) + 2];
dst_bmp[(y * (((halfWidth * 2) * 4)) + (x * 4)) + 3] = src_bmp[((sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)) + 3];
}
我正在使用 Cudafy.NET 在 GPU 上执行图像处理。我已经设置了 class 以及第一个函数(CPU 上的 PerformBarrelCorrection 运行)来设置多个线程来为图像中的每个像素执行逻辑计算。
但是每次我在 GPU 上启动函数时都会抛出异常:
An exception of type 'Cudafy.Host.CudafyHostException' occurred in Cudafy.NET.dll but was not handled in user code
Additional information: CUDA.NET exception: ErrorInvalidValue.
这里是 class 的完整注释,以显示引发异常的行。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cudafy;
using Cudafy.Host;
using Cudafy.Translator;
using System.Drawing;
using System.IO;
namespace AForgeTrial
{
class GPUProcessing
{
public CudafyModule km;
public GPGPU gpu;
public GPUProcessing() {
km = CudafyTranslator.Cudafy();
gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
}
public Bitmap PerformBarrelCorrection(Bitmap source, double strength, float zoom, int imageWidth, int imageHeight)
{
byte[] bmp = ImageToByteArray2(source);
int halfWidth = imageWidth / 2;
int halfHeight = imageHeight / 2;
double correctionRadius = Math.Sqrt(((imageWidth * imageWidth) + (imageHeight * imageHeight)) / strength);
byte[] dev_src_bmp = gpu.CopyToDevice(bmp);
byte[] dst_bmp = new byte[bmp.Length];
byte[] dev_dst_bmp = gpu.Allocate<byte>(dst_bmp);
double[] correctPass = new double[1];
correctPass[0] = correctionRadius;
double[] dev_correctionRadius = gpu.CopyToDevice<double>(correctPass);
float[] zoomPass = new float[1];
zoomPass[0] = zoom;
float[] dev_zoom = gpu.CopyToDevice<float>(zoomPass);
int[] halfWidthPass = new int[1];
halfWidthPass[0] = halfWidth;
int[] dev_halfWidth = gpu.CopyToDevice<int>(halfWidthPass);
int[] halfHeightPass = new int[1];
halfHeightPass[0] = imageHeight;
int[] dev_halfHeight = gpu.CopyToDevice<int>(halfHeightPass);
//int blksize = ((bmp.Length / 3) / 128) + 1;
// EXCEPTION HAPPENS ON THE LINE BELOW
gpu.Launch((bmp.Length / 3), 1).BarrelCorrectionSingleOperation(dev_src_bmp, dev_dst_bmp, dev_correctionRadius, dev_zoom, dev_halfWidth, dev_halfHeight);
gpu.CopyFromDevice(dev_dst_bmp, dst_bmp);
// Convert dst_bmp to Bitmap and return it
Bitmap result;
using (MemoryStream ms = new MemoryStream(dst_bmp))
{
result = new Bitmap(ms);
}
return result;
}
[Cudafy]
public static void BarrelCorrectionSingleOperation(GThread thread, byte[] src_bmp, byte[] dst_bmp, double[] correctionRadius, float[] zoom, int[] halfWidth, int[] halfHeight)
{
// Move a single byte from source to destination or fill if required
}
public static byte[] ImageToByteArray(Bitmap img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
public static byte[] ImageToByteArray2(Bitmap img)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
public void Close() {
gpu.FreeAll();
}
}
}
有人知道这件事吗??提前致谢。
为任何感兴趣的人解决了我自己的问题,尽管它非常小众,但我的代码充满了漏洞。这成功地使用 Cudafy 执行了实时镜头校正。
public void PerformBarrelCorrection(double strength, float zoom)
{
CheckIsSet();
int halfWidth = Width / 2;
int halfHeight = Height / 2;
double correctionRadius = Math.Sqrt(((Width * Width) + (Height * Height)) / strength);
_gpu.Launch(Width, Height).BarrelCorrectionSingleOperation(_gdata.SourceImage, _gdata.ResultImage, correctionRadius, zoom, halfWidth, halfHeight);
}
[Cudafy]
public static void BarrelCorrectionSingleOperation(GThread thread, byte[] src_bmp, byte[] dst_bmp, double correctionRadius, float zoom, int halfWidth, int halfHeight)
{
// Move a single byte from source to destination or fill if required
int x = thread.blockIdx.x;
int y = thread.threadIdx.x;
int newX = x - halfWidth;
int newY = y - halfHeight;
double distance = Math.Sqrt((newX * newX) + (newY * newY));
double r = distance / correctionRadius;
double theta;
if (r == 0)
{
theta = 1;
}
else
{
theta = Math.Atan(r) / r;
}
int sourceX = (int)(halfWidth + theta * newX * zoom);
int sourceY = (int)(halfHeight + theta * newY * zoom);
dst_bmp[(y * ((halfWidth * 2) * 4)) + (x * 4)] = src_bmp[(sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)];
dst_bmp[(y * (((halfWidth * 2) * 4)) + (x * 4)) + 1] = src_bmp[((sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)) + 1];
dst_bmp[(y * (((halfWidth * 2) * 4)) + (x * 4)) + 2] = src_bmp[((sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)) + 2];
dst_bmp[(y * (((halfWidth * 2) * 4)) + (x * 4)) + 3] = src_bmp[((sourceY * ((halfWidth * 2) * 4)) + (sourceX * 4)) + 3];
}