CUDA之矩陣乘法——非方陣計算
說明
A矩陣為M * N,B矩陣為N * M
程式碼
#include "device_functions.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <iostream>
typedef struct {
int width;
int height;
int stride;
float* elements;
} Matrix;
#define BLOCK_SIZE 2
#define N 4
#define M 8
__device__ float GetElement(const Matrix A, int row, int col) {
return A.elements[row * A.stride + col];
}
__device__ void SetElement(Matrix A, int row, int col, float value) {
A.elements[row * A.stride + col] = value;
}
__device__ Matrix GetSubMatrix(Matrix A, int row, int col) {
Matrix Asub;
Asub.width = BLOCK_SIZE;
Asub.height = BLOCK_SIZE;
Asub.stride = A.stride;
Asub.elements = &A.elements[A.stride * BLOCK_SIZE * row+ BLOCK_SIZE * col];
return Asub;
}
__global__ void MatMulKernel(Matrix A, Matrix B, Matrix C) {
int blockRow = blockIdx.y;
int blockCol = blockIdx.x;
Matrix Csub = GetSubMatrix(C, blockRow, blockCol);
float Cvalue = 0;
int row = threadIdx.y;
int col = threadIdx.x;
for (int m = 0; m < (A.width / BLOCK_SIZE); ++m) {
Matrix Asub = GetSubMatrix(A, blockRow, m);
Matrix Bsub = GetSubMatrix(B, m, blockCol);
__shared__ float As[BLOCK_SIZE][BLOCK_SIZE];
__shared__ float Bs[BLOCK_SIZE][BLOCK_SIZE];
As[row][col] = GetElement(Asub, row, col);
Bs[row][col] = GetElement(Bsub, row, col);
__syncthreads();
for (int e = 0; e < BLOCK_SIZE; ++e)
Cvalue += As[row][e] * Bs[e][col];
__syncthreads();
}
SetElement(Csub, row, col, Cvalue);
}
void MatMul(const Matrix A, const Matrix B, Matrix C) {
Matrix d_A;
d_A.width = d_A.stride = A.width;
d_A.height = A.height;
size_t size = A.width * A.height * sizeof(float);
cudaMalloc((void**)&d_A.elements, size);
cudaMemcpy(d_A.elements, A.elements, size,
cudaMemcpyHostToDevice);
Matrix d_B;
d_B.width = d_B.stride = B.width;
d_B.height = B.height;
size = B.width * B.height * sizeof(float);
cudaMalloc((void**)&d_B.elements, size);
cudaMemcpy(d_B.elements, B.elements, size,
cudaMemcpyHostToDevice);
Matrix d_C;
d_C.width = d_C.stride = C.width;
d_C.height = C.height;
size = C.width * C.height * sizeof(float);
cudaMalloc((void**)&d_C.elements, size);
dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
dim3 dimGrid(B.width / dimBlock.x, A.height / dimBlock.y);
MatMulKernel<<<dimGrid, dimBlock>>>(d_A, d_B, d_C);
cudaMemcpy(C.elements, d_C.elements, size,
cudaMemcpyDeviceToHost);
cudaFree(d_A.elements);
cudaFree(d_B.elements);
cudaFree(d_C.elements);
}
void init(Matrix *A,int row, int col) {
A->width=col;
A->height=row;
A->stride=col;
A->elements=(float*) calloc(row*col, sizeof(float));
for(int i=0; i<row*col; i++) A->elements[i]=i;
}
int main() {
//定義四個矩陣,C=A*B為分割成塊使用sharedmemory;C_ref=A*B直接計算;
Matrix A, B, C;
//初始化四個矩陣,賦初值。
init(&A,M,N);
init(&B,N,M);
init(&C,M,M);
int i, j;
printf("A\n");
for(i=0; i<M*N; i++){
printf("%f \t",A.elements[i]);
}
printf("\n");
printf("A\n");
for(i=0; i<M; i++){
for(j=0; j<N; j++) {
printf("%f \t",A.elements[i*N+j]);
}
printf("\n");
}
printf("B\n");
for(i=0; i<N; i++){
for(j=0; j<M; j++) {
printf("%f \t",A.elements[i*M+j]);
}
printf("\n");
}
MatMul(A, B, C);
printf("C\n");
for(i=0; i<M; i++){
for(j=0; j<M; j++) {
printf("%f \t",C.elements[j*M+i]);
}
printf("\n");
}
}
相關推薦
CUDA之矩陣乘法——非方陣計算
說明 A矩陣為M * N,B矩陣為N * M 程式碼 #include "device_functions.h" #include "cuda_runtime.h" #include "device_launch_parameters.h" #incl
CUDA之矩陣乘法
我們已經知道了threads/blocks在CUDA端的組織方式,接下來我們學學多維度空間下的多執行緒模型,下面以矩陣乘法為例。 1. 行優先 儲存方式 二維矩陣在記憶體中的儲存方式受到程式語言的影響,主要可以分為兩種:行優先和列優先。對於程式語言諸如C/C++/CUD
CUDA之矩陣乘法——複數
做好矩陣乘法和轉置之後本來開心得不行的! 準備上手做個最基本的波束形成了! 突然發現希爾伯特變換完以後需要進行各種複數的運算…所以臨時補寫了一個複數乘法… 學著學著好像有點感覺了~!還是蠻有意思的。當然前提是能除錯成功。 用一句傅小姐的名言鼓勵一下“只要
CUDA之矩陣乘法——globalmemory
CUDA 矩陣乘法 使用global memory 報錯 錯誤 17 error : no instance of overloaded function “cudaMalloc”
java 多執行緒平行計算之矩陣乘法(星星筆記)
用java編寫兩個n階的方陣A和B的相乘程式,結果存放在方陣C中,其中使用Runnable介面實現矩陣的乘法。 方陣A和B的初始值如下:(同時開兩個執行緒) 輸出:c中所有元素之和、程式的執行時間 具體的程式如下: package com.xing.matrix; /
CUDA實現矩陣相加的平行計算
(一)目的 熟悉基本的CUDA程式架構以及如何呼叫相應的API進行CUDA程式設計 (二)內容 完成矩陣相加的並行程式的實現(不用share memory實現) 要求: 實現2個矩陣(32*32)的相加,M矩陣的初始值全為2,N矩陣的初始值全為5。同時用C
線性代數之——矩陣乘法和逆矩陣
1. 矩陣乘法 如果矩陣 \(B\) 的列為 \(b_1, b_2, b_3\),那麼 \(EB\) 的列就是 \(Eb_1, Eb_2, Eb_3\)。 \[\boldsymbol{EB = E[b_1 \quad b_2 \quad b_3] = [Eb_1 \quad Eb_2 \quad Eb_3
從矩陣乘法的不同計算方式來看區域性性原理
今天碰到的關於矩陣乘法不同情況下運算速度的問題,隱約記得是因為快取的問題,後來突然想起來CSAPP那本書上講過這個東西的,就是通過矩陣乘法三重迴圈的不同順序來講的區域性性原理的,所以翻過來又看了一下。 兩個矩陣A,B相乘得到C【為了方便起見,把它們都看
CUDA學習--矩陣乘法的並行運算
1. CUDA學習步驟 CPU實現 a*b = c 的矩陣乘法(矩陣尺寸是n*m的,n和m大於1000) 將cpu程式碼移植到cuda。將CPU值傳入GPU,使用cuda計算,與cpu結果對比。 優化思路1:將矩陣分塊進行計算 優化思路2:使用share
Python資料科學之矩陣乘法
背景 Python資料分析離不開矩陣的基礎知識,週末看了一章節的數學基礎知識,重新學習了一下矩陣的乘法知識,線性代數的知識還是十年前上大學時學的,早就忘乾淨了,今日重新整理了一下,其實就是基本的規則記憶,還是能夠理解的。 矩陣乘法定義 百度得到的定義為
矩陣乘法的平行計算
設兩個矩陣A和B,大小分別為M * N 和 N * P, 如果C = A * B, 則C的大小為M * P。 矩陣演算法的演算法表示,虛擬碼如下: for (i = 0; i < M; ++i){ for (j = 0; j < P; +
OpenCL之矩陣乘法實現
kernel 在opencl中,一般最優價值的就是kernel,前面寫的配置檔案基本沒有很大的差別,主要是kernel寫法上。其中矩陣運算又是最能體現opencl價值的地方。先上寫的kernel: __kernel void matrix_mult
cuda編程-矩陣乘法(1)
return mac cpu ims iostream oba 簡單的 oid memory 本方法采用簡單的單線程計算每組行和列乘加運算 代碼如下: #include <stdio.h> #include <stdlib.h> #include
矩陣乘法來加速遞推式計算
span code 分享 pow quic mage src .com image Codevs1281: 給你6個數,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn 計算遞推式,運用矩陣來進行計算加速 然後註意用類似快速冪的
機器學習之數學系列(一)矩陣與矩陣乘法
1.對於矩陣的認識應當把它看成是多個向量的排列表或把矩陣看成行向量,該行向量中的每個元素都是一個列向量,即矩陣是複合行向量。如下圖所示。 2.對於下面這個矩陣的乘法有兩種看法: (1)矩陣將向量[b1,b2,b3].T進行了運動變換,這種變換可以是同空間內變換,也可以是不同空間間的變換;
【upc 9541 矩陣乘法】非正解
深度學習演算法很大程度上基於矩陣運算。例如神經網路中的全連線本質上是一個矩陣乘法,而卷積運算也通常是用矩陣乘法來實現的。有一些科研工作者為了讓神經網路的計算更快捷,提出了二值化網路的方法,就是將網路權重壓縮成只用兩種值表示的形式,這樣就可以用一些 trick 加速計算了。例如兩個二進位制向量點乘
神經網路高效能運算 卷積計算優化 openblas GEMM 矩陣乘法優化 ncnn mobileNet-ssd shueezeNet-ssd
HighPerformanceComputing 高效能運算(High performance computing, 縮寫HPC) 指通常使用很多處理器(作為單個機器的一部分) 或者某一叢集中組織的幾臺計算機(作為單個計 算資源操作)的計算系統和環境。 有許多型別的HP
動態規劃之矩陣鏈乘法
對於給定的n個矩陣形成的矩陣鏈M1,M2,M3,......Mn,求計算乘積M1M2M3.....Mn時進行最少次標量相乘的運算順序,這類問題就稱為矩陣鏈乘法問題。 例: 當給定矩陣Mi的維數後,求出計算n個矩陣的乘積M1M2M3....Mn時所需標量相乘運
AI學習之路(19)TensorFlow裡的矩陣乘法
如果對矩陣的知識有點遺忘,有點陌生,有點想不起來,請先看看這個網頁:基礎知識已經補過了,就直接來使用TF的矩陣乘法了。tf.matmul(a, b, transpose_a=False, transpose_b=False, adjoint_a=False, adjoint_b
CUDA程式設計--實現並行矩陣乘法【80行程式碼】
簡述 這裡只寫了方陣之間的乘法,但是本質上都是一樣的。 我測試過100規模的方陣之間的乘法,沒有問題。 程式碼 讀取檔案data.txt 資料格式就是一個數值N,然後來連續的兩個N*N的矩陣。用空格隔開。 #include "cuda