Esempio n. 1
0
    def test_scatter_gather(self):
        """
        Test scattering and gathering of sparse data from and to a single MPI rank.

        The initial data distribution looks like:

               rank0           rank1           rank2           rank3
            [0, 1, 2, 3]        []              []               []

        Logically (i.e., given point coordinates and domain decomposition), 0 belongs
        to rank0, 1 belongs to rank1, etc. Thus, after scattering, the data distribution
        is expected to be:

               rank0           rank1           rank2           rank3
                [0]             [1]             [2]             [3]

        Then, locally on each rank, some trivial computation is performed, and we obtain:

               rank0           rank1           rank2           rank3
                [0]             [2]             [4]             [6]

        Finally, we gather the data values and we get:

               rank0           rank1           rank2           rank3
            [0, 2, 4, 6]        []              []              []
        """
        grid = Grid(shape=(4, 4), extent=(4.0, 4.0))

        # Initialization
        if grid.distributor.myrank == 0:
            coords = [(1., 1.), (1., 3.), (3., 1.), (3., 3.)]
        else:
            coords = []
        sf = SparseFunction(name='sf',
                            grid=grid,
                            npoint=len(coords),
                            coordinates=coords)
        sf.data[:] = list(range(len(coords)))

        # Scatter
        data = sf._dist_scatter()[sf]
        assert len(data) == 1
        assert data[0] == grid.distributor.myrank

        # Do some local computation
        data = data * 2

        # Gather
        sf._dist_gather(data)
        if grid.distributor.myrank == 0:
            assert np.all(sf.data == [0, 2, 4, 6])
        else:
            assert not sf.data
Esempio n. 2
0
    def test_scatter_gather(self):
        """
        Test scattering and gathering of sparse data from and to a single MPI rank.

        The initial data distribution (A, B, C, and D are generic values) looks like:

               rank0           rank1           rank2           rank3
                [D]             [C]             [B]             [A]

        Logically (i.e., given point coordinates and domain decomposition), A belongs
        to rank0, B belongs to rank1, etc. Thus, after scattering, the data distribution
        is expected to be:

               rank0           rank1           rank2           rank3
                [A]             [B]             [C]             [D]

        Then, locally on each rank, a trivial *2 multiplication is performed:

               rank0           rank1           rank2           rank3
               [A*2]           [B*2]           [C*2]           [D*2]

        Finally, we gather the data values and we get:

               rank0           rank1           rank2           rank3
               [D*2]           [C*2]           [B*2]           [A*2]
        """
        grid = Grid(shape=(4, 4), extent=(4.0, 4.0))

        # Initialization
        data = np.array([3, 2, 1, 0])
        coords = np.array([(3., 3.), (3., 1.), (1., 3.), (1., 1.)])
        sf = SparseFunction(name='sf',
                            grid=grid,
                            npoint=len(coords),
                            coordinates=coords)
        sf.data[:] = data

        # Scatter
        loc_data = sf._dist_scatter()[sf]
        assert len(loc_data) == 1
        assert loc_data[0] == grid.distributor.myrank

        # Do some local computation
        loc_data = loc_data * 2

        # Gather
        sf._dist_gather(loc_data)
        assert len(sf.data) == 1
        assert np.all(sf.data == data[sf.local_indices] * 2)