def test_approximate_symmetric_svd(self): """Compute the SVD of symmetric **A** such that **SVD(A) = V S V^T**""" n = 100 A = El.DistMatrix() El.Uniform(A, n, n) A = A.Matrix() # Make A symmetric for i in xrange(0, A.Height()): for j in xrange(0, i + 1): A.Set(j, i, A.Get(i, j)) # Usign symmetric SVD SA = El.Matrix() VA = El.Matrix() sl_nla.approximate_symmetric_svd(A, SA, VA, k=n) # Check result VAT = El.Matrix() El.Copy(VA, VAT) RESULT = El.Matrix() El.Zeros(RESULT, n, n) El.DiagonalScale(El.RIGHT, El.NORMAL, SA, VAT) El.Gemm(El.NORMAL, El.ADJOINT, 1, VAT, VA, 1, RESULT) self.assertTrue(utils.equal(A, RESULT))
def test_helper(A, M, N, R, sketch, measures, MPI, num_repeats=5, direction="columnwise"): """ Test if the singular values of the original (M x N) and sketched matrix (R x N) are fulfilling some measurement criteria. The test is repeated num_repeats times. """ results = [] for i in range(num_repeats): if direction == "columnwise": S = sketch(M, R) SA = El.DistMatrix(El.dTag, El.STAR, El.STAR) El.Uniform(SA, R, N) else: S = sketch(N, R) SA = El.DistMatrix(El.dTag, El.STAR, El.STAR) El.Uniform(SA, M, R) S.apply(A, SA, direction) for m in measures: results.append(m(SA.Matrix().ToNumPy())) return results
def _read_elemental_dense(self, colDist=El.MC, rowDist=El.MR): comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() # only the root process touches the filesystem if rank == 0: f = h5py.File(self.fpath, 'r') dataset_obj = f[self.dataset] shape = dataset_obj.shape if rank == 0 else None shape = comm.bcast(shape, root=0) height = shape[0] width = shape[1] num_entries = height * width # max memory capacity per process assumed/hardcoded to 10 blocks # XXX should this number be passed as a parameter? max_blocks_per_process = 10 max_block_entries = int( (1.0 * num_entries) / (max_blocks_per_process * size)) # XXX We could set up a different block generating scheme, e.g. more # square-ish blocks block_height = int(numpy.sqrt(max_block_entries)) while max_block_entries % block_height != 0: block_height = block_height + 1 block_width = max_block_entries / block_height num_height_blocks = int(numpy.ceil(height / (1.0 * block_height))) num_width_blocks = int(numpy.ceil(width / (1.0 * block_width))) num_blocks = num_height_blocks * num_width_blocks A = El.DistMatrix(colDist=colDist, rowDist=rowDist) for block in range(num_blocks): # the global coordinates of the block corners i_start = (block / num_width_blocks) * block_height j_start = (block % num_width_blocks) * block_width i_end = min(height, i_start + block_height) j_end = min(width, j_start + block_width) # the block size local_height = i_end - i_start local_width = j_end - j_start # [CIRC, CIRC] matrix is populated by the reader process (i.e. the root)... A_block = El.DistMatrix(colDist=El.CIRC, rowDist=El.CIRC) A_block.Resize(local_height, local_width) if rank == 0: for j in range(j_start, j_end): for i in range(i_start, i_end): A_block.SetLocal(i - i_start, j - j_start, dataset_obj[i, j]) # ... then a view into the full matrix A is constructed... A_block_view = A[i_start:i_end, j_start:j_end] # ... and finally this view is updated by redistribution of the [CIRC, CIRC] block El.Copy(A_block, A_block_view) if rank == 0: f.close() return A
def Constraints(numRows, N0, N1): B = El.SparseMatrix() El.Zeros(B, numRows, N0 * N1) B.Reserve(numRows * N0 * N1) for s in xrange(numRows): for j in xrange(N0 * N1): B.QueueUpdate(s, j, random.uniform(0, 1)) B.ProcessQueues() return B
def CreateExpected(height): c = El.DistMultiVec() #Zeros( c, height, 1 ) #localHeight = c.LocalHeight() #for iLoc in xrange(localHeight): # i = c.GlobalRow(iLoc) # c.SetLocal(iLoc,0,1.+1./i) El.Gaussian(c, height, 1) return c
def test_approximate_svd(self): """Compute the SVD of **A** such that **SVD(A) = U S V^T**.""" n = 100 # Generate random matrix A = El.DistMatrix() El.Uniform(A, n, n) A = A.Matrix() # Dimension to apply along. k = n U = El.Matrix() S = El.Matrix() V = El.Matrix() sl_nla.approximate_svd(A, U, S, V, k=k) # Check result RESULT = El.Matrix() El.Zeros(RESULT, n, n) El.DiagonalScale(El.RIGHT, El.NORMAL, S, U) El.Gemm(El.NORMAL, El.ADJOINT, 1, U, V, 1, RESULT) self.assertTrue(utils.equal(A, RESULT))
def _write_elemental_dense(self, A): comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() # XXX currently gathers at root A_CIRC_CIRC = El.DistMatrix(colDist=El.CIRC, rowDist=El.CIRC) El.Copy(A, A_CIRC_CIRC) if rank == 0: A_numpy_dense = A_CIRC_CIRC.Matrix().ToNumPy() self._write_numpy_dense(A_numpy_dense)
def CreateExpected(height): c = El.DistMultiVec() #Zeros( c, height, 1 ) #localHeight = c.LocalHeight() #for iLoc in xrange(localHeight): # i = c.GlobalRow(iLoc) # c.SetLocal(iLoc,0,1.+1./i) El.Gaussian( c, height, 1 ) El.EntrywiseMap( c, lambda alpha : abs(alpha) ) return c
def Constraints(numRows, N0, N1): B = El.DistSparseMatrix() El.Zeros(B, numRows, N0 * N1) localHeight = B.LocalHeight() B.Reserve(localHeight * N0 * N1) for sLoc in xrange(localHeight): s = B.GlobalRow(sLoc) for j in xrange(N0 * N1): B.QueueLocalUpdate(sLoc, j, random.uniform(0, 1)) B.MakeConsistent() return B
def load_libsvm_file(fpath, col_row): """ Read from a libsv file :param fpath: path of the file :param col_row: 0 to read in col mode, 1 to read in row mode :returns: Returns X, Y matrices """ # Read the data X = El.DistMatrix() Y = El.DistMatrix() return sl_io.readlibsvm(fpath, X, Y, 0)
def Constraints(numCols, N0, N1): B = El.DistSparseMatrix() El.Zeros(B, N0 * N1, numCols) localHeight = B.LocalHeight() B.Reserve(localHeight * numCols) for sLoc in xrange(localHeight): s = B.GlobalRow(sLoc) for j in xrange(numCols): B.QueueLocalUpdate(sLoc, j, random.uniform(0, 1)) B.ProcessQueues() return B
def RectangSparse(height,width): A = El.DistMatrix() El.Zeros( A, height, width ) for s in xrange(height): if s < width: A.Update( s, s, 11 ) if s >= 1 and s-1 < width: A.Update( s, s-1, -1 ) if s+1 < width: A.Update( s, s+1, 2 ) if s >= height and s-height < width: A.Update( s, s-height, -3 ) if s+height < width: A.Update( s, s+height, 4 ) # The dense last column A.Update( s, width-1, -5/height ); return A
def test_apply_colwise(self): A = El.DistMatrix(El.dTag, El.VR, El.STAR) #FIXME: Christos, use your matrix problem factory here El.Uniform(A, _M, _N) #FIXME: A.Matrix will not work in parallel self.sv = np.linalg.svd(A.Matrix().ToNumPy(), full_matrices=1, compute_uv=0) for sketch in self.sketches: results = test_helper(A, _M, _N, _R, sketch, [self.svd_bound], MPI) self.check_result(results, str(sketch))
def ConcatFD2D(N0, N1): A = El.DistSparseMatrix() height = N0 * N1 width = 2 * N0 * N1 A.Resize(height, width) localHeight = A.LocalHeight() A.Reserve(7 * localHeight) for sLoc in xrange(localHeight): s = A.GlobalRow(sLoc) x0 = s % N0 x1 = s / N0 # The finite-difference stencil A.QueueLocalUpdate(sLoc, s, 15) if x0 > 0: A.QueueLocalUpdate(sLoc, s - 1, -1) if x0 + 1 < N0: A.QueueLocalUpdate(sLoc, s + 1, 2) if x1 > 0: A.QueueLocalUpdate(sLoc, s - N0, -3) if x1 + 1 < N1: A.QueueLocalUpdate(sLoc, s + N0, 4) # The identity sRel = s + N0 * N1 A.QueueLocalUpdate(sLoc, sRel, 1) # The dense last column A.QueueLocalUpdate(sLoc, width - 1, -10 / height) A.ProcessQueues() return A
def ConcatFD2D(N0, N1): A = El.DistSparseMatrix() height = N0 * N1 width = 2 * N0 * N1 A.Resize(height, width) localHeight = A.LocalHeight() A.Reserve(11 * localHeight) for sLoc in xrange(localHeight): s = A.GlobalRow(sLoc) x0 = s % N0 x1 = s / N0 sRel = s + N0 * N1 A.QueueUpdate(s, s, 11) A.QueueUpdate(s, sRel, -20) if x0 > 0: A.QueueUpdate(s, s - 1, -1) A.QueueUpdate(s, sRel - 1, -17) if x0 + 1 < N0: A.QueueUpdate(s, s + 1, 2) A.QueueUpdate(s, sRel + 1, -20) if x1 > 0: A.QueueUpdate(s, s - N0, -30) A.QueueUpdate(s, sRel - N0, -3) if x1 + 1 < N1: A.QueueUpdate(s, s + N0, 4) A.QueueUpdate(s, sRel + N0, 3) # The dense last column #A.QueueUpdate( s, width-1, -10/height ); A.ProcessLocalQueues() return A
def FD2D(N0, N1): A = El.DistSparseMatrix() height = N0 * N1 width = N0 * N1 A.Resize(height, width) localHeight = A.LocalHeight() A.Reserve(6 * localHeight) for sLoc in xrange(localHeight): s = A.GlobalRow(sLoc) x0 = s % N0 x1 = s / N0 A.QueueLocalUpdate(sLoc, s, 11) if x0 > 0: A.QueueLocalUpdate(sLoc, s - 1, -1) if x0 + 1 < N0: A.QueueLocalUpdate(sLoc, s + 1, 2) if x1 > 0: A.QueueLocalUpdate(sLoc, s - N0, -3) if x1 + 1 < N1: A.QueueLocalUpdate(sLoc, s + N0, 4) # The dense last column A.QueueLocalUpdate(sLoc, width - 1, -10 / height) A.ProcessQueues() return A
def CreateFactor(height,width): F = El.DistSparseMatrix() El.Zeros( F, height, width ) localHeight = F.LocalHeight() F.Reserve(localHeight*width) for iLoc in xrange(localHeight): i = F.GlobalRow(iLoc) for j in xrange(width): F.QueueLocalUpdate( iLoc, j, math.log(i+j+1.) ) F.ProcessQueues() # NOTE: Without this rescaling, the problem is much harder, as the variables # s becomes quite large # (|| F^T x ||_2 <= u, u^2 <= t, would imply u and t are large). FFrob = El.FrobeniusNorm( F ) El.Scale( 1./FFrob, F ) return F
def test_ExpSemiGroup_kernel(self): """Test ExpSemiGroup kernel.""" X, Y = sl_test_utils.load_libsvm_file(fpath, 0) K = El.DistMatrix() ExpSemiGroup_kernel = sl_kernels.ExpSemiGroup(X.Height(), 0.1) ExpSemiGroup_kernel.gram(X, K, 0, 0) self.assertTrue(sl_test_utils.is_kernel(K))
def test_Laplacian_kernel(self): """Test Laplacian kernel.""" X, Y = sl_test_utils.load_libsvm_file(fpath, 0) K = El.DistMatrix() Laplacian_kernel = sl_kernels.Laplacian(X.Height(), 2.0) Laplacian_kernel.gram(X, K, 0, 0) self.assertTrue(sl_test_utils.is_kernel(K))
def test_Polynomial_kernel(self): """Test Polynomial kernel.""" X, Y = sl_test_utils.load_libsvm_file(fpath, 0) K = El.DistMatrix() Polynomial_kernel = sl_kernels.Polynomial(X.Height(), 1, 1, 1) Polynomial_kernel.gram(X, K, 0, 0) self.assertTrue(sl_test_utils.is_kernel(K, positive=False))
def test_Linear_kernel(self): """Test Linear kernel.""" X, Y = sl_test_utils.load_libsvm_file(fpath, 0) K = El.DistMatrix() Linear_kernel = sl_kernels.Linear(X.Height()) Linear_kernel.gram(X, K, 0, 0) self.assertTrue(sl_test_utils.is_kernel(K))
def test_Gaussian_kernel(self): """Test Gaussian kernel.""" X, Y = sl_test_utils.load_libsvm_file(fpath, 0) K = El.DistMatrix() Gaussian_kernel = sl_kernels.Gaussian(X.Height(), 10.0) Gaussian_kernel.gram(X, K, 0, 0) self.assertTrue(sl_test_utils.is_kernel(K))
def Semidefinite(height): Q = El.DistSparseMatrix() Q.Resize(height,height) localHeight = Q.LocalHeight() Q.Reserve(localHeight) for sLoc in xrange(localHeight): s = Q.GlobalRow(sLoc) Q.QueueLocalUpdate( sLoc, s, 1 ); Q.MakeConsistent() return Q
def Deriv(height): A = El.DistSparseMatrix() A.Resize(height - 1, height) localHeight = A.LocalHeight() A.Reserve(2 * localHeight) for iLoc in xrange(localHeight): i = A.GlobalRow(iLoc) A.QueueLocalUpdate(iLoc, i, 1.) A.QueueLocalUpdate(iLoc, i + 1, -1.) A.ProcessQueues() return A
def test_faster_least_squares_NORMAL(self): """Solution to argmin_X ||A * X - B||_F""" m = 500 n = 100 # Generate problem A, B, X, X_opt = (El.Matrix(), El.Matrix(), El.Matrix(), El.Matrix()) El.Gaussian(A, m, n) El.Gaussian(X_opt, n, 1) El.Zeros(B, m, 1) El.Gemm(El.NORMAL, El.NORMAL, 1, A, X_opt, 0, B) # Solve it using faster least squares sl_nla.faster_least_squares(A, B, X) # Check the norm of our solution El.Gemm(El.NORMAL, El.NORMAL, 1, A, X, -1, B) self.assertAlmostEqual(El.Norm(B), 0) # Checking the solution self.assertTrue(utils.equal(X_opt, X))
def Rectang(height,width): A = El.DistSparseMatrix() A.Resize(height,width) localHeight = A.LocalHeight() A.Reserve(5*localHeight) for sLoc in xrange(localHeight): s = A.GlobalRow(sLoc) A.QueueLocalUpdate( sLoc, s%width, 11 ) A.QueueLocalUpdate( sLoc, (s-1)%width, -1 ) A.QueueLocalUpdate( sLoc, (s+1)%width, 2 ) A.QueueLocalUpdate( sLoc, (s-height)%width, -3 ) A.QueueLocalUpdate( sLoc, (s+height)%width, 4 ) # The dense last column #A.QueueLocalUpdate( sLoc, width-1, -5/height ); A.ProcessQueues() return A
def _read_elemental_dense_parallel(self, colDist=El.MC, rowDist=El.MR): f = h5py.File(fpath, 'r', driver='mpio', comm=MPI.COMM_WORLD) height, width = int(f['shape'][0]), int(f['shape'][1]) A = El.DistMatrix(colDist=colDist, rowDist=colDist) A.Resize(height, width) local_height, local_width = A.LocalHeight(), A.LocalWidth() indices = elemental_dense.get_indices(A) local_data = f[self.dataset][indices] local_buf = A.Matrix().Buffer() for i in range(len(indices)): local_buf[i] = local_data[i] f.close() return A
def StackedFD2D(N0, N1): A = El.DistMatrix() height = 2 * N0 * N1 width = N0 * N1 A.Resize(height, width) blocksize = height // worldSize myStart = blocksize * worldRank if worldRank == worldSize - 1: myHeight = height - myStart else: myHeight = blocksize A.Reserve(6 * myHeight) for sLoc in xrange(localHeight): s = A.GlobalRow(sLoc) if s < N0 * N1: x0 = s % N0 x1 = s / N0 A.QueueUpdate(sLoc, s, 11) if x0 > 0: A.QueueUpdate(sLoc, s - 1, -1) if x0 + 1 < N0: A.QueueUpdate(sLoc, s + 1, 2) if x1 > 0: A.QueueUpdate(sLoc, s - N0, -30) if x1 + 1 < N1: A.QueueUpdate(sLoc, s + N0, 4) else: sRel = s - N0 * N1 x0 = sRel % N0 x1 = sRel / N0 A.QueueUpdate(sLoc, sRel, -20) if x0 > 0: A.QueueUpdate(sLoc, sRel - 1, -17) if x0 + 1 < N0: A.QueueUpdate(sLoc, sRel + 1, -20) if x1 > 0: A.QueueUpdate(sLoc, sRel - N0, -3) if x1 + 1 < N1: A.QueueUpdate(sLoc, sRel + N0, 3) # The dense last column A.QueueUpdate(sLoc, width - 1, -10 / height) A.ProcessQueues() return A
def Square(xSize, ySize): A = El.SparseMatrix(El.dTag) n = xSize * ySize A.Resize(n, n) A.Reserve(5 * n) hxInvSq = (1. * (xSize + 1))**2 hyInvSq = (1. * (ySize + 1))**2 for s in xrange(n): x = s % xSize y = s / xSize A.QueueUpdate(s, s, 8 * (hxInvSq + hyInvSq)) if x != 0: A.QueueUpdate(s, s - 1, -1 * hxInvSq) if x != xSize - 1: A.QueueUpdate(s, s + 1, -2 * hxInvSq) if y != 0: A.QueueUpdate(s, s - xSize, -4 * hyInvSq) if y != ySize - 1: A.QueueUpdate(s, s + xSize, -3 * hyInvSq) A.ProcessQueues() return A
def distr_vec(local_vec, tag): """Converts the given vector to a distributed multivector. Parameters ---------- local_vec : NumPy 1D array. tag : The Elemental data type. Returns ------- Elemental distributed multivector. """ import El vec = El.DistMultiVec(tag=tag) vec.Resize(local_vec.size, 1) for i in range(local_vec.size): vec.Set(i, 0, local_vec[i]) return vec