본문 바로가기
Parallel Programming

KSC 2015 1번 문제 및 답안

by suminhan 2016. 10. 1.

sequential.c

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

double genvv(double x){
	return (x*x+pow(x,4)+pow(x,6)+exp(-x*x)+cos(x)+sin(x)+tan(x));
}

int main(int argc, char **argv){
	int i,n1,n2,j,jsta,jend;
	int iter,niter;
	double xi,xf,dx;
	double tmr;
	double *ar, *br;
	/* Do not change */
	n1 = 0;
	n2 = 100000000;
	niter = 3;
	/* Do not change */

	ar = (double*) malloc(sizeof(double)*n2);
	br = (double*) malloc(sizeof(double)*n2);

	jsta = n1; 
	jend = n2;
	jsta = n1+1;
	jend = n2-1;
	xi = 0.L;
	xf = 1.L;
	dx = (xf-xi)/(double)(n2-n1-1);
	for(i=n1;i<n2;i++){
		br[i] = xi+(double)(i-n1)*dx;
		ar[i] = 0.0;
	}

	for(iter=0;iter<niter;iter++){
		for(j=jsta;j<jend;j++){
			/* Do not change */
			ar[j] = (br[j-1]+br[j+1])/4.L+br[j]/2.L+1.L/genvv(br[j]);
			/* Do not change */
		}
		for(i=n1;i<n2;i++){
			/* Do not change */
			br[i] = ar[i];
			/* Do not change */
		}
	}
	tmr = 0.L;
	for(j=jsta;j<jend;j++){
		tmr += ar[j];
	}
	printf("tmr = %16.7f\n",tmr);
	
	free(ar);
	free(br);
	return 0;

}

parallel.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "mpi.h"

#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)>(b)?(b):(a))

#define TRUE 1
#define FALSE 0


void para_range(int n1,int n2,int nid,int myid,int *ista,int *iend){
	int iwork1, iwork2;
	iwork1 = (n2-n1)/nid;
	iwork2 = (n2-n1)%nid;
	*ista = myid*iwork1 + n1 + MIN(myid,iwork2);
	*iend = *ista + iwork1;
	if(iwork2 > myid) (*iend) ++;
}

double genvv(double x)
{
	double res = x*x + pow(x,4)+ pow(x,6)+exp(-x*x)+cos(x)+sin(x)+tan(x);
	return res;

}

int main (int argc, char **argv)
{
	int i,n1,n2,j,jsta,jend;
	int iter,niter;
	MPI_Status istatus;
	int ierr, myid,nid;
	int iprev, inext, ista, iend;
	MPI_Request isd1,isd2,irv1,irv2;
	int itag, iroot;
	double xi,xf,dx;
	double tmr;
	double *ar, *br;
	double ptmr, tic,toc;

	/* do not change ------ */
	n1 = 0;
	n2 = 100000000;
	niter = 3;
	/* do not change ------ */

	ar = (double*) malloc(n2*sizeof(double));
	br = (double*) malloc(n2*sizeof(double));
	
	xi = 0.L;
	xf = 1.;
	dx = (xf-xi)/(double)(n2-n1-1);

	for(i=n1;i<n2;i++){
		br[i] = xi+(double)(i-n1)*dx;
	}

	MPI_Init(&argc, &argv);
	tic = MPI_Wtime();
	MPI_Comm_size(MPI_COMM_WORLD, &nid);
	MPI_Comm_rank(MPI_COMM_WORLD, &myid);

	para_range(n1,n2,nid,myid,&ista,&iend);
	printf("rank:%10d ista=%15d iend=%15d\n", myid, ista, iend);

	jsta = ista;
	jend = iend;
	if(myid==0) jsta = n1+1;
	if(myid == nid-1) jend = n2-1;

	inext = myid + 1;
	iprev = myid - 1;
	if(myid == nid-1) inext = MPI_PROC_NULL;
	if(myid == 0) iprev = MPI_PROC_NULL;
	for(i=ista;i<iend;i++){
		br[i] = xi+ (double)(i-n1)*dx;
	}

	for(iter=0;iter<niter;iter++){
		itag = 101;
		MPI_Isend(br+iend-1,   1, MPI_DOUBLE, inext, itag, MPI_COMM_WORLD, &isd1);
		MPI_Isend(br+ista,   1, MPI_DOUBLE, iprev, itag, MPI_COMM_WORLD, &isd2);
		MPI_Irecv(br+ista-1,   1, MPI_DOUBLE, iprev, itag, MPI_COMM_WORLD, &irv1);
		MPI_Irecv(br+iend,   1, MPI_DOUBLE, inext, itag, MPI_COMM_WORLD, &irv2);
		MPI_Wait(&isd1,&istatus);
		MPI_Wait(&isd2,&istatus);
		MPI_Wait(&irv1,&istatus);
		MPI_Wait(&irv2,&istatus);

		for(j=jsta;j<jend;j++){
			/*  not change -----{ */
			ar[j] = (br[j-1]+br[j+1])/4.L + br[j]/2.L + 1.L/genvv(br[j]);
			/*  not change -----} */
		}
		for(i=ista;i<iend;i++){
			/*  not change -----{ */
			br[i] = ar[i];
			/*  not change -----} */
		}

	}
	ptmr = 0.L;
	for(j=jsta;j<jend;j++){
		ptmr += ar[j];
	}
	iroot = 0;
	MPI_Reduce(&ptmr, &tmr, 1, MPI_DOUBLE, MPI_SUM, iroot, MPI_COMM_WORLD);
	if(myid==0) printf("tmr = %16.6f\n",tmr);
	toc = MPI_Wtime();
	if(myid==0) printf("%g sec\n",toc-tic);

	free(ar);
	free(br); 

	MPI_Finalize();

}

