1from petsc4py import PETSc 2import unittest 3 4import numpy as np 5 6 7def mkdata(comm, m, N, bs): 8 start = m * comm.rank 9 end = start + m 10 idt = PETSc.IntType 11 sdt = PETSc.ScalarType 12 rows = np.array(range(start, end), dtype=idt) 13 cols = np.array(range(N), dtype=idt) 14 vals = np.array(range(m * N * bs * bs), dtype=sdt) 15 vals.shape = (-1, bs, bs) 16 return rows, cols, vals 17 18 19class BaseTestMatAnyDense: 20 COMM = PETSc.COMM_NULL 21 GRID = 0, 0 22 BSIZE = None 23 TYPE = PETSc.Mat.Type.DENSE 24 25 def setUp(self): 26 COMM = self.COMM 27 GM, GN = self.GRID 28 BS = self.BSIZE # or 1 29 # 30 self.A = PETSc.Mat().create(comm=COMM) 31 bs = BS or 1 32 m, N = GM, GN 33 rowsz = (m * bs, None) 34 colsz = (None, N * bs) 35 self.A.setSizes([rowsz, colsz], BS) 36 self.A.setType(self.TYPE) 37 38 def tearDown(self): 39 self.A.destroy() 40 self.A = None 41 PETSc.garbage_cleanup() 42 43 def testSetValues(self): 44 self._preallocate() 45 r, c, v = self._set_values() 46 self.A.assemble() 47 self._chk_array(self.A, r, c, v) 48 r, c, v = self._set_values() 49 self.A.assemble() 50 self._chk_array(self.A, r, c, v) 51 52 def testGetDiagonalBlock(self): 53 M, N = self.A.getSize() 54 # only for square matrices 55 if M != N: 56 return 57 self._preallocate() 58 self._set_values() 59 self.A.assemble() 60 B = self.A.getDiagonalBlock() 61 self.assertEqual(self.A.getLocalSize(), B.getSize()) 62 B.destroy() 63 64 def testSubMatrix(self): 65 self._preallocate() 66 self._set_values() 67 self.A.assemble() 68 B = self.A.getDenseSubMatrix() 69 X = B.copy() 70 self.A.restoreDenseSubMatrix(B) 71 self.assertTrue(self.A.equal(X)) 72 X.destroy() 73 M, N = self.A.getSize() 74 rst = min(1,M) 75 cst = min(2,N) 76 ren = min(3,M) 77 cen = min(5,N) 78 B = self.A.getDenseSubMatrix(rst, ren, cst, cen) 79 self.assertTrue(B.getSize(), (ren - rst, cen - cst)) 80 self.A.restoreDenseSubMatrix(B) 81 self.assertFalse(B) 82 B = self.A.getDenseSubMatrix(cbegin=cst, rbegin=rst, cend=cen, rend=ren) 83 self.assertTrue(B.getSize(), (ren - rst, cen - cst)) 84 self.A.restoreDenseSubMatrix(B) 85 self.assertFalse(B) 86 87 def testCreateTranspose(self): 88 self._preallocate() 89 self._set_values() 90 self.A.assemble() 91 A = self.A 92 AT = PETSc.Mat().createTranspose(A) 93 x, y = A.createVecs() 94 xt, yt = AT.createVecs() 95 # 96 y.setRandom() 97 A.multTranspose(y, x) 98 y.copy(xt) 99 AT.mult(xt, yt) 100 self.assertTrue(yt.equal(x)) 101 # 102 x.setRandom() 103 A.mult(x, y) 104 x.copy(yt) 105 AT.multTranspose(yt, xt) 106 self.assertTrue(xt.equal(y)) 107 # 108 underlyingA = AT.getTransposeMat() 109 self.assertTrue(underlyingA.equal(A)) 110 111 def _preallocate(self): 112 self.A.setPreallocationDense(None) 113 114 def _set_values(self): 115 COMM = self.COMM 116 GM, GN = self.GRID 117 BS = self.BSIZE or 1 118 rows, cols, vals = mkdata(COMM, GM, GN, BS) 119 if not self.BSIZE: 120 setvalues = self.A.setValues 121 else: 122 setvalues = self.A.setValuesBlocked 123 setvalues(rows, cols, vals) 124 return rows, cols, vals 125 126 def _chk_bs(self, A, bs): 127 self.assertEqual(A.getBlockSize(), bs or 1) 128 129 def _chk_array(self, A, r, c, v): 130 return # XXX 131 vals = self.A.getValues(r, c) 132 vals.shape = v.shape 133 self.assertTrue(np.allclose(vals, v)) 134 135 136# -- Dense --------------------- 137 138 139class BaseTestMatDense(BaseTestMatAnyDense, unittest.TestCase): 140 COMM = PETSc.COMM_WORLD 141 GRID = 0, 0 142 BSIZE = None 143 144 145# -- Seq Dense -- 146 147 148class TestMatSeqDense(BaseTestMatDense): 149 COMM = PETSc.COMM_SELF 150 TYPE = PETSc.Mat.Type.SEQDENSE 151 152 153class TestMatSeqDense_G23(TestMatSeqDense): 154 GRID = 2, 3 155 156 157class TestMatSeqDense_G45(TestMatSeqDense): 158 GRID = 4, 5 159 160 161class TestMatSeqDense_G77(TestMatSeqDense): 162 GRID = 7, 7 163 164 165class TestMatSeqDense_G89(TestMatSeqDense): 166 GRID = 8, 9 167 168 169# -- MPI Dense -- 170 171 172class TestMatMPIDense(BaseTestMatDense): 173 COMM = PETSc.COMM_WORLD 174 TYPE = PETSc.Mat.Type.MPIDENSE 175 176 177class TestMatMPIDense_G23(TestMatMPIDense): 178 GRID = 2, 3 179 180 181class TestMatMPIDense_G45(TestMatMPIDense): 182 GRID = 4, 5 183 184 185class TestMatMPIDense_G77(TestMatMPIDense): 186 GRID = 7, 7 187 188 189class TestMatMPIDense_G89(TestMatMPIDense): 190 GRID = 8, 9 191 192 193# -- Dense + Block --------------- 194 195 196class BaseTestMatDense_B(BaseTestMatAnyDense, unittest.TestCase): 197 COMM = PETSc.COMM_WORLD 198 GRID = 0, 0 199 BSIZE = 1 200 201 def _preallocate(self): 202 # self.A.setBlockSize(self.BSIZE) 203 self.A.setPreallocationDense(None) 204 # self.A.setBlockSize(self.BSIZE) 205 self._chk_bs(self.A, self.BSIZE) 206 207 208# -- Seq Dense + Block -- 209 210 211class TestMatSeqDense_B(BaseTestMatDense_B): 212 COMM = PETSc.COMM_SELF 213 TYPE = PETSc.Mat.Type.SEQDENSE 214 215 216# bs = 1 217class TestMatSeqDense_B_G23(TestMatSeqDense_B): 218 GRID = 2, 3 219 220 221class TestMatSeqDense_B_G45(TestMatSeqDense_B): 222 GRID = 4, 5 223 224 225class TestMatSeqDense_B_G89(TestMatSeqDense_B): 226 GRID = 8, 9 227 228 229# bs = 2 230class TestMatSeqDense_B_G23_B2(TestMatSeqDense_B_G23): 231 BSIZE = 2 232 233 234class TestMatSeqDense_B_G45_B2(TestMatSeqDense_B_G45): 235 BSIZE = 2 236 237 238class TestMatSeqDense_B_G89_B2(TestMatSeqDense_B_G89): 239 BSIZE = 2 240 241 242# bs = 3 243class TestMatSeqDense_B_G23_B3(TestMatSeqDense_B_G23): 244 BSIZE = 3 245 246 247class TestMatSeqDense_B_G45_B3(TestMatSeqDense_B_G45): 248 BSIZE = 3 249 250 251class TestMatSeqDense_B_G89_B3(TestMatSeqDense_B_G89): 252 BSIZE = 3 253 254 255# bs = 4 256class TestMatSeqDense_B_G23_B4(TestMatSeqDense_B_G23): 257 BSIZE = 4 258 259 260class TestMatSeqDense_B_G45_B4(TestMatSeqDense_B_G45): 261 BSIZE = 4 262 263 264class TestMatSeqDense_B_G89_B4(TestMatSeqDense_B_G89): 265 BSIZE = 4 266 267 268# bs = 5 269class TestMatSeqDense_B_G23_B5(TestMatSeqDense_B_G23): 270 BSIZE = 5 271 272 273class TestMatSeqDense_B_G45_B5(TestMatSeqDense_B_G45): 274 BSIZE = 5 275 276 277class TestMatSeqDense_B_G89_B5(TestMatSeqDense_B_G89): 278 BSIZE = 5 279 280 281# -- MPI Dense + Block -- 282 283 284class TestMatMPIDense_B(BaseTestMatDense_B): 285 COMM = PETSc.COMM_WORLD 286 TYPE = PETSc.Mat.Type.MPIDENSE 287 288 289# bs = 1 290class TestMatMPIDense_B_G23(TestMatMPIDense_B): 291 GRID = 2, 3 292 293 294class TestMatMPIDense_B_G45(TestMatMPIDense_B): 295 GRID = 4, 5 296 297 298class TestMatMPIDense_B_G77(TestMatMPIDense_B): 299 GRID = 7, 7 300 301 302class TestMatMPIDense_B_G89(TestMatMPIDense_B): 303 GRID = 8, 9 304 305 306# bs = 2 307class TestMatMPIDense_B_G23_B2(TestMatMPIDense_B_G23): 308 BSIZE = 2 309 310 311class TestMatMPIDense_B_G45_B2(TestMatMPIDense_B_G45): 312 BSIZE = 2 313 314 315class TestMatMPIDense_B_G77_B2(TestMatMPIDense_B_G77): 316 BSIZE = 2 317 318 319class TestMatMPIDense_B_G89_B2(TestMatMPIDense_B_G89): 320 BSIZE = 2 321 322 323# bs = 3 324class TestMatMPIDense_B_G23_B3(TestMatMPIDense_B_G23): 325 BSIZE = 3 326 327 328class TestMatMPIDense_B_G45_B3(TestMatMPIDense_B_G45): 329 BSIZE = 3 330 331 332class TestMatMPIDense_B_G77_B3(TestMatMPIDense_B_G77): 333 BSIZE = 3 334 335 336class TestMatMPIDense_B_G89_B3(TestMatMPIDense_B_G89): 337 BSIZE = 3 338 339 340# bs = 4 341class TestMatMPIDense_B_G23_B4(TestMatMPIDense_B_G23): 342 BSIZE = 4 343 344 345class TestMatMPIDense_B_G45_B4(TestMatMPIDense_B_G45): 346 BSIZE = 4 347 348 349class TestMatMPIDense_B_G77_B4(TestMatMPIDense_B_G77): 350 BSIZE = 4 351 352 353class TestMatMPIDense_B_G89_B4(TestMatMPIDense_B_G89): 354 BSIZE = 4 355 356 357# bs = 5 358class TestMatMPIDense_B_G23_B5(TestMatMPIDense_B_G23): 359 BSIZE = 5 360 361 362class TestMatMPIDense_B_G45_B5(TestMatMPIDense_B_G45): 363 BSIZE = 5 364 365 366class TestMatMPIDense_B_G77_B5(TestMatMPIDense_B_G77): 367 BSIZE = 5 368 369 370class TestMatMPIDense_B_G89_B5(TestMatMPIDense_B_G89): 371 BSIZE = 5 372 373 374# ----- 375 376if __name__ == '__main__': 377 unittest.main() 378