【问题标题】:Multiply two-dimensional matrices.‏ with pycuda使用 pycuda 将二维矩阵相乘。
【发布时间】:2012-12-27 01:22:26
【问题描述】:

如何迭代两个数组?

__global__ void euclidean(float *x, float *y, int dim_x, int dim_y, int ms, float *solution) {

            int idx = threadIdx.x + blockDim.x * blockIdx.x;
            int idy = threadIdx.y + blockDim.y * blockIdx.y;

            float result = 0.0;

            for (int iter = 0; iter < ms; iter++) {

                float x_e = x[idy * ms + iter];
                float y_e = y[idx * ms + iter];

                result += (x_e * y_e);
            }
}

输入: X = [[1,2], [3,4], [5,6], [7,8], [9,10]]Y = [[0,0], [1,1]]

预期输出: [[0, 3], [0, 7], [0, 11], [0, 15]. [0, 19]]

我该怎么做?我的困难是在 X 和 Y 上进行迭代。

预期:

[idx: 0 idy: 0 = 0] [idx: 1 idy: 0 = 3] [idx: 2 idy: 0 = 0] [idx: 3 idy: 0 = 7] [idx: 4 idy: 0 = 0] [idx: 0 idy: 1 = 11] [idx: 1 idy: 1 = 0] [idx: 2 idy: 1 = 15] [idx: 3 idy: 1 = 0] [idx: 4 idy: 1 = 19]

【问题讨论】:

    标签: c++ python cuda python-2.7 pycuda


    【解决方案1】:

    我会执行以下操作来将 2 个矩阵相乘。这可以处理边界条件,因此应该适用于任何网格/块大小。

    // Compute C = A * B
    __global__ void matrixMultiply(float * A, float * B, float * C,
                       int numARows, int numAColumns,
                       int numBRows, int numBColumns,
                       int numCRows, int numCColumns) {
        float cValue = 0;
        int Row = blockIdx.y * blockDim.y + threadIdx.y;
        int Col = blockIdx.x * blockDim.x + threadIdx.x;
    
        if ((Row < numCRows) && (Col < numCColumns)) {
            for (int k = 0; k < numAColumns; k++) {
                cValue += A[Row*numAColumns + k] * B[k*numBColumns + Col];
            }
            C[Row*numCColumns + Col] = cValue;
        }
    }
    

    如果您想要更高效的实现,您还可以使用共享内存:

    // Compute C = A * B
    __global__ void matrixMultiplyShared(float * A, float * B, float * C,
                         int numARows, int numAColumns,
                         int numBRows, int numBColumns,
                         int numCRows, int numCColumns) {
        __shared__ float ds_A[TILE_WIDTH_I][TILE_WIDTH_I];
        __shared__ float ds_B[TILE_WIDTH_I][TILE_WIDTH_I];
    
        int bx = blockIdx.x;
        int by = blockIdx.y;
        int tx = threadIdx.x;
        int ty = threadIdx.y;
    
        int Row = by * TILE_WIDTH + ty;
        int Col = bx * TILE_WIDTH + tx;
        float cValue = 0;
    
        for (int m = 0; m < (numAColumns/TILE_WIDTH); m++) {
            if (Row < numARows && m*TILE_WIDTH_I + tx < numAColumns) {
              ds_A[ty][tx] = A[Row*numAColumns + m*TILE_WIDTH_I + tx];
            } else {
             ds_A[ty][tx] = 0;
           }
    
            if (m*TILE_WIDTH_I + ty < numBRows && Col < numBColumns) {
              ds_B[ty][tx] = B[(m*TILE_WIDTH_I + ty)*numBColumns + Col];
           } else {
             ds_B[ty][tx] = 0;
           }
    
            __syncthreads();
    
            if ((Row < numCRows) && (Col < numCColumns)) {
                for (int k = 0; k < TILE_WIDTH; k++) {
                    cValue += ds_A[ty][k] * ds_B[k][tx];
                }
            }
    
            __syncthreads();
        }
    
        if ((Row < numCRows) && (Col < numCColumns)) {
            C[Row*numCColumns + Col] = cValue;
        }
    }
    

    【讨论】:

    • 不起作用。检查pastebin.com/dUvz56sR。输入 multMatrix([[2,2], [3,3]], [[2,2], [3,3]])。输出:[[10, 10], [15,15]]。预期输出:[[8, 12], [12, 18]]
    • 似乎可以使用具有不同行数的矩阵。例如 multMatrix([[2,2], [3,3]], [[2,2], [3,3], [4,4]])
    • 你确定你通过 PyCuda 传递了正确的参数吗?你能分享它为你的例子产生的输出吗?这些内核对我来说适用于 Cuda 上的许多不同矩阵。例如,[[2, 2], [3, 3]] * [[2, 2], [3, 3]],输出应该是 [[10, 10], [15, 15]] 和不是 [[8, 12], [8, 12]],你是怎么得出这个结果的?
    • 对不起。我最终弄得一团糟。当我实际上想要另一个操作时,我问了一个乘法的例子。混淆一切。但是上面的 sn-p 代码对我帮助很大。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多