【MPI编程】任意节点数的蝶形求和(高性能计算)

4 篇文章 0 订阅

简述

对于任意情况下的蝶形求和,本质上和任意的树形求和是一样的。只需要做逻辑上的抽象,假设那些点存在补全就好了,然后再加一个限定条件就ok了

代码

#include<stdio.h>
#include<string.h>
#include<mpi.h>
#pragma warning(disable : 4996)
#define MAX_STRING 100
using namespace std;
#include <fstream>
#include <iostream>

int main(void) {
	int len;
	double scalar, local_sum = 0;
	int comm_sz;
	int my_rank;
	int divided_len;
	int last_divided;
	int begin_i;
	int oper_N = 2;
	MPI_Init(NULL, NULL);
	MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	
	
	// 只有一个线程的时候不操作
	if (comm_sz <= 1) {
		MPI_Finalize();
		return 0;
	}
	ifstream cin("D:\\C++\\VS\\repo\\MPI-DEMO\\MPI-DEMO\\input.txt");
	cin >> len; // 输入数据长度

	divided_len = len / comm_sz;
	last_divided = len % comm_sz;

	if (my_rank < last_divided) {
		divided_len++;
		begin_i = my_rank * divided_len;
	}
	else {
		begin_i = (my_rank - last_divided) * divided_len + ((divided_len + 1)* last_divided);
	}
	// 局部和
	for (int i = 0; i < len; ++i) {
		cin >> scalar;
		if (i < begin_i || i >= begin_i + divided_len) continue;
		else {
			local_sum += scalar;
		}
	}
	// 假设comm_sz不一定是2的幂
	// 蝶形求和
	while (oper_N <= comm_sz || (oper_N > comm_sz && oper_N / 2 < comm_sz)) {
		// 往前发
		if (my_rank % oper_N < oper_N / 2) {
			if (my_rank + oper_N / 2 < comm_sz){
				MPI_Send(&local_sum, 1, MPI_DOUBLE, my_rank + oper_N / 2, 0, MPI_COMM_WORLD);
				MPI_Recv(&scalar, 1, MPI_DOUBLE, my_rank + oper_N / 2, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
				local_sum += scalar;
			}
		}// 往后发
		else if (my_rank % oper_N >= oper_N / 2) {
			MPI_Send(&local_sum, 1, MPI_DOUBLE, my_rank - oper_N / 2, 0, MPI_COMM_WORLD);
			MPI_Recv(&scalar, 1, MPI_DOUBLE, my_rank - oper_N / 2, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
			local_sum += scalar;
		}
		oper_N *= 2;
	}
	if (my_rank == 0) {
		cout << local_sum << endl;
	}
	MPI_Finalize();

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

肥宅_Sean

公众号“肥宅Sean”欢迎关注

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

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

打赏作者

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

抵扣说明:

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

余额充值