我正在尝试使用Alea CuBlas axpy进行矩阵添加,但它似乎只添加了顶行
let matrixAddition (a:float[,]) (b: float[,]) =
use mA = gpu.AllocateDevice(a)
use mB = gpu.AllocateDevice(b)
blas.Axpy(a.Length,1.,mA.Ptr,1,mB.Ptr,1)
Gpu.Copy2DToHost(mB)
答案 0 :(得分:1)
我举了你的例子,它运行良好。
代码:
var gpu = Gpu.Default;
var blas = Blas.Get(Gpu.Default);
var hostA = new float[,]
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
};
var hostB = new float[,]
{
{10, 20, 30},
{40, 50, 60},
{70, 80, 90},
};
PrintArray(hostA);
PrintArray(hostB);
var deviceA = gpu.AllocateDevice(hostA);
var deviceB = gpu.AllocateDevice(hostB);
blas.Axpy(deviceA.Length, 1f, deviceA.Ptr, 1, deviceB.Ptr, 1);
var hostC = Gpu.Copy2DToHost(deviceB);
PrintArray(hostC);
Print Help:
private static void PrintArray(float[,] array)
{
for (var i = 0; i < array.GetLength(0); i++)
{
for (var k = 0; k < array.GetLength(1); k++)
{
Console.Write("{0} ", array[i, k]);
}
Console.WriteLine();
}
Console.WriteLine(new string('-', 10));
}
这就是我得到的:
两个问题: - 您使用的是哪种版本的AleaGpu? - 您使用的是什么版本的CUDA工具包?
我对我的样本编码: Alea 3.0.4-beta2 ,我有 CudaToolkit 8.0 。
为了确保我尝试在F#中编写您的示例代码。 (我不会说流利的F#)
代码:
let gpu = Gpu.Default;
let blas = Blas.Get(Gpu.Default);
let hostA: float[,] = array2D [[ 1.0; 2.0; 3.0 ]; [ 4.0; 5.0; 6.0 ]; [ 7.0; 8.0; 9.0 ]]
let hostB: float[,] = array2D [[ 10.0; 20.0; 30.0 ]; [ 40.0; 50.0; 60.0 ]; [ 70.0; 80.0; 90.0 ]]
PrintArray(hostA)
PrintArray(hostB)
use deviceA = gpu.AllocateDevice(hostA);
use deviceB = gpu.AllocateDevice(hostB);
blas.Axpy(deviceA.Length, 1.0, deviceA.Ptr, 1, deviceB.Ptr, 1);
let hostC = Gpu.Copy2DToHost(deviceB);
PrintArray(hostC)
Print Help:
let PrintArray(array: float[,]): unit =
for i in 0 .. array.GetLength(0) - 1 do
for k in 0 .. array.GetLength(1) - 1 do
Console.Write("{0} ", array.[i, k]);
Console.WriteLine();
Console.WriteLine(new string('-', 10));
答案 1 :(得分:1)
JokingBear的代码和redb代码之间有一个重要的区别。
在问题代码的这一行
blas.Axpy(a.Length,1.,mA.Ptr,1,mB.Ptr,1)
a 的类型为 float [,] ,长度将为该矩阵 a 中元素的数量。
但是,更正的代码使用此
blas.Axpy(deviceA.Length, 1f, deviceA.Ptr, 1, deviceB.Ptr, 1);
deviceA 不再是 float [,] ,而是 DeviceMemory2D 对象。
DeviceMemory2D.Length 比(float [,])更令人惊讶地更大(我的硬件上为3x3矩阵为384)。长度因为GPU上的分配似乎由于某些未知的原因占据了更多的空间。
JokingBear的代码仅对顶行进行求和的关键原因是因为(float [,])。长度对于GPU内存上的数据结构而言太短了。与alea的版本无关。