Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

магПП2013 / gauss_omp

.c
Скачиваний:
12
Добавлен:
19.04.2015
Размер:
3.61 Кб
Скачать
/* GAUSS_OMP */

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include "omp.h"

void wtime(double *t)// заменить функцией omp
{
  static int sec = -1;
  struct timeval tv;
  gettimeofday(&tv, (void *)0);
  if (sec < 0) sec = tv.tv_sec;
  *t = (tv.tv_sec - sec) + 1.0e-6*tv.tv_usec;
}


int TRACE=0;

void init(double *a,double *b,double *x,int n);
void gauss(double *a,double *b,double *x,int n);
void prt1a(char *t1, double *v, int n,char *t2) ;

int N;
double *A;
#define A(i,j) A[(i)*N+(j)]
double *B;
double *X;

int main(int argc,char **argv){
	double time0, time1;
	FILE *in;// здесь и далее заменить на потоковый io
	int i;
	in=fopen("data.in","r");
	if(in==NULL) {
		printf("Can not open 'data.in' "); exit(1);
	}

	i=fscanf(in,"%d %d", &N, &TRACE);
	if(i<1) {
		printf("Wrong 'data.in' (N ...)"); exit(2);
	}
	A=(double *)malloc(N*N*sizeof(double));
	B=(double *)malloc(N*sizeof(double));
	X=(double *)malloc(N*sizeof(double));

	printf("GAUSS %dx%d  <",N,N);
	init(A,B,X,N);
	wtime(&time0);
	/*time0=omp_get_wtime ();*/
	gauss(A,B,X,N);
	wtime(&time1);
	/*time1=omp_get_wtime ();*/
	printf("Time in seconds=%gs\t",time1-time0);
	prt1a("X=(", X,N>10?10:N,"...)\n");

	free(A);
	free(B);
	free(X);
	return 0;
}

void init(double *a, double *b, double *x, int n)
{
#define a(i,j) a[(i)*n+(j)]
int i,j;
#pragma omp parallel for shared (a,n) private(i,j)
	for(i=0;i<=n-1;i++){
		for(j=0;j<=n-1;j++) {
			a(i,j) = (i==j)? 0.01 /*2.*/ : 1.0/(i+(n-j)+1.0);
		}
	}
#pragma omp parallel for shared (a,b,n) private(i,j)
	for(j=0;j<=n-1;j++){ 
		b[j]=0.;
		for(i=0;i<=n-1;i++){
			b[j]=b[j]+a(j,i)* (i%3+1); /* for X be {1,2,3,1,2,3,...} */
		}
	}
	return;
}

void gauss(double *a, double *b, double *x, int n) {
#define a(i,j) a[(i)*n+(j)]
int i,j,k;
int ip;
double p;
double tmp;
double *localp;
int *localip;
int num_threads;
num_threads=omp_get_max_threads();
localp=(double *)malloc(num_threads*sizeof(double));
localip=(int *)malloc(num_threads*sizeof(int));
	/*Gaussian elimination*/
	for(i=0;i<=n-1;i++) {
		/*Finding the pivot element*/
		#pragma omp parallel shared(a,n,i,localip,localp)
		{
			int thread_num = omp_get_thread_num (); 			
			localip[thread_num]=0;
			localp[thread_num]=0.;
			#pragma omp for private (j)
			for(j=i+1;j<=n-1;j++) {
				if(fabs(a(j,i))>localp[thread_num]) {
					localp[thread_num]=fabs(a(j,i));
					localip[thread_num]=j;
				}
			}
		}
		ip=i;
		p=fabs(a(i,i));
		for(j=0;j<num_threads;j++) {
			if (localp[j]>p) {
			    p=localp[j];
			    ip=localip[j];				
			}	
		}
		if(TRACE && i%TRACE==0) printf("\nip=%d p=%.4g\t", ip, p);
		#pragma omp parallel for private(j,k) shared(a,n,i,ip)
		for(j=i;j<=n-1;j++) {
			for(k=i+1;k<=n-1;k++) {
				if(j!=ip) a(j,k) -= a(ip,k)*a(j,i)/a(ip,i);
			}
		}
		#pragma omp parallel for private(j) shared(a,b,n,i,ip)
		for(j=i;j<=n-1;j++) {
			if(j!=ip) b[j] -= b[ip]*a(j,i)/a(ip,i);
		}
		if(ip!=i) {
			#pragma omp parallel for shared(a,n,i,ip) private(k,tmp)
			for(k=i;k<=n-1;k++) {
				tmp=a(ip,k); a(ip,k)=a(i,k); a(i,k)=tmp;
			}
			tmp=b[ip]; b[ip]=b[i]; b[i]=tmp;
		}
	}
	/*Back Substitution*/
	for(i=n-1;i>=0;i--) {
		x[i]=b[i] /a(i,i);
		#pragma omp parallel for private(j) shared(a,b,x,n,i)
		for(j=0;j<=i-1;j++){
			b[j] = b[j] - x[i]*a(j,i);
		}
	}
	return;
}

void prt1a(char * t1, double *v, int n,char *t2){
	int j;	
	printf("%s",t1);
	for(j=0;j<n;j++)
	    printf("%.4g%s",v[j], j%8==7? "\n": ", ");
	printf("%s",t2);
}
Соседние файлы в папке магПП2013