MPI-1-MPI_Scatter/Gather:并行处理文本

欲仙欲死的MPI作业题

简而言之,就是让你读取txt文件(内容如下:)

16
0.36
0.89
0.59
0.81
0.81
0.87
0.63
0.40
0.58
0.59
0.91
0.53
0.35
0.45
0.33
0.16

其中,第一行是向量的长度/位数(length of the vector),后面的16个则是具体的条目(entries of the vector)。

第一个要求:

仅用编号(rank)为0的处理器进行读取文件的处理;

第二个要求:

将16个entries按照处理器个数(默认为4个)平均分配给各个处理器进行处理,也就是每个处理器仅处理4个entries,同时,每个处理器分配相应大小(4个entries)的内存;

第三个要求:

每个处理器上entries的量分别加上1.0(比如,处理器1的entries为1、2、3、4,那么在此步骤之后变为2、3、4、5);

第四个要求:

将每个处理器上分配的、加上1.0过后的entries传回处理器0(rank=0的处理器),并且按照和txt同样的格式输出新的txt文件。

 

虽然并不算是很难的问题,但是考虑到学习MPI的时间不长,对于我来说还是比较麻烦的。

那么废话不多说,show you my code:

#include 
#include 
#include 
#include 


typedef struct
{
	int size;
	double* entry;
}
vector;

// alloc_vec
vector alloc_vec(vector vec)
{
	vec.entry=(double*)malloc(sizeof(double)*vec.size);
	return vec;
}

//free_vec
vector free_vec(vector vec)
{
	free(vec.entry);
	return vec;
}





//main
int main(int argc, char **argv)
{
	int rank, numprocs;
	char file[1000] = {0};
	char *filename="vec16.txt";
	int i=0;
	vector vec;


	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);

// Exercises 1.1	
	if(rank == 0)
	{
		FILE *fp = fopen(filename, "r");

	//give the value of length of the vector from the first line to vec.size
		while(!feof(fp))
		{
			fgets(file, 10, fp);
			//printf("file=%s",file);
			vec.size=atoi(file);
			break;
		}
	// alloc_vec
		vec=alloc_vec(vec);

	//give the value of the remaining line/lines to vec.entry
		while(!feof(fp))
		{
			memset(file, 0, sizeof(file));

			// include the line break symbol
			fgets(file, sizeof(file) - 1, fp); 

			if(i>1);
			{		
				vec.entry[i]=atof(file);
				i++;
			}
		}
		fclose(fp);

	//test the vec	
		printf("Ex1.1: I'm rank %d of %d\n",rank, numprocs);
		printf("Ex1.1: vec.size=%d\n",vec.size);

		for(i=0;i

输出结果:

liu@ubuntu:~/5611/1$ mpirun -np 4 ./test
Ex1.1: I'm rank 0 of 4
Ex1.1: vec.size=16
Ex1.1: vec.entry[0]=0.360000
Ex1.1: vec.entry[1]=0.890000
Ex1.1: vec.entry[2]=0.590000
Ex1.1: vec.entry[3]=0.810000
Ex1.1: vec.entry[4]=0.810000
Ex1.1: vec.entry[5]=0.870000
Ex1.1: vec.entry[6]=0.630000
Ex1.1: vec.entry[7]=0.400000
Ex1.1: vec.entry[8]=0.580000
Ex1.1: vec.entry[9]=0.590000
Ex1.1: vec.entry[10]=0.910000
Ex1.1: vec.entry[11]=0.530000
Ex1.1: vec.entry[12]=0.350000
Ex1.1: vec.entry[13]=0.450000
Ex1.1: vec.entry[14]=0.330000
Ex1.1: vec.entry[15]=0.160000

Ex1.2: Now is process 0: 
Ex1.2: v1_2.entry[0]=0.360000
Ex1.2: v1_2.entry[1]=0.890000
Ex1.2: v1_2.entry[2]=0.590000
Ex1.2: v1_2.entry[3]=0.810000

Ex1.3: Now is process 0: 
Ex1.3: v1_2.entry[0]=1.360000
Ex1.3: v1_2.entry[1]=1.890000
Ex1.3: v1_2.entry[2]=1.590000
Ex1.3: v1_2.entry[3]=1.810000

Ex1.2: Now is process 1: 
Ex1.2: v1_2.entry[0]=0.810000
Ex1.2: v1_2.entry[1]=0.870000
Ex1.2: v1_2.entry[2]=0.630000
Ex1.2: v1_2.entry[3]=0.400000

Ex1.3: Now is process 1: 
Ex1.3: v1_2.entry[0]=1.810000
Ex1.3: v1_2.entry[1]=1.870000
Ex1.3: v1_2.entry[2]=1.630000
Ex1.3: v1_2.entry[3]=1.400000

Ex1.2: Now is process 2: 
Ex1.2: v1_2.entry[0]=0.580000
Ex1.2: v1_2.entry[1]=0.590000
Ex1.2: v1_2.entry[2]=0.910000
Ex1.2: v1_2.entry[3]=0.530000

Ex1.3: Now is process 2: 
Ex1.3: v1_2.entry[0]=1.580000
Ex1.3: v1_2.entry[1]=1.590000
Ex1.3: v1_2.entry[2]=1.910000
Ex1.3: v1_2.entry[3]=1.530000

Ex1.2: Now is process 3: 
Ex1.2: v1_2.entry[0]=0.350000
Ex1.2: v1_2.entry[1]=0.450000
Ex1.2: v1_2.entry[2]=0.330000
Ex1.2: v1_2.entry[3]=0.160000

Ex1.3: Now is process 3: 
Ex1.3: v1_2.entry[0]=1.350000
Ex1.3: v1_2.entry[1]=1.450000
Ex1.3: v1_2.entry[2]=1.330000
Ex1.3: v1_2.entry[3]=1.160000

Ex1.4: I'm rank 0 of 4
Ex1.4: vec.size=16
Ex1.4: vec.entry[0]=1.360000
Ex1.4: vec.entry[1]=1.890000
Ex1.4: vec.entry[2]=1.590000
Ex1.4: vec.entry[3]=1.810000
Ex1.4: vec.entry[4]=1.810000
Ex1.4: vec.entry[5]=1.870000
Ex1.4: vec.entry[6]=1.630000
Ex1.4: vec.entry[7]=1.400000
Ex1.4: vec.entry[8]=1.580000
Ex1.4: vec.entry[9]=1.590000
Ex1.4: vec.entry[10]=1.910000
Ex1.4: vec.entry[11]=1.530000
Ex1.4: vec.entry[12]=1.350000
Ex1.4: vec.entry[13]=1.450000
Ex1.4: vec.entry[14]=1.330000
Ex1.4: vec.entry[15]=1.160000

值得注意的是,120行与125行的

	MPI_Barrier(MPI_COMM_WORLD);

// Exercises 1.4

	MPI_Gather(v1_2.entry, v1_2.size, MPI_DOUBLE, vec.entry, v1_2.size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	MPI_Barrier(MPI_COMM_WORLD);

某种程度上是为了输出结果的美观......

以及,注意147-148行的顺序:

	MPI_Finalize();
	return 0;

还有特别注意给vec与v1_2这两个变量分配内存、释放内存的位置,否则,会造成预料之外的影响(一定几率导致程序崩溃或者输出预料之外的值)

其他也没什么好说的,估计等日后学习进度更加深入以后会写一些关于MPI学习的建议之类的吧!

现在我只想静静,打打鬼10星.( ̄▽ ̄)"

你可能感兴趣的:(HPC,MPI)