使用axpy的CuBlas Matrix Addition

时间:2017-07-05 11:20:42

标签: aleagpu

我正在尝试使用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)

2 个答案:

答案 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));
    }

这就是我得到的:

output

两个问题:   - 您使用的是哪种版本的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的版本无关。