Example #1
0
    def test_get_block_vector_for_dot_product_3(self):
        rank = comm.Get_rank()

        rank_ownership = np.array([[1, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]])
        m = MPIBlockMatrix(4, 3, rank_ownership, comm)
        sub_m = np.array([[1, 0], [0, 1]])
        sub_m = coo_matrix(sub_m)
        if rank == 0:
            m.set_block(3, rank, sub_m.copy())
        elif rank == 1:
            m.set_block(0, 0, sub_m.copy())
            m.set_block(rank, rank, sub_m.copy())
            m.set_block(3, rank, sub_m.copy())
        else:
            m.set_block(rank, rank, sub_m.copy())
            m.set_block(3, rank, sub_m.copy())

        rank_ownership = np.array([0, 1, 2])
        v = MPIBlockVector(3, rank_ownership, comm)
        sub_v = np.ones(2)
        v.set_block(rank, sub_v.copy())

        res = m._get_block_vector_for_dot_product(v)

        self.assertIsNot(res, v)
        self.assertTrue(np.array_equal(res.get_block(0), sub_v))
        if rank == 0:
            self.assertIsNone(res.get_block(1))
            self.assertIsNone(res.get_block(2))
        elif rank == 1:
            self.assertTrue(np.array_equal(res.get_block(1), sub_v))
            self.assertIsNone(res.get_block(2))
        elif rank == 2:
            self.assertTrue(np.array_equal(res.get_block(2), sub_v))
            self.assertIsNone(res.get_block(1))
Example #2
0
    def test_get_block_vector_for_dot_product_4(self):
        rank = comm.Get_rank()

        rank_ownership = np.array([[-1, 1, 2],
                                   [0, 1, 2],
                                   [0, 1, 2],
                                   [0, 1, 2]])
        m = MPIBlockMatrix(4, 3, rank_ownership, comm)
        sub_m = np.array([[1, 0],
                          [0, 1]])
        sub_m = coo_matrix(sub_m)
        m.set_block(0, 0, sub_m.copy())
        if rank == 0:
            m.set_block(3, rank, sub_m.copy())
        else:
            m.set_block(rank, rank, sub_m.copy())
            m.set_block(3, rank, sub_m.copy())

        rank_ownership = np.array([0, 1, 2])
        v = MPIBlockVector(3, rank_ownership, comm)
        sub_v = np.ones(2)
        v.set_block(rank, sub_v.copy())

        res = m._get_block_vector_for_dot_product(v)

        self.assertIs(res, v)
Example #3
0
    def test_dot(self):

        mat1 = self.square_mpi_mat
        mat2 = self.square_mpi_mat2

        serial_mat1 = self.square_serial_mat
        serial_mat2 = self.square_serial_mat2

        rank = comm.Get_rank()

        bv1 = MPIBlockVector(2, [0, 1], comm)

        if rank == 0:
            bv1.set_block(0, np.arange(4, dtype=np.float64))
        if rank == 1:
            bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)
        bv1.broadcast_block_sizes()

        serial_bv1 = BlockVector(2)
        serial_bv1.set_block(0, np.arange(4, dtype=np.float64))
        serial_bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)

        res = mat1.dot(bv1)
        serial_res = serial_mat1.dot(serial_bv1)
        self.assertIsInstance(res, BlockVector)
        self.assertEqual(res.nblocks, serial_res.nblocks)
        for bid in range(serial_res.nblocks):
            self.assertTrue(
                np.allclose(res.get_block(bid), serial_res.get_block(bid)))
Example #4
0
    def test_matvec_1(self):
        rank = comm.Get_rank()

        rank_ownership = np.array([[0, -1, -1, 0],
                                   [-1, 1, -1, 1],
                                   [-1, -1, 2, 2],
                                   [0, 1, 2, -1]])
        m = MPIBlockMatrix(4, 4, rank_ownership, comm)
        sub_m = np.array([[1, 0],
                          [0, 1]])
        sub_m = coo_matrix(sub_m)
        m.set_block(rank, rank, sub_m.copy())
        m.set_block(rank, 3, sub_m.copy())
        m.set_block(3, rank, sub_m.copy())
        m.set_block(3, 3, sub_m.copy())
        m.broadcast_block_sizes()

        rank_ownership = np.array([0, 1, 2, -1])
        v = MPIBlockVector(4, rank_ownership, comm)
        sub_v = np.ones(2)
        v.set_block(rank, sub_v.copy())
        v.set_block(3, sub_v.copy())
        v.broadcast_block_sizes()

        res = m.dot(v)
        self.assertIsInstance(res, MPIBlockVector)
        self.assertTrue(np.array_equal(res.get_block(rank), sub_v*2))
        self.assertTrue(np.array_equal(res.get_block(3), sub_v*4))
        self.assertTrue(np.array_equal(res.rank_ownership, np.array([0, 1, 2, -1])))
        self.assertFalse(res.has_none)
