xref: /petsc/src/binding/petsc4py/test/test_mat_dense.py (revision dbb0007b940a1b26670b8b6f28bdc72b8ef8ca02)
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