def test_reshape_iterable(self): d = Decomposition([[0, 1, 2], [3, 4], [5, 6, 7], [8, 9, 10, 11]], 2) assert d.reshape(()) == Decomposition([[], [], [], []], 2) assert d.reshape((1, 3, 5)) == Decomposition([[0], [1], [2], []], 2) assert d.reshape((1, 3, 10, 11)) == Decomposition([[0], [1], [], [2, 3]], 2) assert d.reshape((1, 3, 10, 11, 14)) == Decomposition([[0], [1], [], [2, 3]], 2)
def test_reshape_identity(self): d = Decomposition([[0, 1], [2, 3]], 2) # Identity decomposition assert len(d.reshape(0, 0)) == 2 assert all( list(i) == j for i, j in zip(d.reshape(0, 0), [[0, 1], [2, 3]]))
def test_reshape_left_only(self): d = Decomposition([[0, 1], [2, 3]], 2) # Extension at left only assert len(d.reshape(2, 0)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(2, 0), [[0, 1, 2, 3], [4, 5]])) # Reduction at left affecting one sub-domain only, but not the whole subdomain assert len(d.reshape(-1, 0)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(-1, 0), [[0], [1, 2]])) # Reduction at left over one whole sub-domain assert len(d.reshape(-2, 0)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(-2, 0), [[], [0, 1]])) # Reduction at right over multiple sub-domains assert len(d.reshape(-3, 0)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(-3, 0), [[], [0]]))
def test_reshape_right_only(self): d = Decomposition([[0, 1], [2, 3]], 2) # Extension at right only assert len(d.reshape(0, 2)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(0, 2), [[0, 1], [2, 3, 4, 5]])) # Reduction at right affecting one sub-domain only, but not the whole subdomain assert len(d.reshape(0, -1)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(0, -1), [[0, 1], [2]])) # Reduction at right over one whole sub-domain assert len(d.reshape(0, -2)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(0, -2), [[0, 1], []])) # Reduction at right over multiple sub-domains assert len(d.reshape(0, -3)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(0, -3), [[0], []]))
def __init__(self, npoint, dimension, distributor): super(SparseDistributor, self).__init__(npoint, dimension) self._distributor = distributor # The dimension decomposition decomposition = SparseDistributor.decompose(npoint, distributor) offs = np.concatenate([[0], np.cumsum(decomposition)]) self._decomposition = [Decomposition([np.arange(offs[i], offs[i+1]) for i in range(self.nprocs)], self.myrank)]
def test_reshape_slice(self): d = Decomposition([[0, 1, 2], [3, 4], [5, 6, 7], [8, 9, 10, 11]], 2) assert d.reshape(slice(None)) == d assert d.reshape(slice(2, 9)) == Decomposition([[0], [1, 2], [3, 4, 5], [6]], 2) assert d.reshape(slice(3, 5)) == Decomposition([[], [0, 1], [], []], 2) assert d.reshape(slice(3, 3)) == Decomposition([[], [], [], []], 2) assert d.reshape(slice(13, 13)) == Decomposition([[], [], [], []], 2) assert d.reshape(slice(2, None)) == Decomposition([[0], [1, 2], [3, 4, 5], [6, 7, 8, 9]], 2) assert d.reshape(slice(4)) == Decomposition([[0, 1, 2], [3], [], []], 2) assert d.reshape(slice(-2, 2)) == Decomposition([[0, 1, 2, 3], [], [], []], 2) assert d.reshape(slice(-2)) == Decomposition([[0, 1, 2], [3, 4], [5, 6, 7], [8, 9]], 2) assert d.reshape(slice(3, -1)) == Decomposition([[], [0, 1], [2, 3, 4], [5, 6, 7]], 2)
def test_convert_index(self): d = Decomposition([[0, 1, 2], [3, 4], [5, 6, 7], [8, 9, 10, 11]], 2) # A global index as single argument assert d.convert_index(5) == 0 assert d.convert_index(6) == 1 assert d.convert_index(7) == 2 assert d.convert_index(3) is None # Retrieve relative local min/man given global min/max assert d.convert_index((5, 7)) == (0, 2) assert d.convert_index((5, 9)) == (0, 2) assert d.convert_index((1, 3)) == (-1, -3) assert d.convert_index((1, 6)) == (0, 1) assert d.convert_index((None, None)) == (0, 2) # Retrieve absolute local min/man given global min/max assert d.convert_index((5, 7), rel=False) == (5, 7) assert d.convert_index((5, 9), rel=False) == (5, 7) assert d.convert_index((1, 3), rel=False) == (-1, -3) assert d.convert_index((1, 6), rel=False) == (5, 6) assert d.convert_index((None, None), rel=False) == (5, 7)
def __init__(self, shape, dimensions, input_comm=None, topology=None): super(Distributor, self).__init__(shape, dimensions) if configuration['mpi']: # First time we enter here, we make sure MPI is initialized if not MPI.Is_initialized(): MPI.Init() global init_by_devito init_by_devito = True self._input_comm = (input_comm or MPI.COMM_WORLD).Clone() # Make sure the cloned communicator will be freed up upon exit def cleanup(): if self._input_comm is not None: self._input_comm.Free() atexit.register(cleanup) if topology is None: # `MPI.Compute_dims` sets the dimension sizes to be as close to each other # as possible, using an appropriate divisibility algorithm. Thus, in 3D: # * topology[0] >= topology[1] >= topology[2] # * topology[0] * topology[1] * topology[2] == self._input_comm.size # However, `MPI.Compute_dims` is distro-dependent, so we have to enforce # some properties through our own wrapper (e.g., OpenMPI v3 does not # guarantee that 9 ranks are arranged into a 3x3 grid when shape=(9, 9)) self._topology = compute_dims(self._input_comm.size, len(shape)) else: self._topology = topology if self._input_comm is not input_comm: # By default, Devito arranges processes into a cartesian topology. # MPI works with numbered dimensions and follows the C row-major # numbering of the ranks, i.e. in a 2x3 Cartesian topology (0,0) # maps to rank 0, (0,1) maps to rank 1, (0,2) maps to rank 2, (1,0) # maps to rank 3, and so on. self._comm = self._input_comm.Create_cart(self._topology) else: self._comm = input_comm else: self._input_comm = None self._comm = MPI.COMM_NULL self._topology = tuple(1 for _ in range(len(shape))) # The domain decomposition self._decomposition = [ Decomposition(np.array_split(range(i), j), c) for i, j, c in zip(shape, self.topology, self.mycoords) ]
def test_reshape_left_right(self): d = Decomposition([[0, 1], [2, 3]], 2) # Extension at both left and right assert len(d.reshape(1, 1)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(1, 1), [[0, 1, 2], [3, 4, 5]])) # Reduction at both left and right assert len(d.reshape(-1, -1)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(-1, -1), [[0], [1]])) # Reduction at both left and right, with the right one obliterating one subdomain assert len(d.reshape(-1, -2)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(-1, -2), [[0], []])) # Reduction at both left and right obliterating all subdomains # triggering an exception assert len(d.reshape(-1, -3)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(-1, -3), [[], []])) assert len(d.reshape(-2, -2)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(-1, -3), [[], []]))
def test_reshape_identity(self): d = Decomposition([[0, 1], [2, 3]], 2) # Identity decomposition assert len(d.reshape(0, 0)) == 2 assert all(list(i) == j for i, j in zip(d.reshape(0, 0), [[0, 1], [2, 3]]))