Example #5
0
def main():
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()
    
    owners = [0, 1, 2, -1]
    x = MPIBlockVector(4, rank_owner=owners, mpi_comm=comm)
    
    owners = np.array([[ 0, -1, -1, 0],
                       [-1,  1, -1, 1],
                       [-1, -1,  2, 2]])
    a = MPIBlockMatrix(3, 4, rank_ownership=owners, mpi_comm=comm)
    
    np.random.seed(0)
    x.set_block(3, np.random.uniform(-10, 10, size=10))
    
    np.random.seed(rank)
    x.set_block(rank, np.random.uniform(-10, 10, size=10))
    a.set_block(rank, rank, random(10, 10, density=0.1))
    a.set_block(rank, 3, random(10, 10, density=0.1))
    
    b = a * x  # parallel matrix-vector dot product
    
    # check the answer
    local_x = x.make_local_copy().flatten()
    local_a = a.to_local_array()
    local_b = b.make_local_copy().flatten()
    
    err = np.abs(local_a.dot(local_x) - local_b).max()

    if rank == 0:
        print('error: ', err)

    return err
Example #6
0
 def _build_mpi_block_vector(self,
                             extra_block: bool = False) -> MPIBlockVector:
     if extra_block:
         n = self._num_time_blocks + 1
     else:
         n = self._num_time_blocks
     rank_ownership = -1 * np.ones(n, dtype=np.int64)
     for ndx in range(self._num_time_blocks):
         rank_ownership[ndx] = self._ownership_map[ndx]
     vec = MPIBlockVector(nblocks=n,
                          rank_owner=rank_ownership,
                          mpi_comm=self._comm)
     return vec
    def test_mpi_schur_complement(self):
        rank_by_index = list()
        for ndx in range(3):
            for _rank in range(size):
                if (ndx - _rank) % size == 0:
                    rank_by_index.append(_rank)
        rank_by_index.append(-1)

        A = MPIBlockMatrix(nbrows=4,
                           nbcols=4,
                           rank_ownership=[
                               rank_by_index, rank_by_index, rank_by_index,
                               rank_by_index
                           ],
                           mpi_comm=comm)
        if rank_by_index[0] == rank:
            A.set_block(
                0, 0, coo_matrix(np.array([[1, 1], [0, 1]], dtype=np.double)))
        if rank_by_index[1] == rank:
            A.set_block(
                1, 1, coo_matrix(np.array([[1, 0], [0, 1]], dtype=np.double)))
        if rank_by_index[2] == rank:
            A.set_block(
                2, 2, coo_matrix(np.array([[1, 0], [1, 1]], dtype=np.double)))
        A.set_block(3, 3,
                    coo_matrix(np.array([[0, 0], [0, 1]], dtype=np.double)))
        if rank_by_index[0] == rank:
            A.set_block(
                3, 0, coo_matrix(np.array([[0, -1], [0, 0]], dtype=np.double)))
        if rank_by_index[1] == rank:
            A.set_block(
                3, 1, coo_matrix(np.array([[-1, 0], [0, -1]],
                                          dtype=np.double)))
        if rank_by_index[2] == rank:
            A.set_block(
                3, 2, coo_matrix(np.array([[0, 0], [-1, 0]], dtype=np.double)))
        A.broadcast_block_sizes()

        local_A = BlockMatrix(4, 4)
        local_A.set_block(
            0, 0, coo_matrix(np.array([[1, 1], [0, 1]], dtype=np.double)))
        local_A.set_block(
            1, 1, coo_matrix(np.array([[1, 0], [0, 1]], dtype=np.double)))
        local_A.set_block(
            2, 2, coo_matrix(np.array([[1, 0], [1, 1]], dtype=np.double)))
        local_A.set_block(
            3, 3, coo_matrix(np.array([[0, 0], [0, 1]], dtype=np.double)))
        local_A.set_block(
            3, 0, coo_matrix(np.array([[0, -1], [0, 0]], dtype=np.double)))
        local_A.set_block(
            3, 1, coo_matrix(np.array([[-1, 0], [0, -1]], dtype=np.double)))
        local_A.set_block(
            3, 2, coo_matrix(np.array([[0, 0], [-1, 0]], dtype=np.double)))
        local_A.set_block(0, 3, local_A.get_block(3, 0).transpose(copy=True))
        local_A.set_block(1, 3, local_A.get_block(3, 1).transpose(copy=True))
        local_A.set_block(2, 3, local_A.get_block(3, 2).transpose(copy=True))

        rhs = MPIBlockVector(nblocks=4,
                             rank_owner=rank_by_index,
                             mpi_comm=comm)
        if rank_by_index[0] == rank:
            rhs.set_block(0, np.array([1, 0], dtype=np.double))
        if rank_by_index[1] == rank:
            rhs.set_block(1, np.array([0, 0], dtype=np.double))
        if rank_by_index[2] == rank:
            rhs.set_block(2, np.array([0, 1], dtype=np.double))
        rhs.set_block(3, np.array([1, 1], dtype=np.double))
        rhs.broadcast_block_sizes()

        local_rhs = BlockVector(4)
        local_rhs.set_block(0, np.array([1, 0], dtype=np.double))
        local_rhs.set_block(1, np.array([0, 0], dtype=np.double))
        local_rhs.set_block(2, np.array([0, 1], dtype=np.double))
        local_rhs.set_block(3, np.array([1, 1], dtype=np.double))

        x1 = np.linalg.solve(local_A.toarray(), local_rhs.flatten())

        solver_class = parapint.linalg.MPISchurComplementLinearSolver
        sc_solver = solver_class(
            subproblem_solvers={
                ndx: ScipyInterface(compute_inertia=True)
                for ndx in range(3)
            },
            schur_complement_solver=ScipyInterface(compute_inertia=True))
        sc_solver.do_symbolic_factorization(A)
        sc_solver.do_numeric_factorization(A)
        x2 = sc_solver.do_back_solve(rhs)

        self.assertTrue(np.allclose(x1, x2.make_local_copy().flatten()))

        inertia1 = sc_solver.get_inertia()
        eig = np.linalg.eigvals(local_A.toarray())
        pos = np.count_nonzero(eig > 0)
        neg = np.count_nonzero(eig < 0)
        zero = np.count_nonzero(eig == 0)
        inertia2 = (pos, neg, zero)
        self.assertEqual(inertia1, inertia2)

        sc_solver.do_numeric_factorization(A)
        x2 = sc_solver.do_back_solve(rhs)
        self.assertTrue(np.allclose(x1, x2.make_local_copy().flatten()))
