def max(self, generator, postprocessor=None): if postprocessor is None: def postprocessor(value): return value if self.distributed_max: local_list_indices = list( range(self.mpi_comm.rank, len(self._list), self.mpi_comm.size)) # start from index rank and take steps of length equal to size else: local_list_indices = list(range(len(self._list))) values = array(len(local_list_indices)) values_with_postprocessing = array(len(local_list_indices)) for i in range(len(local_list_indices)): values[i] = generator(self._list[local_list_indices[i]]) values_with_postprocessing[i] = postprocessor(values[i]) if self.distributed_max: local_i_max = argmax(values_with_postprocessing) local_value_max = values[local_i_max] (global_value_max, global_i_max) = parallel_max(local_value_max, local_list_indices[local_i_max], postprocessor, self.mpi_comm) assert isinstance(global_i_max, tuple) assert len(global_i_max) == 1 global_i_max = global_i_max[0] else: global_i_max = argmax(values_with_postprocessing) global_value_max = values[global_i_max] return (global_value_max, global_i_max)
def _abs(vector: Vector.Type()): # Note: PETSc offers VecAbs and VecMax, but for symmetry with the matrix case we do the same by hand vec = to_petsc4py(vector) row_start, row_end = vec.getOwnershipRange() i_max = None value_max = None for i in range(row_start, row_end): val = vec.getValue(i) if value_max is None or fabs(val) > fabs(value_max): i_max = i value_max = val assert i_max is not None assert value_max is not None # mpi_comm = vec.comm.tompi4py() (global_value_max, global_i_max) = parallel_max(value_max, (i_max, ), fabs, mpi_comm) return AbsOutput(global_value_max, global_i_max)
def _abs(matrix: Matrix.Type()): # Note: PETSc offers a method MatGetRowMaxAbs, but it is not wrapped in petsc4py. We do the same by hand mat = to_petsc4py(matrix) row_start, row_end = mat.getOwnershipRange() i_max, j_max = None, None value_max = None for i in range(row_start, row_end): cols, vals = mat.getRow(i) for (c, v) in zip(cols, vals): if value_max is None or fabs(v) > fabs(value_max): i_max = i j_max = c value_max = v assert i_max is not None assert j_max is not None assert value_max is not None # mpi_comm = mat.comm.tompi4py() (global_value_max, global_ij_max) = parallel_max(value_max, (i_max, j_max), fabs, mpi_comm) return AbsOutput(global_value_max, global_ij_max)