myparallel.c
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<mpi.h>


double genvv(double x){
	return (x*x+pow(x,4)+pow(x,6)+exp(-x*x)+cos(x)+sin(x)+tan(x));
}

int main(int argc, char **argv){

	int i,n1,n2,j,jsta,jend;
	int iter,niter;
	double xi,xf,dx;
	double tmr;
	double *ar, *br;
	/* Do not change */
	n1 = 0;
	n2 = 100000000;
	niter = 3;
	/* Do not change */

	int nprocs, myrank, q, r, asize, xspos;
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
	q = (n2-n1)/nprocs;
	r = (n2-n1)%nprocs;
	asize = myrank<r?(q+1):q;
	xspos = (myrank<r?(q+1)*myrank:(q*myrank+r)) + n1;

	ar = (double*) malloc(sizeof(double)*(asize+2));
	br = (double*) malloc(sizeof(double)*(asize+2));

	jsta = 0;
	jend = jsta + asize;
	if(myrank == 0) jsta = jsta+1;
	if(myrank == nprocs-1) jend = jend-1;
	xi = 0.L;
	xf = 1.L;
	dx = (xf-xi)/(double)(n2-n1-1);
	for(i=0;i<asize;i++){
		br[i+1] = xi+(double)(i-n1+xspos)*dx;
		ar[i+1] = 0.0;
	}

	MPI_Request req[4];
	MPI_Status stat[4];
	for(iter=0;iter<niter;iter++){
		if(myrank < nprocs-1){
			MPI_Isend(&br[asize], 1, MPI_DOUBLE, myrank+1, 123, MPI_COMM_WORLD, &req[0]);
			MPI_Irecv(&br[asize+1], 1, MPI_DOUBLE, myrank+1, 321, MPI_COMM_WORLD, &req[1]);
		}
		if(myrank > 0){
			MPI_Isend(&br[1], 1, MPI_DOUBLE, myrank-1, 321, MPI_COMM_WORLD, &req[2]);
			MPI_Irecv(&br[0], 1, MPI_DOUBLE, myrank-1, 123, MPI_COMM_WORLD, &req[3]);
		}
		if(myrank < nprocs-1){
			MPI_Waitall(2, req, stat);
		}
		if (myrank > 0){
			MPI_Waitall(2, req+2, stat+2);
		}
		for(j=jsta+1;j<jend+1;j++){
			/* Do not change */
			ar[j] = (br[j-1]+br[j+1])/4.L+br[j]/2.L+1.L/genvv(br[j]);
			/* Do not change */
		}
		for(i=1;i<asize+1;i++){
			/* Do not change */
			br[i] = ar[i];
			/* Do not change */
		}
	}
	tmr = 0.L;
	int cnt = 0;
	for(j=jsta+1;j<jend+1;j++){
		tmr += ar[j];
		cnt++;
	}
	double tot;
	MPI_Reduce(&tmr, &tot, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
	if(!myrank)
		printf("tmr = %16.7f\n",tot);
	
	free(ar);
	free(br);

	MPI_Finalize();
	return 0;

}


'Parallel Programming' 카테고리의 다른 글

KSC 2015 3번 문제 및 풀이  (0) 2016.10.01
KSC 2015 2번 문제 및 답안  (0) 2016.10.01
KSC 2014 3번 문제 및 답안  (0) 2016.10.01
KSC 2014 2번 문제 및 답안  (0) 2016.10.01
KSC 2014 1번 문제 및 답안  (0) 2016.10.01

댓글