利用MIC做矩阵运算

本文用作学习笔记,仅做参考。
代码实现D=A*B+C的矩阵运算,A与B分别为n*m与m*n矩阵.
具体如下(本代码所用语言为C++):

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <offload.h>

//定义矩阵A的行数(N)与列数(M)
#define N 5
#define M 5

//检测是否在mic上运行
	__attribute__((target (mic)))
void offload_check(void)
{
	#ifdef __MIC__
	printf("check func:Run on the mic!\n");
	#else
	printf("check func;Run on the cpu!\n");
	#endif
}

//矩阵加法
	__attribute__((target (mic)))
void MatAdd(float** A,float** B,float** C,int n,int m)
{
	offload_check();
	#pragma omp parallel //num_threads(set_omp_num_threads)
	{
		#pragma omp for 
		for (int i=0;i<n;i++)
			{
				for (int j=0;j<m;j++)
				C[i][j]=A[i][j]+B[i][j];
			}
	}
}

//矩阵乘法
	__attribute__((target (mic)))
void MatMulti(float** A,float** B,float** C,int n,int m)
{
	offload_check();
	#pragma omp parallel //num_threads(set_omp_num_threads)
	{
		#pragma omp for 
		for (int i=0;i<n;i++)
		{
			for (int j=0;j<n;j++){
				C[i][j]=0.0;
				for (int k=0;k<m;k++)
				{
					C[i][j] += A[i][k] * B[k][j];    
				}
			}
		}
	}
}
int main( int argc,char** argv)
{
	int i,j;
	float *in1;
	float **A,**B,**C,**D,**E,**F; 
	//分配内存
	A=(float**)malloc(sizeof(float*)*N);  
	for(int i=0;i<N;i++)  
	A[i]=(float*)malloc(sizeof(float)*M); 
	B=(float**)malloc(sizeof(float*)*M);  
	for(int i=0;i<M;i++)  
	B[i]=(float*)malloc(sizeof(float)*N); 
	C=(float**)malloc(sizeof(float*)*N);  
	for(int i=0;i<N;i++)  
	C[i]=(float*)malloc(sizeof(float)*N); 
	D=(float**)malloc(sizeof(float*)*N);  
	for(int i=0;i<N;i++)  
	D[i]=(float*)malloc(sizeof(float)*N); 
	E=(float**)malloc(sizeof(float*)*N);  
	for(int i=0;i<N;i++)  
	E[i]=(float*)malloc(sizeof(float)*N); 
	F=(float**)malloc(sizeof(float*)*N);  
	for(int i=0;i<N;i++)  
	F[i]=(float*)malloc(sizeof(float)*N); 
	
	//对A,B,C矩阵进行初始化
	for (int i=0;i<N;i++)
	{
		for (int j=0;j<M;j++)
		{
			A[i][j]=i+1;
			B[j][i]=i+2;
		}
	}  
	for (int i=0;i<N;i++)
		{
		for (int j=0;j<N;j++)
		{
			C[i][j]=i+3;
		}
	} 
	
	#pragma offload target(mic:0) in(A:length(N)) in(B:length(M)) inout(E:length(N)) signal(in1)
	{
	MatMulti(A,B,E,N,M);
	}
	
	for (int i=0;i<N;i++)
	{
		for (int j=0;j<N;j++)
		F[i][j]=E[i][j];
	}
	
	
	#pragma offload target(mic:0) in(F,C:length(N)) out(D:length(N)) signal(in1) 
	{
	MatAdd(F,C,D,N,N);
	}
	
	//check the result
	for (int i=0;i<N;i++)
	{
		for (int j=0;j<N;j++)
		printf("%d,%d,%f\n",i,j,D[i][j]);
	}
	//释放内存
	free(A);
	free(B);
	free(C);
	free(D);
	free(E);
	free(F);
}

代码尚待完善,目前发现的不足如下:

  • 尚未知晓#pragma语句中signal传参的作用为何,只是若是不加signal参数,调试时会出现:

    ```cpp offload error :process on the device 0 was terminated by signal 11 ```	 
    

    代码改来改去不得其法,没办法只好暂时这般勉强处理。

  • 本代码实现的是D=A*B+C矩阵运算,运算方式是:E=A*B,F=E,D=F+C,E,F作为辅助矩阵,实际上占用了大量无用的内存。
    如果说E是作为加法与乘法的函数转换的中间量有其存在的意义的话,F就完全是没有大的存在必要的,可以去掉。
    至于中间量E,实际上也是可以去除的:实际上可以将加法与乘法合并到一个函数中进行。

  • 矩阵是在程序中事先初始化的,结果暂时就通过printf打印,欲使代码实际可用,还需根据实际情况进行修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

today__present

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值