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
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)