tutorial
来自「并行解法器,功能强大」· 代码 · 共 1,185 行 · 第 1/4 页
TXT
1,185 行
#====================================================================# ------------------------# | CVS File Information |# ------------------------# # $RCSfile: az_tutorial,v $## $Author: tuminaro $## $Date: 2000/06/02 16:49:21 $## $Revision: 1.6 $## $Name: $#==================================================================== AZTEC TutorialA sample AZTEC application is provided in the file 'az_tutorial.c'. The 11 exercises below are performed by continually modifying the sample program. By doing the exercises, the new user will be introduced to many of AZTEC'sfeatures. Unless otherwise stated, problem x will require modification to the program used for problem x-1. Complete answers to the exercises aregiven at the end of this document.To compile and run the original sample program, the OBJ line in the application Makefile must be changed to : OBJ = az_tutorial.o. 'az_tutorial.c' corresponds to setting up and solving a 2D Poisson approximation on a 6 x 6 grid where the right hand side corresponds to a delta function in the lower left corner of the grid. Below we illustrate the program body:line no.------- 62 /* get number of processors and the name of this processor */ 63 #ifdef AZ_MPI 64 MPI_Init(&argc,&argv); 65 AZ_set_proc_config(proc_config, MPI_COMM_WORLD); 66 #else 67 AZ_set_proc_config(proc_config, AZ_NOT_MPI); 68 #endif 69 70 /* Define partitioning: matrix rows (ascending order) owned by this node */ 71 72 nrow = n*n; 73 AZ_read_update(&N_update, &update, proc_config, nrow, 1, AZ_linear); 74 75 /* 76 * Create the matrix: each processor creates only rows appearing in update[] 77 * (using global col. numbers). 78 */ 79 80 bindx = (int *) calloc(N_update*MAX_NZ_ROW+1,sizeof(int)); 81 val = (double *) calloc(N_update*MAX_NZ_ROW+1,sizeof(double)); 82 if (val == NULL) perror("Error: Not enough space to create matrix"); 83 84 bindx[0] = N_update+1; 85 86 for (i = 0; i < N_update; i++) { 87 create_matrix_row(update[i], i, val, bindx); 88 } 89 90 /* convert matrix to a local distributed matrix */ 91 92 AZ_transform(proc_config, &external, bindx, val, update, &update_index, 93 &extern_index, &data_org, N_update, NULL, NULL, NULL, NULL, 94 AZ_MSR_MATRIX); 95 96 /* initialize AZTEC options */ 97 98 AZ_defaults(options, params); 99 100 /* Set rhs (delta function at lower left corner) and initialize guess */ 101 102 b = (double *) calloc(N_update, sizeof(double)); 103 x = (double *) calloc(N_update + data_org[AZ_N_external], sizeof(double)); 104 if ((x == NULL) && (i != 0)) perror("Not enough space in rhs"); 105 106 for (i = 0; i < N_update; i++) { 107 x[update_index[i]] = 0.0; 108 b[update_index[i]] = 0.0; 109 if (update[i] == 0) b[update_index[i]] = 1.0; 110 } 111 112 113 /* solve the system of equations using b as the right hand side */ 114 115 AZ_solve(x, b, options, params, NULL, bindx, NULL, NULL, NULL, val, data_org, 116 status, proc_config); 117 118 /* Free allocated memory */ 119 120 121 free((void *) update); free((void *) update_index); 122 free((void *) external); free((void *) extern_index); 123 124 free((void *) x); free((void *) b); free((void *) bindx); 125 free((void *) val); free((void *) data_org); 126 127 128 #ifdef AZ_MPI 129 MPI_Finalize(); 130 #endif 131 132 } /* main */ 133 134 135 136 137 138 139 140 /***************************************************************************/ 141 /***************************************************************************/ 142 /***************************************************************************/ 143 144 void create_matrix_row(int row, int location, double val[], int bindx[]) 145 146 /* Add one row to an MSR matrix corresponding to a discrete approximation to the 147 * 2D Poisson operator on an n x n square. 148 * 149 * Parameters: 150 * row == global row number of the new row to be added. 151 * location == local row where diagonal of the new row will be stored. 152 * val,bindx == (see user's guide). On output, val[] and bindx[] 153 * are appended such that the new row has been added. 154 */ 155 156 { 157 int k; 158 159 /* check neighbors in each direction and add nonzero if neighbor exits */ 160 161 k = bindx[location]; 162 bindx[k] = row + 1; if ((row )%n != n-1) val[k++] = -1.; 163 bindx[k] = row - 1; if ((row )%n != 0) val[k++] = -1.; 164 bindx[k] = row + n; if ((row/n)%n != n-1) val[k++] = -1.; 165 bindx[k] = row - n; if ((row/n)%n != 0) val[k++] = -1.; 166 167 bindx[location+1] = k; val[location] = 4.; /* matrix diagonal */ 168 }If you run this program, the iteration output should approximately be the following: ******************************************************* ***** Preconditioned GMRES solution ***** No preconditioning ***** No scaling ******************************************************* iter: 0 residual = 1.000000e+00 iter: 1 residual = 3.333333e-01 iter: 2 residual = 1.549193e-01 iter: 3 residual = 8.498208e-02 iter: 4 residual = 5.178089e-02 iter: 5 residual = 3.392084e-02 iter: 6 residual = 2.343361e-02 iter: 7 residual = 1.673219e-02 iter: 8 residual = 1.183812e-02 iter: 9 residual = 7.732077e-03 iter: 10 residual = 4.398328e-03 iter: 11 residual = 1.241776e-03 iter: 12 residual = 5.528073e-04 iter: 13 residual = 1.918082e-04 iter: 14 residual = 6.826307e-05 iter: 15 residual = 1.470372e-05 iter: 16 residual = 3.001987e-06 iter: 17 residual = 2.111772e-07 ---IMPORTANT: SAVE A COPY OF THIS PROGRAM IN THE FILE 'original.c'.Problem 1: 2D Poisson PARTITIONING (6 x 6)=========To partition or distribute problems over processors, each processormust set 'N_update' to the number of matrix rows it will own and the array 'update' to the specific matrix row numbers (in ascending order)owned by this processor. In our sample program, a linear partitioning is used via the function AZ_read_update() (line 73).Change the AZ_read_update() call so that it instead reads the paritioningfrom the file '.update'. Initialize this file so that the row r (0 <= r < 36)is assigned to processor number r%P (mod function in "C") where P isthe number of processors used with this '.update' file. Note: AZ_read_update() is not particularly fast in that it reads a single file and thus distributes rows serially. For large data setsit is generally better to use some kind of parallel input/output.See the AZ_read_update() description in the Aztec User's Guide for more information.The output of this program should be the same as that of the originalsample problem as we have only changed the assignment of rows to processors. Problem 2: DENSE MSR matrix (4 x 4)=========IMPORTANT: COPY THE FILE 'original.c' INTO 'az_tutorial.c'. YOU MIGHT WANT TO SAVE 'az_tutorial.c' BEFORE DOING THIS.Change this program to solve the matrix application / \ / \ | 7 3 2 1 | | 1 | | 5 8 3 1 | x = | 0 | | 5 3 9 2 | | 0 | | 1 2 1 6 | | 0 | \ / \ /Using x = 0 as an initial guess.Hint: Change in line 72 to indicate the number of matrix rows (nrow=4). Other than this, only the subroutine create_matrix_row() needs to be changed. The "Data Formats" and "High Level Data Interface" sections of the Aztec User's Guide explain the MSR data format used to represent the matrix. Essentially, to append a row to a matrix already containing j rows (rows are locally numbered from 0 to j-1), we need to do the following: a) set index, k, to point to the free space for the offdiagonal elements: k = bindx[j] b) Store each off diagonal element as follows: val[k] = 1st off-diagonal, bindx[k] = 1st off-diagonal column number k = k + 1 val[k] = 2nd off-diagonal, bindx[k] = 2nd off-diagonal column number etc c) put the diagonal element of the new row in val[j] d) store free space pointer in bindx[j+1] (i.e. bindx[j+1] = k).This program should produce approximately the following iteration output: ******************************************************* ***** Preconditioned GMRES solution ***** No preconditioning ***** No scaling ******************************************************* iter: 0 residual = 1.000000e+00 iter: 1 residual = 7.141428e-01 iter: 2 residual = 1.687498e-01 iter: 3 residual = 2.119830e-02 iter: 4 residual = 1.928932e-16---Problem 3: Aztec OPTIONS (solver) - 2D Poisson (6 x 6)=========IMPORTANT: COPY THE FILE 'original.c' INTO 'az_tutorial.c'. YOU MIGHT WANT TO SAVE 'az_tutorial.c' BEFORE DOING THIS.The original sample program uses the GMRES algorithm as this is the default AZTEC method (indicated by setting options[AZ_solver] in AZ_defaults). Changethe sample program so that we use the TFQMR method and so that the algorithmterminates when the initial residual is reduced by 10^5 (instead of the default 10^6). See the "Aztec Options" section of the Aztec User's Guide for more information.Note: this example is just for demonstration purposes as we should really usethe conjugate gradient algorithm for this symmetric problem.The resulting iteration output of the program should now approximately be: ******************************************************* ***** Preconditioned TFQMR solution ***** No preconditioning ***** No scaling ******************************************************* iter: 0 residual = 1.000000e+00 iter: 1 residual = 3.078276e-01 iter: 2 residual = 1.352989e-01 iter: 3 residual = 7.202456e-02 iter: 4 residual = 4.273759e-02 iter: 5 residual = 2.571415e-02 iter: 6 residual = 1.391762e-02 iter: 7 residual = 6.317909e-03 iter: 8 residual = 2.292283e-03 iter: 9 residual = 6.648821e-04 iter: 10 residual = 1.506405e-04 iter: 11 residual = 1.590716e-05 iter: 12 residual = 9.021697e-07 --- Problem 4: BROADCASTING n ( grid-size parameter ) - 2D Poisson (n x n)=========Currently, the grid size parameter, n (for an n x n grid), is fixed.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?