def _createParallelMatrix(self, f_gamma): log("Building matrix") return self._createParallelMatrixPETSc(f_gamma) product_coordinates=self.productCoordinates() n_coordinates = product_coordinates.shape[0] distribution_plan = DistributionPlan(communicator=mpi.COMM_WORLD, n_rows=product_coordinates.shape[0], n_columns=product_coordinates.shape[0]) matrix = ParallelMatrix(distribution_plan=distribution_plan) if self._mode_element_wise: for i_row in distribution_plan.localRows(): self._printProgress(n_coordinates, i_row) r_i = product_coordinates[i_row, :] for i_column in range(n_coordinates): r_j = product_coordinates[i_column, :] value = f_gamma(r_i, r_j) # TODO raise NotImplementedError("Can only handle entire rows") # matrix.setElement(i_row, i_column, value) else: for i_row in distribution_plan.localRows(): self._printProgress(len(distribution_plan.localRows()), i_row) r_i = product_coordinates[i_row, :] value = f_gamma(r_i) value = value.reshape(value.size) matrix.setRow(global_index=i_row, content=value) if distribution_plan.communicator().Get_rank() == 0: log("done") return matrix
class AutocorrelationOperator(object): def __init__(self, N_e, sigma_matrix, weighted_fields, x_coordinates, y_coordinates, k, number_modes): log("Setting up autocorrelation operator") self._action = 0 self._builder = AutocorrelationBuilder(N_e, sigma_matrix, weighted_fields, x_coordinates, y_coordinates, k, strategy=BuilderStrategyPython) self._distribution_plan = DistributionPlan(communicator=mpi.COMM_WORLD, n_columns=self.dimensionSize(), n_rows=self.dimensionSize()) log("Setting up PETSc interface") self._petSc_operator = PetScOperator(self) self._number_modes = number_modes mpi.COMM_WORLD.barrier() def numberModes(self): return self._number_modes def action(self, v): return self._builder._strategy.evaluateAllR_2_Fredholm(v) #return self._builder.evaluateAllR_2(v) def xCoordinates(self): return self._builder.xCoordinates() def yCoordinates(self): return self._builder.yCoordinates() def parrallelLinearOperator(self): return self def communicator(self): return self._distribution_plan.communicator() def parallelDot(self, v): v_in = ParallelVector(self._distribution_plan) v_in.broadcast(v, root=0) self.dot(v_in, v_in) return v_in.fullData() def dot(self, v_in, v_out=None): self._action += 1 logProgress(self._number_modes, self._action, "Fredholm operator") return self._builder._strategy.evaluateAllR_2_Fredholm_parallel(v_in, v_out) def dimensionSize(self): dimension_size = self._builder._x_coordinates.shape[0] * self._builder._y_coordinates.shape[0] return dimension_size def totalShape(self): dimension_size = self.dimensionSize() shape = (dimension_size, dimension_size) return shape def distributionPlan(self): return self._distribution_plan def __rmul__(self, scalar): return self def trace(self): return self._builder.calculateIntensity() def releaseMemory(self): pass def petScMatrix(self): context = self._petSc_operator A = PETSc.Mat().createPython([self.dimensionSize(),self.dimensionSize()], context) A.setUp() return A
class TwoformPETSc(object): def __init__(self, twoform): self._parent = twoform vector = self._parent.vector(0) self._n_size = vector.size self._petsc_matrix = PETSc.Mat().create() self._petsc_matrix.setSizes([self._n_size, self._n_size]) self._petsc_matrix.setUp() self._parallel_matrix = ParallelMatrixPETSc(self._petsc_matrix) plan = self._parallel_matrix.distributionPlan() self._parent._distribution_plan = plan self._vector_in = ParallelVector(plan) self._vector_out = ParallelVector(plan) self._distribution_plan = DistributionPlan( communicator=mpi.COMM_WORLD, n_columns=self.dimensionSize(), n_rows=self.dimensionSize()) def mult(self, A, x, y): xx = x.getArray(readonly=1) yy = y.getArray(readonly=0) yy[:] = self._1d_dot(xx) def _1d_dot(self, xx): x_2d = self.from1dTo2d(xx) result_2d = self._parent.dot(x_2d) return self.from2dTo1d(result_2d) def from1dTo2d(self, x_1d): x_2d = x_1d.reshape( (len(self.xCoordinates()), len(self.yCoordinates()))) return x_2d def from2dTo1d(self, x_2d): x_1d = x_2d.reshape( len(self.xCoordinates()) * len(self.yCoordinates())) return x_1d def xCoordinates(self): return self._parent.xCoordinates() def yCoordinates(self): return self._parent.yCoordinates() def dimensionSize(self): return self._n_size def totalShape(self): return (self._n_size, self._n_size) def trace(self): return self._parent.intensity() def petScMatrix(self): context = self A = PETSc.Mat().createPython( [self.dimensionSize(), self.dimensionSize()], context) A.setUp() return A def communicator(self): return self._distribution_plan.communicator() def distributionPlan(self): return self._distribution_plan def dot(self, v_in, v_out=None): if v_out is None: v_out = v_in v_out.broadcast(self._1d_dot(v_in.fullData()), root=0) def releaseMemory(self): pass def getVecs(self): return self._petsc_matrix.getVecs() def diagonalize(self, target_number_modes=50): print("Doing diagonalization") new_twoform = Eigenmoder(self.xCoordinates(), self.yCoordinates()).eigenmodes( self, target_number_modes) new_twoform._eigenvalues /= np.diff(self.xCoordinates())[0] * np.diff( self.yCoordinates())[0] return new_twoform
class TwoformPETSc(object): def __init__(self, twoform): self._parent = twoform vector = self._parent.vector(0) self._n_size = vector.size self._petsc_matrix = PETSc.Mat().create() self._petsc_matrix.setSizes([self._n_size, self._n_size]) self._petsc_matrix.setUp() self._parallel_matrix = ParallelMatrixPETSc(self._petsc_matrix) plan = self._parallel_matrix.distributionPlan() self._parent._distribution_plan = plan self._vector_in = ParallelVector(plan) self._vector_out = ParallelVector(plan) self._distribution_plan = DistributionPlan(communicator=mpi.COMM_WORLD, n_columns=self.dimensionSize(), n_rows=self.dimensionSize()) def mult(self, A, x, y): xx = x.getArray(readonly=1) yy = y.getArray(readonly=0) yy[:] = self._1d_dot(xx) def _1d_dot(self, xx): x_2d = self.from1dTo2d(xx) result_2d = self._parent.dot(x_2d) return self.from2dTo1d(result_2d) def from1dTo2d(self, x_1d): x_2d = x_1d.reshape((len(self.xCoordinates()), len(self.yCoordinates()))) return x_2d def from2dTo1d(self, x_2d): x_1d = x_2d.reshape(len(self.xCoordinates()) * len(self.yCoordinates())) return x_1d def xCoordinates(self): return self._parent.xCoordinates() def yCoordinates(self): return self._parent.yCoordinates() def dimensionSize(self): return self._n_size def totalShape(self): return (self._n_size, self._n_size) def trace(self): return self._parent.intensity() def petScMatrix(self): context = self A = PETSc.Mat().createPython([self.dimensionSize(),self.dimensionSize()], context) A.setUp() return A def communicator(self): return self._distribution_plan.communicator() def distributionPlan(self): return self._distribution_plan def dot(self, v_in, v_out=None): if v_out is None: v_out = v_in v_out.broadcast(self._1d_dot(v_in.fullData()), root=0) def releaseMemory(self): pass def getVecs(self): return self._petsc_matrix.getVecs() def diagonalize(self, target_number_modes=50): print("Doing diagonalization") new_twoform = Eigenmoder(self.xCoordinates(), self.yCoordinates()).eigenmodes(self, target_number_modes) new_twoform._eigenvalues /= np.diff(self.xCoordinates())[0] * np.diff(self.yCoordinates())[0] return new_twoform