Добавил:
Upload
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:магПП2013 / gauss_omp
.c/* 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