想法:想在找到最大元后,开启并发多个线程(机器)一起消去下面的行(变成上三角行列式)
结果运行调用,从main那里调用,并不是局部调用、、、
残缺的代码:
#include "stdio.h"
#include "math.h"
#include "mpi.h"
#include "stdlib.h"
float *gauss(float *arr, int row, int col);
float *solution(float *arr, int row, int col, int argc, char *argv[]);
float *backProgram(float *arr, int row, int col);
float *elimination(float *arr, int row, int col, int i, int argc, char *argv[]);
int SelectIndex(float *arr, int row, int col, int i);
float *swapRow(float *arr, int row, int col, int i, int j);
void printArr(float *arr)
{
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 5; j++)
{
printf("%f ", arr[i * 5 + j]);
}
printf("\n");
}
}
// 高斯消元函数
float *gauss(float *arr, int row, int col)
{
//float *result = solution(arr, row, col);
// return result;
}
// row 为行数, col为列数,
float *solution(float *arr, int row, int col, int argc, char *argv[])
{
for(int i = 0; i < row; i++)
{
// printf("变化前来一下\n");
// printArr(arr);
int maxRow = SelectIndex(arr, row, col, i);
if(maxRow != i)
{
swapRow(arr, row, col, i, maxRow);
}
float divNum = arr[i * col + i];
for(int k = i; k < col; k++)
{
arr[i * col + k] /= divNum;
}
// printf("变化后来一下\n");
// printArr(arr);
arr = elimination(arr, row, col, i, argc, argv); // 这里是消去下面的行,我在这里弄一下并发执行
}
backProgram(arr, row, col);
return arr;
}
// 回代、求值
float *backProgram(float *arr, int row, int col)
{
for(int i = row - 1; i>= 0; i--)
{
for(int j = i - 1; j >= 0; j--)
{
arr[j * col + col - 1] -= arr[j * col + i] * arr[i * col + col - 1];
arr[j * col + i] = 0;
}
}
return arr;
}
//消去当前行下面的所有元素
float *elimination(float *arr, int row, int col, int i, int argc, char *argv[])
{
// 在这里尝试添加 并发语句
int numprocess;
int myid;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &numprocess);
if(myid == 0) // 0号当做是调度者的身份,让其他的线程(机器)去执行
{
printf("你们去执行吧,我把任务交给你们\n");
// float *arrTmp;
float *arrTmp = (float *)malloc(sizeof(float) * col * row); // 临时数组用于存储 回传的信息
for(int i = 1; i < col - i - 1; i++)
{
printf("我将发送数据到%d --> %d线程\n", myid, i);
printArr(arr);
// 把所有的数据都发送过去, 让他们去处理
MPI_Send(&arr, row * col, MPI_FLOAT, i, 80, MPI_COMM_WORLD);
}
// 线程循环,
for(int kk = 1; kk < row - i + 1; kk++)
{
printf("我从 %d线程接收数据,我是%d\n", kk, myid);
MPI_Recv(&arrTmp, row * col, MPI_FLOAT, kk, 80, MPI_COMM_WORLD, &status);
printf("我是线程%d, 我从%d 接收到的数据是:\n", myid, kk);
printArr(arrTmp);
// 把 列元素更新
for(int k = i; k < col; k++)
{
arr[row - kk + 1 + k] = arrTmp[row - kk + 1 + k];
}
}
printf("结束了,能走到这一步吗?\n");
}
else
{
// float *recArr;
float *recArr =(float *)malloc(sizeof(float) * row * col); // 用于接收的数组,在这个数组里面修改,然后回传
printf("我的id:%d,我要开始接收数据了\n", myid);
MPI_Recv(&recArr, row * col, MPI_FLOAT, 0, 80, MPI_COMM_WORLD, &status);
printf("我线程%d, 接收到的数据是:\n", myid);
printArr(recArr);
float subNum;
int k = row - myid + 1;
subNum = recArr[k * col + i];
for(int kk = i; kk < col; kk++) // 这一行中 列的处理
{
recArr[k * col + kk] -= (recArr[i * col + kk] * subNum);
}
printf("数据处理完毕,我是线程%d, 返还数据回去\n", myid);
printArr(recArr);
MPI_Send(&recArr, row * col, MPI_FLOAT, 0, 80, MPI_COMM_WORLD);
}
return arr;
}
// 求最大行
int SelectIndex(float *arr, int row, int col, int i)
{
int index = 0;
float max = 0;
for(int k = i * col + i; k < row * col; k += col)
{
if(fabs(max) < fabs(arr[k]))
{
max = arr[k];
index = k;
}
}
return index / col;
}
// 两行交换
float *swapRow(float *arr, int row, int col, int i, int j)
{
float tmp;
for(int k = 0; k < col; k++)
{
tmp = arr[i * col + k];
arr[i * col + k] = arr[j * col + k];
arr[j * col + k] = tmp;
}
return arr;
}
// 主函数
int main(int argc, char *argv[])
{
float arr[] = {2, 3, 11, 5, 2,
1, 1, 5, 2, 1,
2, 1, 3, 2, -3,
1, 1, 3, 3, -3};
printf("高斯消元之前:\n");
printArr(arr);
float *a = solution(arr, 4, 5, argc, argv);
printf("\n高斯消元求解后:\n");
printArr(arr);
return 0;
}
GG: