1 2 static char help[] = "Tests MatTranspose(), MatNorm(), MatAXPY() and MatAYPX().\n\n"; 3 4 #include <petscmat.h> 5 6 static PetscErrorCode TransposeAXPY(Mat C,PetscScalar alpha,Mat mat,PetscErrorCode (*f)(Mat,Mat*)) 7 { 8 Mat D,E,F,G; 9 MatType mtype; 10 11 PetscFunctionBegin; 12 CHKERRQ(MatGetType(mat,&mtype)); 13 if (f == MatCreateTranspose) { 14 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"\nMatAXPY: (C^T)^T = (C^T)^T + alpha * A, C=A, SAME_NONZERO_PATTERN\n")); 15 } else { 16 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"\nMatAXPY: (C^H)^H = (C^H)^H + alpha * A, C=A, SAME_NONZERO_PATTERN\n")); 17 } 18 CHKERRQ(MatDuplicate(mat,MAT_COPY_VALUES,&C)); 19 CHKERRQ(f(C,&D)); 20 CHKERRQ(f(D,&E)); 21 CHKERRQ(MatAXPY(E,alpha,mat,SAME_NONZERO_PATTERN)); 22 CHKERRQ(MatConvert(E,mtype,MAT_INPLACE_MATRIX,&E)); 23 CHKERRQ(MatView(E,PETSC_VIEWER_STDOUT_WORLD)); 24 CHKERRQ(MatDestroy(&E)); 25 CHKERRQ(MatDestroy(&D)); 26 CHKERRQ(MatDestroy(&C)); 27 if (f == MatCreateTranspose) { 28 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: C = C + alpha * (A^T)^T, C=A, SAME_NONZERO_PATTERN\n")); 29 } else { 30 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: C = C + alpha * (A^H)^H, C=A, SAME_NONZERO_PATTERN\n")); 31 } 32 if (f == MatCreateTranspose) { 33 CHKERRQ(MatTranspose(mat,MAT_INITIAL_MATRIX,&D)); 34 } else { 35 CHKERRQ(MatHermitianTranspose(mat,MAT_INITIAL_MATRIX,&D)); 36 } 37 CHKERRQ(f(D,&E)); 38 CHKERRQ(MatDuplicate(mat,MAT_COPY_VALUES,&C)); 39 CHKERRQ(MatAXPY(C,alpha,E,SAME_NONZERO_PATTERN)); 40 CHKERRQ(MatView(C,PETSC_VIEWER_STDOUT_WORLD)); 41 CHKERRQ(MatDestroy(&E)); 42 CHKERRQ(MatDestroy(&D)); 43 CHKERRQ(MatDestroy(&C)); 44 if (f == MatCreateTranspose) { 45 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: (C^T)^T = (C^T)^T + alpha * (A^T)^T, C=A, SAME_NONZERO_PATTERN\n")); 46 } else { 47 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: (C^H)^H = (C^H)^H + alpha * (A^H)^H, C=A, SAME_NONZERO_PATTERN\n")); 48 } 49 CHKERRQ(MatDuplicate(mat,MAT_COPY_VALUES,&C)); 50 CHKERRQ(f(C,&D)); 51 CHKERRQ(f(D,&E)); 52 CHKERRQ(f(mat,&F)); 53 CHKERRQ(f(F,&G)); 54 CHKERRQ(MatAXPY(E,alpha,G,SAME_NONZERO_PATTERN)); 55 CHKERRQ(MatConvert(E,mtype,MAT_INPLACE_MATRIX,&E)); 56 CHKERRQ(MatView(E,PETSC_VIEWER_STDOUT_WORLD)); 57 CHKERRQ(MatDestroy(&G)); 58 CHKERRQ(MatDestroy(&F)); 59 CHKERRQ(MatDestroy(&E)); 60 CHKERRQ(MatDestroy(&D)); 61 CHKERRQ(MatDestroy(&C)); 62 63 /* Call f on a matrix that does not implement the transposition */ 64 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: Now without the transposition operation\n")); 65 CHKERRQ(MatConvert(mat,MATSHELL,MAT_INITIAL_MATRIX,&C)); 66 CHKERRQ(f(C,&D)); 67 CHKERRQ(f(D,&E)); 68 /* XXX cannot use MAT_INPLACE_MATRIX, it leaks mat */ 69 CHKERRQ(MatConvert(E,mtype,MAT_INITIAL_MATRIX,&F)); 70 CHKERRQ(MatAXPY(F,alpha,mat,SAME_NONZERO_PATTERN)); 71 CHKERRQ(MatView(F,PETSC_VIEWER_STDOUT_WORLD)); 72 CHKERRQ(MatDestroy(&F)); 73 CHKERRQ(MatDestroy(&E)); 74 CHKERRQ(MatDestroy(&D)); 75 CHKERRQ(MatDestroy(&C)); 76 PetscFunctionReturn(0); 77 } 78 79 int main(int argc,char **argv) 80 { 81 Mat mat,tmat = 0; 82 PetscInt m = 7,n,i,j,rstart,rend,rect = 0; 83 PetscErrorCode ierr; 84 PetscMPIInt size,rank; 85 PetscBool flg; 86 PetscScalar v, alpha; 87 PetscReal normf,normi,norm1; 88 89 ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 90 CHKERRQ(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_COMMON)); 91 CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL)); 92 CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 93 CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); 94 n = m; 95 CHKERRQ(PetscOptionsHasName(NULL,NULL,"-rectA",&flg)); 96 if (flg) {n += 2; rect = 1;} 97 CHKERRQ(PetscOptionsHasName(NULL,NULL,"-rectB",&flg)); 98 if (flg) {n -= 2; rect = 1;} 99 100 /* ------- Assemble matrix --------- */ 101 CHKERRQ(MatCreate(PETSC_COMM_WORLD,&mat)); 102 CHKERRQ(MatSetSizes(mat,PETSC_DECIDE,PETSC_DECIDE,m,n)); 103 CHKERRQ(MatSetFromOptions(mat)); 104 CHKERRQ(MatSetUp(mat)); 105 CHKERRQ(MatGetOwnershipRange(mat,&rstart,&rend)); 106 for (i=rstart; i<rend; i++) { 107 for (j=0; j<n; j++) { 108 v = 10.0*i+j+1.0; 109 CHKERRQ(MatSetValues(mat,1,&i,1,&j,&v,INSERT_VALUES)); 110 } 111 } 112 CHKERRQ(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY)); 113 CHKERRQ(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY)); 114 115 /* ----------------- Test MatNorm() ----------------- */ 116 CHKERRQ(MatNorm(mat,NORM_FROBENIUS,&normf)); 117 CHKERRQ(MatNorm(mat,NORM_1,&norm1)); 118 CHKERRQ(MatNorm(mat,NORM_INFINITY,&normi)); 119 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"original A: Frobenious norm = %g, one norm = %g, infinity norm = %g\n",(double)normf,(double)norm1,(double)normi)); 120 CHKERRQ(MatView(mat,PETSC_VIEWER_STDOUT_WORLD)); 121 122 /* --------------- Test MatTranspose() -------------- */ 123 CHKERRQ(PetscOptionsHasName(NULL,NULL,"-in_place",&flg)); 124 if (!rect && flg) { 125 CHKERRQ(MatTranspose(mat,MAT_REUSE_MATRIX,&mat)); /* in-place transpose */ 126 tmat = mat; 127 mat = NULL; 128 } else { /* out-of-place transpose */ 129 CHKERRQ(MatTranspose(mat,MAT_INITIAL_MATRIX,&tmat)); 130 } 131 132 /* ----------------- Test MatNorm() ----------------- */ 133 /* Print info about transpose matrix */ 134 CHKERRQ(MatNorm(tmat,NORM_FROBENIUS,&normf)); 135 CHKERRQ(MatNorm(tmat,NORM_1,&norm1)); 136 CHKERRQ(MatNorm(tmat,NORM_INFINITY,&normi)); 137 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"B = A^T: Frobenious norm = %g, one norm = %g, infinity norm = %g\n",(double)normf,(double)norm1,(double)normi)); 138 CHKERRQ(MatView(tmat,PETSC_VIEWER_STDOUT_WORLD)); 139 140 /* ----------------- Test MatAXPY(), MatAYPX() ----------------- */ 141 if (mat && !rect) { 142 alpha = 1.0; 143 CHKERRQ(PetscOptionsGetScalar(NULL,NULL,"-alpha",&alpha,NULL)); 144 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: B = B + alpha * A\n")); 145 CHKERRQ(MatAXPY(tmat,alpha,mat,DIFFERENT_NONZERO_PATTERN)); 146 CHKERRQ(MatView(tmat,PETSC_VIEWER_STDOUT_WORLD)); 147 148 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAYPX: B = alpha*B + A\n")); 149 CHKERRQ(MatAYPX(tmat,alpha,mat,DIFFERENT_NONZERO_PATTERN)); 150 CHKERRQ(MatView(tmat,PETSC_VIEWER_STDOUT_WORLD)); 151 } 152 153 { 154 Mat C; 155 alpha = 1.0; 156 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: C = C + alpha * A, C=A, SAME_NONZERO_PATTERN\n")); 157 CHKERRQ(MatDuplicate(mat,MAT_COPY_VALUES,&C)); 158 CHKERRQ(MatAXPY(C,alpha,mat,SAME_NONZERO_PATTERN)); 159 CHKERRQ(MatView(C,PETSC_VIEWER_STDOUT_WORLD)); 160 CHKERRQ(MatDestroy(&C)); 161 CHKERRQ(TransposeAXPY(C,alpha,mat,MatCreateTranspose)); 162 CHKERRQ(TransposeAXPY(C,alpha,mat,MatCreateHermitianTranspose)); 163 } 164 165 { 166 Mat matB; 167 /* get matB that has nonzeros of mat in all even numbers of row and col */ 168 CHKERRQ(MatCreate(PETSC_COMM_WORLD,&matB)); 169 CHKERRQ(MatSetSizes(matB,PETSC_DECIDE,PETSC_DECIDE,m,n)); 170 CHKERRQ(MatSetFromOptions(matB)); 171 CHKERRQ(MatSetUp(matB)); 172 CHKERRQ(MatGetOwnershipRange(matB,&rstart,&rend)); 173 if (rstart % 2 != 0) rstart++; 174 for (i=rstart; i<rend; i += 2) { 175 for (j=0; j<n; j += 2) { 176 v = 10.0*i+j+1.0; 177 CHKERRQ(MatSetValues(matB,1,&i,1,&j,&v,INSERT_VALUES)); 178 } 179 } 180 CHKERRQ(MatAssemblyBegin(matB,MAT_FINAL_ASSEMBLY)); 181 CHKERRQ(MatAssemblyEnd(matB,MAT_FINAL_ASSEMBLY)); 182 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD," A: original matrix:\n")); 183 CHKERRQ(MatView(mat,PETSC_VIEWER_STDOUT_WORLD)); 184 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD," B(a subset of A):\n")); 185 CHKERRQ(MatView(matB,PETSC_VIEWER_STDOUT_WORLD)); 186 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: B = B + alpha * A, SUBSET_NONZERO_PATTERN\n")); 187 CHKERRQ(MatAXPY(mat,alpha,matB,SUBSET_NONZERO_PATTERN)); 188 CHKERRQ(MatView(mat,PETSC_VIEWER_STDOUT_WORLD)); 189 CHKERRQ(MatDestroy(&matB)); 190 } 191 192 /* Test MatZeroRows */ 193 j = rstart - 1; 194 if (j < 0) j = m-1; 195 CHKERRQ(MatZeroRows(mat,1,&j,0.0,NULL,NULL)); 196 CHKERRQ(MatView(mat,PETSC_VIEWER_STDOUT_WORLD)); 197 198 CHKERRQ(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD)); 199 /* Free data structures */ 200 CHKERRQ(MatDestroy(&mat)); 201 CHKERRQ(MatDestroy(&tmat)); 202 ierr = PetscFinalize(); 203 return ierr; 204 } 205 206 /*TEST 207 208 test: 209 suffix: 11_A 210 args: -mat_type seqaij -rectA 211 filter: grep -v "Mat Object" 212 213 test: 214 suffix: 12_A 215 args: -mat_type seqdense -rectA 216 filter: grep -v type | grep -v "Mat Object" 217 218 test: 219 requires: cuda 220 suffix: 12_A_cuda 221 args: -mat_type seqdensecuda -rectA 222 output_file: output/ex2_12_A.out 223 filter: grep -v type | grep -v "Mat Object" 224 225 test: 226 requires: kokkos_kernels 227 suffix: 12_A_kokkos 228 args: -mat_type aijkokkos -rectA 229 output_file: output/ex2_12_A.out 230 filter: grep -v type | grep -v "Mat Object" 231 232 test: 233 suffix: 11_B 234 args: -mat_type seqaij -rectB 235 filter: grep -v "Mat Object" 236 237 test: 238 suffix: 12_B 239 args: -mat_type seqdense -rectB 240 filter: grep -v type | grep -v "Mat Object" 241 242 test: 243 requires: cuda 244 suffix: 12_B_cuda 245 args: -mat_type seqdensecuda -rectB 246 output_file: output/ex2_12_B.out 247 filter: grep -v type | grep -v "Mat Object" 248 249 test: 250 requires: kokkos_kernels 251 suffix: 12_B_kokkos 252 args: -mat_type aijkokkos -rectB 253 output_file: output/ex2_12_B.out 254 filter: grep -v type | grep -v "Mat Object" 255 256 test: 257 suffix: 21 258 args: -mat_type mpiaij 259 filter: grep -v type | grep -v "MPI processes" 260 261 test: 262 suffix: 22 263 args: -mat_type mpidense 264 filter: grep -v type | grep -v "Mat Object" 265 266 test: 267 requires: cuda 268 suffix: 22_cuda 269 output_file: output/ex2_22.out 270 args: -mat_type mpidensecuda 271 filter: grep -v type | grep -v "Mat Object" 272 273 test: 274 requires: kokkos_kernels 275 suffix: 22_kokkos 276 output_file: output/ex2_22.out 277 args: -mat_type aijkokkos 278 filter: grep -v type | grep -v "Mat Object" 279 280 test: 281 suffix: 23 282 nsize: 3 283 args: -mat_type mpiaij 284 filter: grep -v type | grep -v "MPI processes" 285 286 test: 287 suffix: 24 288 nsize: 3 289 args: -mat_type mpidense 290 filter: grep -v type | grep -v "Mat Object" 291 292 test: 293 requires: cuda 294 suffix: 24_cuda 295 nsize: 3 296 output_file: output/ex2_24.out 297 args: -mat_type mpidensecuda 298 filter: grep -v type | grep -v "Mat Object" 299 300 test: 301 suffix: 2_aijcusparse_1 302 args: -mat_type mpiaijcusparse 303 output_file: output/ex2_21.out 304 requires: cuda 305 filter: grep -v type | grep -v "MPI processes" 306 307 test: 308 suffix: 2_aijkokkos_1 309 args: -mat_type aijkokkos 310 output_file: output/ex2_21.out 311 requires: kokkos_kernels 312 filter: grep -v type | grep -v "MPI processes" 313 314 test: 315 suffix: 2_aijcusparse_2 316 nsize: 3 317 args: -mat_type mpiaijcusparse 318 output_file: output/ex2_23.out 319 requires: cuda 320 filter: grep -v type | grep -v "MPI processes" 321 322 test: 323 suffix: 2_aijkokkos_2 324 nsize: 3 325 args: -mat_type aijkokkos 326 output_file: output/ex2_23.out 327 # Turn off hip due to intermittent CI failures on hip.txcorp.com. Should re-enable this test when the machine is upgraded. 328 requires: !sycl !hip kokkos_kernels 329 filter: grep -v type | grep -v "MPI processes" 330 331 test: 332 suffix: 3 333 nsize: 2 334 args: -mat_type mpiaij -rectA 335 336 test: 337 suffix: 3_aijcusparse 338 nsize: 2 339 args: -mat_type mpiaijcusparse -rectA 340 requires: cuda 341 342 test: 343 suffix: 4 344 nsize: 2 345 args: -mat_type mpidense -rectA 346 filter: grep -v type | grep -v "MPI processes" 347 348 test: 349 requires: cuda 350 suffix: 4_cuda 351 nsize: 2 352 output_file: output/ex2_4.out 353 args: -mat_type mpidensecuda -rectA 354 filter: grep -v type | grep -v "MPI processes" 355 356 test: 357 suffix: aijcusparse_1 358 args: -mat_type seqaijcusparse -rectA 359 filter: grep -v "Mat Object" 360 output_file: output/ex2_11_A_aijcusparse.out 361 requires: cuda 362 363 test: 364 suffix: aijcusparse_2 365 args: -mat_type seqaijcusparse -rectB 366 filter: grep -v "Mat Object" 367 output_file: output/ex2_11_B_aijcusparse.out 368 requires: cuda 369 370 TEST*/ 371