예제 #1
0
파일: heat.c 프로젝트: sirspock/ppa
int main (int argc, char *argv[])
{
void inidat(), prtdat(), update();
int taskid,                     /* this task's unique id */
  numworkers,                 /* number of worker processes */
  numtasks,                   /* number of tasks */
  averow,rows,offset,extra,   /* for sending rows of data */
  dest, source,               /* to - from for message send-receive */
  left,right,        /* neighbor tasks */
  msgtype,                    /* for message types */
  rc,start,end,               /* misc */
  i,ix,iy,iz,it;              /* loop variables */

  inidat(NXPROB, NYPROB, u);
  prtdat(NXPROB, NYPROB, u, "initial.dat");
}
예제 #2
0
int main (int argc, char *argv[])
{
void inidat(), prtdat(), update();
float  u[2][NXPROB][NYPROB];        /* array for grid */
int	taskid,                     /* this task's unique id */
	numworkers,                 /* number of worker processes */
	numtasks,                   /* number of tasks */
	averow,rows,offset,extra,   /* for sending rows of data */
	dest, source,               /* to - from for message send-receive */
	left,right,        /* neighbor tasks */
	msgtype,                    /* for message types */
	rc,start,end,               /* misc */
	i,ix,iy,iz,it;              /* loop variables */
MPI_Status status;


/* First, find out my taskid and how many tasks are running */
   MPI_Init(&argc,&argv);
   MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
   MPI_Comm_rank(MPI_COMM_WORLD,&taskid);
   numworkers = numtasks-1;

   if (taskid == MASTER) {
      /************************* master code *******************************/
      /* Check if numworkers is within range - quit if not */
      if ((numworkers > MAXWORKER) || (numworkers < MINWORKER)) {
         printf("ERROR: the number of tasks must be between %d and %d.\n",
                 MINWORKER+1,MAXWORKER+1);
         printf("Quitting...\n");
         MPI_Abort(MPI_COMM_WORLD, rc);
         exit(1);
         }
      printf ("Starting mpi_heat2D with %d worker tasks.\n", numworkers);

      /* Initialize grid */
      printf("Grid size: X= %d  Y= %d  Time steps= %d\n",NXPROB,NYPROB,STEPS);
      printf("Initializing grid and writing initial.dat file...\n");
      inidat(NXPROB, NYPROB, u);
      prtdat(NXPROB, NYPROB, u, "initial.dat");

      /* Distribute work to workers.  Must first figure out how many rows to */
      /* send and what to do with extra rows.  */
      averow = NXPROB/numworkers;
      extra = NXPROB%numworkers;
      offset = 0;
      for (i=1; i<=numworkers; i++)
      {
         rows = (i <= extra) ? averow+1 : averow; 
         /* Tell each worker who its neighbors are, since they must exchange */
         /* data with each other. */  
         if (i == 1) 
            left = NONE;
         else
            left = i - 1;
         if (i == numworkers)
            right = NONE;
         else
            right = i + 1;
         /*  Now send startup information to each worker  */
         dest = i;
         MPI_Send(&offset, 1, MPI_INT, dest, BEGIN, MPI_COMM_WORLD);
         MPI_Send(&rows, 1, MPI_INT, dest, BEGIN, MPI_COMM_WORLD);
         MPI_Send(&left, 1, MPI_INT, dest, BEGIN, MPI_COMM_WORLD);
         MPI_Send(&right, 1, MPI_INT, dest, BEGIN, MPI_COMM_WORLD);
         MPI_Send(&u[0][offset][0], rows*NYPROB, MPI_FLOAT, dest, BEGIN, 
                  MPI_COMM_WORLD);
         printf("Sent to task %d: rows= %d offset= %d ",dest,rows,offset);
         printf("left= %d right= %d\n",left,right);
         offset = offset + rows;
      }
      /* Now wait for results from all worker tasks */
      for (i=1; i<=numworkers; i++)
      {
         source = i;
         msgtype = DONE;
         MPI_Recv(&offset, 1, MPI_INT, source, msgtype, MPI_COMM_WORLD, 
                  &status);
         MPI_Recv(&rows, 1, MPI_INT, source, msgtype, MPI_COMM_WORLD, &status);
         MPI_Recv(&u[0][offset][0], rows*NYPROB, MPI_FLOAT, source,
                  msgtype, MPI_COMM_WORLD, &status);
      }

      /* Write final output, call X graph and finalize MPI */
      printf("Writing final.dat file and generating graph...\n");
      prtdat(NXPROB, NYPROB, &u[0][0][0], "final.dat");
      printf("Click on MORE button to view initial/final states.\n");
      printf("Click on EXIT button to quit program.\n");
      //draw_heat(NXPROB,NYPROB);
      MPI_Finalize();
   }   /* End of master code */



   /************************* workers code **********************************/
   if (taskid != MASTER) 
   {
      /* Initialize everything - including the borders - to zero */
      for (iz=0; iz<2; iz++)
         for (ix=0; ix<NXPROB; ix++) 
            for (iy=0; iy<NYPROB; iy++) 
               u[iz][ix][iy] = 0.0;

      /* Receive my offset, rows, neighbors and grid partition from master */
      source = MASTER;
      msgtype = BEGIN;
      MPI_Recv(&offset, 1, MPI_INT, source, msgtype, MPI_COMM_WORLD, &status);
      MPI_Recv(&rows, 1, MPI_INT, source, msgtype, MPI_COMM_WORLD, &status);
      MPI_Recv(&left, 1, MPI_INT, source, msgtype, MPI_COMM_WORLD, &status);
      MPI_Recv(&right, 1, MPI_INT, source, msgtype, MPI_COMM_WORLD, &status);
      MPI_Recv(&u[0][offset][0], rows*NYPROB, MPI_FLOAT, source, msgtype, 
               MPI_COMM_WORLD, &status);

      /* Determine border elements.  Need to consider first and last columns. */
      /* Obviously, row 0 can't exchange with row 0-1.  Likewise, the last */
      /* row can't exchange with last+1.  */
      start=offset;
      end=offset+rows-1;
      if (offset==0) 
         start=1;
      if ((offset+rows)==NXPROB) 
         end--;
      printf("task=%d  start=%d  end=%d\n",taskid,start,end);

      /* Begin doing STEPS iterations.  Must communicate border rows with */
      /* neighbors.  If I have the first or last grid row, then I only need */
      /*  to  communicate with one neighbor  */
      printf("Task %d received work. Beginning time steps...\n",taskid);
      iz = 0;
      for (it = 1; it <= STEPS; it++)
      {
         if (left != NONE)
         {
            MPI_Send(&u[iz][offset][0], NYPROB, MPI_FLOAT, left,
                     RTAG, MPI_COMM_WORLD);
            source = left;
            msgtype = LTAG;
            MPI_Recv(&u[iz][offset-1][0], NYPROB, MPI_FLOAT, source,
                      msgtype, MPI_COMM_WORLD, &status);
         }
         if (right != NONE)
         {
            MPI_Send(&u[iz][offset+rows-1][0], NYPROB, MPI_FLOAT, right,
                      LTAG, MPI_COMM_WORLD);
            source = right;
            msgtype = RTAG;
            MPI_Recv(&u[iz][offset+rows][0], NYPROB, MPI_FLOAT, source, msgtype,
                      MPI_COMM_WORLD, &status);
         }
         /* Now call update to update the value of grid points */
         update(start,end,NYPROB,&u[iz][0][0],&u[1-iz][0][0]);
         iz = 1 - iz;
      }
      /* Finally, send my portion of final results back to master */
      MPI_Send(&offset, 1, MPI_INT, MASTER, DONE, MPI_COMM_WORLD);
      MPI_Send(&rows, 1, MPI_INT, MASTER, DONE, MPI_COMM_WORLD);
      MPI_Send(&u[iz][offset][0], rows*NYPROB, MPI_FLOAT, MASTER, DONE, 
               MPI_COMM_WORLD);
      MPI_Finalize();
   }
}
예제 #3
0
/* Main program */
int main(){
        /* not Locals */
        lapack_complex_double *a, *temp, * u, *vt;
        lapack_int m = M, n = N, lda = LDA, ldu = LDU, ldvt = LDVT, info;
		
        /* Local arrays */
		//void prtdat();
		double *s;
        double *superb; 
        int svd_count=0;
		int i, j ,ix ,iy, index, ii, jj ;    
		double  x_min,
				x_max,
				y_min,
				y_max,
				stepx,						/* step size for finding gridpoints coordinates in x and y dimension.*/
				stepy;
		double e=0.1;        
		/* Array used for the ploting of
		* grid, as an input to the 
		* draw_pseudospectra function. */
		double *plot;
		//double plot[n][n]; 
		COLOUR colour;
		BITMAP4 col,grey = {128,128,128,0};
		
		       
        /* Memory alocations*/
		temp = malloc((lda*m)*sizeof(lapack_complex_double));
		a = malloc((lda*m)*sizeof(lapack_complex_double));
		u = malloc((ldu*m)*sizeof(lapack_complex_double));
		vt = malloc((ldvt*n)*sizeof(lapack_complex_double));
		s = malloc(m*sizeof(double));
		superb = malloc(min(m,n)*sizeof(double));
		plot = malloc((NGRID*NGRID)*sizeof(double));
		z = malloc((NGRID*NGRID)*sizeof(double _Complex));
		
	
		//allocating the 2D array data.
	  if ((data = malloc(SCALE*NGRID*sizeof(double *))) == NULL) {
      fprintf(stderr,"Failed to malloc space for the data\n");
      exit(-1);
   }
   for (i=0;i<SCALE*NGRID;i++) {
      if ((data[i] = malloc(SCALE*NGRID*sizeof(double))) == NULL) {
         fprintf(stderr,"Failed to malloc space for the data\n");
         exit(-1);
      }
   }
   for (i=0;i<SCALE*NGRID;i++){
      for (j=0;j<SCALE*NGRID;j++){
         data[i][j] = 0;
	 //   printf("%f\t",data[i][j]);
	 }
		  }
		
/*
		printf("-------------------------------------------------\n");
		printf("        ---------------------------------           \n");
		printf ("Starting Computing Pseudopsecta of grcar Matrix\n");
		printf("Give the doundaries of the 2-dimenional domain\n");
		printf("Insert the minimum value of x-axis\n");
		clearerr(stdin);
		scanf("%lf",&x_min);
		//getchar();
		printf("Insert the maximum value of x-axis\n");
		scanf("%lf",&x_max);
		printf("Insert the minimum value of y-axis\n");
		scanf("%lf",&y_min);
		printf("Insert the maximun value of y-axis\n");
		scanf("%lf",&y_max);
		//printf("Give the grid size you want:\n");
		//scanf("%d",&n);
*/ 	  
		/*if (x_min==0.0)*/  x_min=XMIN;
		/*if (x_max==0.0)*/  x_max=XMAX;
		/*if (y_min==0.0)*/  y_min=YMIN;
		/*if (y_max==0.0)*/  y_max=YMAX;
	
		/* Initialize grid */
		printf("The size of the domain is: X=[%f-%f]  Y=[%f-%f] \n",x_min,x_max,y_min,y_max);
	  
		stepx=(double)abs(x_max-x_min)/(NGRID-1);
		stepy=(double)abs(y_max-y_min)/(NGRID-1);
		printf("To stepx einai %f\n",stepx);
		printf("To stepy einai %f\n",stepy);	
	   

	
	   for (i =0; i <NGRID*NGRID; i++){
			z[i]=x_min+(i/n * stepx)+(y_min + (i%n * stepy))*I;
		 // z[i]=lapack_make_complex_double( i/n,i%n); just for testing
		//**	printf( " (%6.2f,%6.2f)", lapack_complex_double_real(z[i]), lapack_complex_double_imag(z[i]) );
		}

	   memset(temp,0,(lda*m)*sizeof(*temp));
	   memset(a,0,(lda*m)*sizeof(*a));
	   memset(u,0,(ldu*m)*sizeof(*u));
	   memset(vt,0,(ldvt*m)*sizeof(*vt));
		
		
	   j=0;
	   for (i = 0; i < lda*m ; i=i+n ){	
			if(i==0){
				a[i]=lapack_make_complex_double( 1,0);
				a[i+1]=lapack_make_complex_double( 1,0);
				a[i+2]=lapack_make_complex_double( 1,0);
				a[i+3]=lapack_make_complex_double( 1,0);
			}
			else if(i == (n-3)*n ){
				a[i+j]=lapack_make_complex_double( -1,0);
				a[i+(j+1)]=lapack_make_complex_double( 1,0);
				a[i+(j+2)]=lapack_make_complex_double( 1,0);
				a[i+(j+3)]=lapack_make_complex_double( 1,0);
				j++;
			}
			else if(i == (n-2)*n ){
				a[i+j]=lapack_make_complex_double( -1,0);
				a[i+(j+1)]=lapack_make_complex_double( 1,0);
				a[i+(j+2)]=lapack_make_complex_double( 1,0);
				j++;
			}
			else if(i == (n-1)*n ){
				a[i+j]=lapack_make_complex_double( -1,0);
				a[i+(j+1)]=lapack_make_complex_double( 1,0);
				j++;
			}
			else{
				a[i+j]=lapack_make_complex_double( -1,0);
				a[i+(j+1)]=lapack_make_complex_double( 1,0);
				a[i+(j+2)]=lapack_make_complex_double( 1,0);
				a[i+(j+3)]=lapack_make_complex_double( 1,0);
				a[i+(j+4)]=lapack_make_complex_double( 1,0);
				j++;
			}
		} 

		//print_matrix("Entry Matrix A", m, n, a, lda );
		for (iy = 0; iy < NGRID*NGRID; iy++){   
			 //printf("temp size %d, a size %d",(lda*m)*sizeof(*temp),(lda*m)*sizeof(*a));
			memcpy(temp, a ,(lda*m)*sizeof(*temp));
			 //~ print_matrix( "Entry Matrix Temp just after memcopy", m, n, temp, lda );
			 //~ print_matrix( "Entry Matrix A just after memcopy", m, n, a, lda );
			// printf( "To  z[%d](%6.4f,%6.4f)\n",iy,lapack_complex_double_real(z[iy]),lapack_complex_double_imag(z[iy]) );
			for (i = 0; i < lda*m ; i=i+(n+1)){	
				//~ printf("%d",i);
				//~ printf( "To  a[%d](%6.2f,%6.2f)\t",i, lapack_complex_double_real(a[i]), lapack_complex_double_imag(a[i]) );
				//~ printf( "To  z[%d](%6.2f,%6.2f)\n",iy,lapack_complex_double_real(z[iy]),lapack_complex_double_imag(z[iy]) );
				
				temp[i]=a[i]-z[iy];
				//~ temp[index] = lapack_make_complex_double(lapack_complex_double_real(a[index])-lapack_complex_double_real(z[iy]),  lapack_complex_double_imag(a[index])-lapack_complex_double_imag(z[iy])    );
				//~ printf( " temp[%d](%6.2f,%6.2f)", i,lapack_complex_double_real(temp[i]), lapack_complex_double_imag(temp[i]) );
				//~ printf( "\n");
			}
			//printf("GRCAR MATRIX AFTER SUBSTRACTION (%d,%d)\n",iy/n,iy%n);
			//~ print_matrix( "Entry Matrix Temp just before", m, n, temp, lda );
	
			/* Executable statements */
			//~ print_matrix( "AT THE BEGINING OF THE FOR LOOP", m, n, a, lda );
			printf( "LAPACKE_zgesvd (row-major, high-level) Example Program Results(%d,%d)\n",iy/NGRID,iy%NGRID);
			/* Compute SVD */
			info = LAPACKE_zgesvd( LAPACK_ROW_MAJOR, 'N', 'N', m, n, temp, lda, s, NULL, ldu, NULL, ldvt, superb );
			svd_count++;
			//~ 
			//~ print_matrix( "IN THE MIDDLE OF THE FOR LOOP", m, n, a, lda );
			//~ print_matrix( "IN THE MIDDLE OF THE FOR LOOP-TEMP", m, n, temp, lda );
			/* Check for convergence */
			if( info > 0 ) {
				printf( "The algorithm computing SVD failed to converge.\n" );
				exit( 1 );
			}
			/* Print singular values */
			if( info == 0){
//				printf("Solution\n");	
				for ( i= 0; i< m; i++ ) {
//					printf(" s[ %d ] = %f\n", i, s[ i ] );
				}
			}
			
			if(s[m-1] <= e){
				printf("THIS ELEMENT BELONGS TO PSEUDOSPECTRA (%d,%d):%6.10f\n",(iy/NGRID+1),(iy%NGRID+1),s[m-1]);
				/*to index tis parapanw ektupwshs anaferetai sto index tou antistoixou mhtrwou apo thn synarthsh ths matlab grcar_example.m*/
				//~ plot[iy/n][iy%n]=s[m-1];
				plot[iy]=s[m-1];
			 }
			 //~ else   plot[iy/n][iy%n]=0;
				else plot[iy]=0;
		
	
		
	//~ print_rmatrix( "Singular values", 1, m, s, 1 );
	
	/* Print left singular vectors */
	// print_matrix( "Left singular vectors (stored columnwise)", m, m, u, ldu );
	/* Print right singular vectors */
	// print_matrix( "Right singular vectors (stored rowwise)", m, n, vt, ldvt );
		}
		
		
		prtdat(NGRID, NGRID, plot, "svd.data");
		printf("Total number of svd evaluations in the %d,%d grid is:\t %d\n",NGRID,NGRID,svd_count);
		
		//giving values to data from plot
		for (i = 0; i<NGRID*NGRID; i++)  data[SCALE*(i/NGRID)][SCALE*(i%NGRID)] = plot[i];
	   /////////////////
    BITMAP4 black = {0,0,0,0};
    Draw_Line(image,NGRID,NGRID,x_min,y_min,x_max,y_min,black);
   //////////////////	
		//~ contours[0] = 0.1;
		//~ contours[1] = 0.01;
		//~ contours[2] = 0.001;
		//~ contours[3] = 0.0001;
		//~ contours[4] = 0.00001;
		if ((image = Create_Bitmap(SCALE*NGRID,SCALE*NGRID)) == NULL) {
      fprintf(stderr,"Malloc of bitmap failed\n");
      exit(-1);
   }
 Erase_Bitmap(image,SCALE*NGRID,SCALE*NGRID,grey); /* Not strictly necessary */
   for (j=0;j<SCALE*NGRID;j++) {
      for (i=0;i<SCALE*NGRID;i++) {
         colour = GetColour(data[i][j],0,0.1,1);      /////////////////////////////////////////////
         col.r = colour.r * 255;
        // col.b = colour.b * 255;
       //  Draw_Pixel(image,SCALE*NGRID,SCALE*NGRID,(double)i,(double)j,col);
        //          colour = GetColour(data[i][j],0,0.0001,1);      /////////////////////////////////////////////
       //  col.g = colour.g * 255;
         Draw_Pixel(image,SCALE*NGRID,SCALE*NGRID,(double)i,(double)j,col);
      }
   }

   /* Finally do the contouring */
   CONREC(data,0,SCALE*NGRID-1,0,SCALE*NGRID-1,
      z,NCONTOUR,contours,drawline);
   fprintf(stderr,"Drew %d vectors\n",vectorsdrawn);

   /* 
      Write the image as a TGA file 
      See bitmaplib.c for more details, or write "image"
      in your own prefered format.
   */
   if ((fp = fopen("image.tga","w")) == NULL) {
      fprintf(stderr,"Failed to open output image\n");
      exit(-1);
   }
   Write_Bitmap(fp,image,SCALE*NGRID,SCALE*NGRID,12);
   fclose(fp);

		
		
		
		exit(0);
} /* End of LAPACKE_zgesvd Example */