资源简介
经典的cannon算法,主要用于矩阵相乘的并行求解问题。这个实现简单易懂,里面有详细注释。
代码片段和文件信息
#include
#include
#include
#include
#include
#include
/* 全局变量声明 */
float **A **B **C; /* 总矩阵C = A * B */
float *a *b *c *tmp_a *tmp_b; /* a、b、c表分块,tmp_a、tmp_b表缓冲区 */
int dg dl dl2p sp; /* dg:总矩阵维数;dl:矩阵块维数;dl2=dl*dl;p:处理器个数;sp=sqrt(p) */
int my_rank my_row my_col; /* my_rank:处理器ID;(my_rowmy_col):处理器逻辑阵列坐标 */
MPI_Status status;
/*
*函数名: get_index
*功能:处理器逻辑阵列坐标至rank号的转换
*输入:坐标、逻辑阵列维数
*输出:rank号
*/
int get_index(int row int col int sp)
{
return ((row+sp)%sp)*sp + (col+sp)%sp;
}
/*
*函数名:random_A_B
*功能:随机生成矩阵A和B
*/
void random_A_B()
{
int ij;
srand((unsigned int)time(NULL)); /*设随机数种子*/
/*随机生成AB并初始化C*/
for(i=0; i for(j=0; j {
A[i][j] = rand();
B[i][j] = rand();
C[i][j] = 0.0;
}
}
/* 函数名:scatter_A_B
* 功能:rank为0的处理器向其他处理器发送A、B矩阵的相关块
*/
void scatter_A_B()
{
int ijkl;
int p_iminp_imaxp_jminp_jmax;
for(k=0; k
{
/*计算相应处理器所分得的矩阵块在总矩阵中的坐标范围*/
p_jmin = (k % sp ) * dl;
p_jmax = (k % sp + 1) * dl-1;
p_imin = (k - (k % sp))/sp * dl;
p_imax = ((k - (k % sp))/sp +1) *dl -1;
l = 0;
/*rank=0的处理器将AB中的相应块拷至tmp_atmp_b,准备向其他处理器发送*/
for(i=p_imin; i<=p_imax; i++)
{
for(j=p_jmin; j<=p_jmax; j++)
{
tmp_a[l] = A[i][j];
tmp_b[l] = B[i][j];
l++;
}
}
/*rank=0的处理器直接将自己对应的矩阵块从tmp_atmp_b拷至ab*/
if(k==0)
{
memcpy(a tmp_a dl2 * sizeof(float));
memcpy(b tmp_b dl2 * sizeof(float));
} else /*rank=0的处理器向其他处理器发送tmp_atmp_b中相关的矩阵块*/
{
MPI_Send(tmp_a dl2 MPI_FLOAT k 1 MPI_COMM_WORLD);
MPI_Send(tmp_b dl2 MPI_FLOAT k 2 MPI_COMM_WORLD);
}
}
}
/*
*函数名:init_alignment
*功能:矩阵A和B初始对准
*/
void init_alignment()
{
/*将A中坐标为(ij)的分块A(ij)向左循环移动i步*/
MPI_Sendrecv(a dl2 MPI_FLOAT get_index(my_rowmy_col-my_rowsp) 1
tmp_a dl2 MPI_FLOAT get_index(my_rowmy_col+my_rowsp) 1 MPI_COMM_WORLD &status);
memcpy(a tmp_a dl2 * sizeof(float) );
/*将B中坐标为(ij)的分块B(ij)向上循环移动j步*/
MPI_Sendrecv(b dl2 MPI_FLOAT get_index(my_row-my_colmy_colsp) 1
tmp_b dl2 MPI_FLOAT get_index(my_row+my_colmy_colsp) 1 MPI_COMM_WORLD &status);
memcpy(b tmp_b dl2 * sizeof(float) );
}
/*
*函数名:main_shift
*功能:分块矩阵左移和上移,并计算分块c
*/
void main_shift()
{
int ijkl;
for(l=0; l {
/*矩阵块相乘,c+=a*b */
for(i=0; i
for(j=0; j
for(k=0; k
c[i*dl+j] += a[i*dl+k]*b[k*dl+j];
/* 将分块a左移1位 */
MPI_Send(a dl2 MPI_FLOAT get_index(my_row my_col-1 sp) 1 MPI_COMM_WORLD);
MPI_Recv(a dl2 MPI_FLOAT get_index(my_row my_col+1 sp) 1 MPI_COMM_WORLD &status);
- 上一篇:北京2013-2018年期间空气质量历史数据
- 下一篇:数据结构二叉树家谱管理系统
相关资源
- SVR算法程序可运行
- 计算机图形学 边填充算法实现代码
- 福建师范大学历年算法考卷
- 栈的实现及应用,六种基本算法
- Bresenham算法绘制线段并利用“橡皮筋
- 介绍几种压缩算法及《笨笨数据压缩
- 改进的BP神经网络算法
- A星算法_原理讲解_例子
- 云模型的相关算法cloud
- 旋转矩阵求欧拉角的简单算法
- 栅栏填充算法源码(VC)
- RSA算法源码
- 关联分析Apriori算法实现
- [免费]relax算法成像
- 操作系统 LRU算法 实验报告 及 程序代
- 分治法快速排序算法QuickSort C
- 现代谱估计算法 music ESPRIT 谐波分解
- MUSIC算法c 实现
- 007出纳管理系统 v7[1].5.94 算法注册机
- 克鲁斯卡尔算法C和C 实现代码
- capon波束形成算法-VC实现
- QGA 量子遗传算法
- 利用OpenGL写毛笔字算法
- 带头结点的单链表的c算法实现
- 自适应隐写算法wow
- 协同过滤算法源码
- RSA AES DES ECC加密算法源码
- 密码学课程设计:DES加密解密算法的
- 北航人工智能原理课大作业源代码,
- A*算法的2D演示(带源码)
评论
共有 条评论