Example #8
0
    def test_mul(self):

        mat1 = self.square_mpi_mat
        mat2 = self.square_mpi_mat2

        serial_mat1 = self.square_serial_mat
        serial_mat2 = self.square_serial_mat2

        rank = comm.Get_rank()

        bv1 = MPIBlockVector(2, [0, 1], comm)

        if rank == 0:
            bv1.set_block(0, np.arange(4, dtype=np.float64))
        if rank == 1:
            bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)
        bv1.broadcast_block_sizes()

        serial_bv1 = BlockVector(2)
        serial_bv1.set_block(0, np.arange(4, dtype=np.float64))
        serial_bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)

        res = mat1 * bv1
        serial_res = serial_mat1 * serial_bv1
        self.assertIsInstance(res, BlockVector)
        self.assertEqual(res.nblocks, serial_res.nblocks)
        for bid in range(serial_res.nblocks):
            self.assertTrue(
                np.allclose(res.get_block(bid), serial_res.get_block(bid)))

        res = mat2 * bv1
        serial_res = serial_mat2 * serial_bv1
        self.assertIsInstance(res, BlockVector)
        self.assertEqual(res.nblocks, serial_res.nblocks)
        for bid in range(serial_res.nblocks):
            self.assertTrue(
                np.allclose(res.get_block(bid), serial_res.get_block(bid)))

        bv1 = MPIBlockVector(2, [0, -1], comm)

        if rank == 0:
            bv1.set_block(0, np.arange(4, dtype=np.float64))
        bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)
        bv1.broadcast_block_sizes()

        res = mat1 * bv1
        serial_res = serial_mat1 * serial_bv1
        self.assertIsInstance(res, BlockVector)
        self.assertEqual(res.nblocks, serial_res.nblocks)
        for bid in range(serial_res.nblocks):
            self.assertTrue(
                np.allclose(res.get_block(bid), serial_res.get_block(bid)))

        res = mat2 * bv1
        serial_res = serial_mat2 * serial_bv1
        self.assertIsInstance(res, BlockVector)
        self.assertEqual(res.nblocks, serial_res.nblocks)
        for bid in range(serial_res.nblocks):
            self.assertTrue(
                np.allclose(res.get_block(bid), serial_res.get_block(bid)))

        # rectangular matrix
        mat1 = self.rectangular_mpi_mat
        serial_mat1 = self.rectangular_serial_mat

        bv1 = MPIBlockVector(3, [0, 1, 2], comm)

        if rank == 0:
            bv1.set_block(0, np.arange(4, dtype=np.float64))
        if rank == 1:
            bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)
        if rank == 2:
            bv1.set_block(2, np.arange(2, dtype=np.float64) + 8)

        bv1.broadcast_block_sizes()

        serial_bv1 = BlockVector(3)
        serial_bv1.set_block(0, np.arange(4, dtype=np.float64))
        serial_bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)
        serial_bv1.set_block(2, np.arange(2, dtype=np.float64) + 8)

        # with warnings.catch_warnings():
        #     warnings.simplefilter("ignore")
        res = mat1 * bv1
        serial_res = serial_mat1 * serial_bv1

        self.assertIsInstance(res, BlockVector)
        self.assertEqual(serial_res.nblocks, 2)
        self.assertEqual(res.nblocks, 2)
        for bid in range(serial_res.nblocks):
            self.assertTrue(
                np.allclose(res.get_block(bid), serial_res.get_block(bid)))

        bv1 = MPIBlockVector(3, [0, 1, 0], comm)

        if rank == 0:
            bv1.set_block(0, np.arange(4, dtype=np.float64))
            bv1.set_block(2, np.arange(2, dtype=np.float64) + 8)
        if rank == 1:
            bv1.set_block(1, np.arange(4, dtype=np.float64) + 4)
        bv1.broadcast_block_sizes()

        res = mat1 * bv1
        serial_res = serial_mat1 * serial_bv1
        self.assertIsInstance(res, BlockVector)
        self.assertEqual(res.nblocks, serial_res.nblocks)
        for bid in range(serial_res.nblocks):
            self.assertTrue(
                np.allclose(res.get_block(bid), serial_res.get_block(bid)))

        res = mat1 * 3.0
        serial_res = serial_mat1 * 3.0
        self.assertIsInstance(res, MPIBlockMatrix)
        rows, columns = np.nonzero(res.ownership_mask)
        for i, j in zip(rows, columns):
            if res.get_block(i, j) is not None:
                self.assertTrue(
                    np.allclose(
                        res.get_block(i, j).toarray(),
                        serial_res.get_block(i, j).toarray()))
            else:
                self.assertIsNone(serial_res.get_block(i, j))

        res = 3.0 * mat1
        serial_res = serial_mat1 * 3.0

        self.assertIsInstance(res, MPIBlockMatrix)
        rows, columns = np.nonzero(res.ownership_mask)
        for i, j in zip(rows, columns):
            if res.get_block(i, j) is not None:
                self.assertTrue(
                    np.allclose(
                        res.get_block(i, j).toarray(),
                        serial_res.get_block(i, j).toarray()))
            else:
                self.assertIsNone(serial_res.get_block(i, j))
Example #9
0
def main():
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()

    owners = [2, 0, 1, -1]
    x = MPIBlockVector(4, rank_owner=owners, mpi_comm=comm)
    x.set_block(owners.index(rank), np.ones(3) * (rank + 1))
    x.set_block(3, np.array([1, 2, 3]))

    y = MPIBlockVector(4, rank_owner=owners, mpi_comm=comm)
    y.set_block(owners.index(rank), np.ones(3) * (rank + 1))
    y.set_block(3, np.array([1, 2, 3]))

    z1: MPIBlockVector = x + y  # add x and y
    z2 = x.dot(y)  # dot product
    z3 = np.abs(x).max()  # infinity norm

    z1_local = z1.make_local_copy()
    if rank == 0:
        print(z1_local.flatten())
        print(z2)
        print(z3)

    return z1_local, z2, z3