def test_get_size(self): v = pyamgx.Vector().create(self.rsrc) n, block_dim = v.get_size() assert (n == 0) assert (block_dim == 1) v.upload(np.array([1, 2, 3.], dtype=np.float64)) n, block_dim = v.get_size() assert (n == 3) assert (block_dim == 1) v.destroy()
def test_solve_matrix_rectangular(self): M = pyamgx.Matrix().create(self.rsrc) x = pyamgx.Vector().create(self.rsrc) b = pyamgx.Vector().create(self.rsrc) ''' Matrix: 1, 2, 0 2, 1, 0 ''' M.upload(np.array([0, 2, 4], dtype=np.int32), np.array([0, 1, 0, 1], dtype=np.int32), np.array([1., 2., 2., 1.], dtype=np.float64)) x.upload(np.zeros(3, dtype=np.float64)) b.upload(np.array([1, 2], dtype=np.float64)) solver = pyamgx.Solver().create(self.rsrc, self.cfg) solver.setup(M) with pytest.raises(ValueError): solver.solve(b, x) solver.destroy() M.destroy() x.destroy() b.destroy()
def test_create_and_destroy(self): v = pyamgx.Vector().create(self.rsrc) v.destroy()
"exception_handling": 1, "solver": { "monitor_residual": 1, "solver": "BICGSTAB", "convergence": "RELATIVE_INI_CORE", "preconditioner": { "solver": "NOSOLVER" } } }) rsc = pyamgx.Resources().create_simple(cfg) # Create matrices and vectors: A = pyamgx.Matrix().create(rsc) b = pyamgx.Vector().create(rsc) x = pyamgx.Vector().create(rsc) # Create solver: solver = pyamgx.Solver().create(rsc, cfg) # Upload system: M = sparse.csr_matrix(np.random.rand(5, 5)) rhs = np.random.rand(5) sol = np.zeros(5, dtype=np.float64) A.upload_CSR(M) b.upload(rhs) x.upload(sol) # Setup and solve system:
def __init__(self, A, linear_solver, env): if linear_solver is 'lu': self.A = A.tocsc() self.lu = splu(self.A) elif linear_solver is 'cg': self.A = A.tocsr() elif linear_solver in ['cudaCG']: self.A = A.tocsr() self.dData = env.cuda.to_device(self.A.data) self.dPtr = env.cuda.to_device(self.A.indptr) self.dInd = env.cuda.to_device(self.A.indices) self.cuSparseDescr = env.cuSparse.matdescr() elif linear_solver in ['cudaPCG']: self.A = A.tocsr() self.Adescr = env.cuSparse.matdescr() self.Adata = env.cuda.to_device(self.A.data) self.Aptr = env.cuda.to_device(self.A.indptr) self.Aind = env.cuda.to_device(self.A.indices) A_t = self.A.copy() A_t = -A_t # Make it positive definite A_t.data = np.where(A_t.nonzero()[0] >= A_t.nonzero()[1], A_t.data, 0.) A_t.eliminate_zeros() A_t_descr = env.cuSparse.matdescr(matrixtype='S', fillmode='L') info = env.cuSparse.csrsv_analysis(trans='N', m=A_t.shape[0], nnz=A_t.nnz, \ descr=A_t_descr, csrVal=A_t.data, \ csrRowPtr=A_t.indptr, csrColInd=A_t.indices) env.cuSparse.csric0(trans='N', m=A_t.shape[0], \ descr=A_t_descr, csrValM=A_t.data, csrRowPtrA=A_t.indptr,\ csrColIndA=A_t.indices, info=info) self.L = A_t self.Lmv_descr = env.cuSparse.matdescr() # self.Lsv_descr = cuSparse.matdescr(matrixtype='T', fillmode='L') self.Lsv_descr = env.cuSparse.matdescr(matrixtype='T') self.Ldata = env.cuda.to_device(self.L.data) self.Lptr = env.cuda.to_device(self.L.indptr) self.Lind = env.cuda.to_device(self.L.indices) self.Lsv_info = env.cuSparse.csrsv_analysis(trans='N', m=self.L.shape[0], \ nnz=self.L.nnz, descr=self.Lsv_descr, csrVal=self.Ldata, \ csrRowPtr=self.Lptr, csrColInd=self.Lind) self.LT = self.L.transpose() self.LT.tocsr() self.LTmv_descr = env.cuSparse.matdescr() # self.LTsv_descr = env.cuSparse.matdescr(matrixtype='T', fillmode='U') self.LTsv_descr = env.cuSparse.matdescr() self.LTdata = env.cuda.to_device(self.LT.data) self.LTptr = env.cuda.to_device(self.LT.indptr) self.LTind = env.cuda.to_device(self.LT.indices) self.LTsv_info = env.cuSparse.csrsv_analysis(trans='T', m=self.L.shape[0], \ nnz=self.L.nnz, descr=self.Lsv_descr, csrVal=self.Ldata, \ csrRowPtr=self.Lptr, csrColInd=self.Lind) elif linear_solver is 'pcg': self.A = A.tocsr() A_t = -self.D2s elif linear_solver is 'amg': self.A = A.tocsr() self.A_spd = self.A.copy() self.A_spd = -self.A_spd self.B = np.ones((self.A_spd.shape[0], 1), dtype=self.A_spd.dtype) self.BH = self.B.copy() if self.A_spd.shape[0] in [40962, 163842, 655362]: self.A_amg = rootnode_solver(self.A_spd, B=self.B, BH=self.BH, strength=('evolution', {'epsilon': 2.0, 'k': 2, 'proj_type': 'l2'}), smooth=('energy', {'weighting': 'local', 'krylov': 'cg', 'degree': 2, 'maxiter': 3}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), \ None, None, None, None, None, None, None, None, None, None, \ None, None, None, None], aggregate="standard", presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver="pinv") elif self.A_spd.shape[0] in [81920, 327680, 1310720, 5242880]: self.A_amg = rootnode_solver(self.A_spd, B=self.B, BH=self.BH, strength=('evolution', {'epsilon': 4.0, 'k': 2, 'proj_type': 'l2'}), smooth=('energy', {'weighting': 'local', 'krylov': 'cg', 'degree': 2, 'maxiter': 3}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), \ None, None, None, None, None, None, None, None, None, None, \ None, None, None, None], aggregate="standard", presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver="pinv") elif self.A_spd.shape[0] in [2621442]: self.A_amg = rootnode_solver(self.A_spd, B=self.B, BH=self.BH, strength=('evolution', {'epsilon': 4.0, 'k': 2, 'proj_type': 'l2'}), smooth=('energy', {'weighting': 'local', 'krylov': 'cg', 'degree': 3, 'maxiter': 4}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), \ None, None, None, None, None, None, None, None, None, None, \ None, None, None, None], aggregate="standard", presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver="pinv") else: print("Unknown matrix. Using a generic AMG solver") self.A_amg = rootnode_solver(self.A_spd, B=self.B, BH=self.BH, strength=('evolution', {'epsilon': 2.0, 'k': 2, 'proj_type': 'l2'}), smooth=('energy', {'weighting': 'local', 'krylov': 'cg', 'degree': 2, 'maxiter': 3}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), \ None, None, None, None, None, None, None, None, None, None, \ None, None, None, None], aggregate="standard", presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver="pinv") elif linear_solver is 'amgx': import pyamgx pyamgx.initialize() hA = A.tocsr() if hA.nnz * 1. / hA.shape[0] > 5.5: # Primary mesh AMGX_CONFIG_FILE_NAME = 'amgx_config/PCGF_CLASSICAL_AGGRESSIVE_PMIS_JACOBI.json' if hA.nnz * 1. / hA.shape[0] < 5.5: # Dual mesh AMGX_CONFIG_FILE_NAME = 'amgx_config/PCGF_CLASSICAL_AGGRESSIVE_PMIS.json' else: print( 'Error: cannot determine primary or dual mesh, not sure which config to use.' ) cfg = pyamgx.Config().create_from_file(AMGX_CONFIG_FILE_NAME) rsc = pyamgx.Resources().create_simple(cfg) mode = 'dDDI' # Create solver: self.amgx = pyamgx.Solver().create(rsc, cfg, mode) # Create matrices and vectors: d_A = pyamgx.Matrix().create(rsc, mode) self.d_x = pyamgx.Vector().create(rsc, mode) self.d_b = pyamgx.Vector().create(rsc, mode) d_A.upload(hA.indptr, hA.indices, hA.data) # Setup and solve system: self.amgx.setup(d_A) ## Clean up: #A.destroy() #x.destroy() #b.destroy() #self.amgx.destroy() #rsc.destroy() #cfg.destroy() #pyamgx.finalize() else: raise ValueError("Invalid solver choice.")
def __init__(self, vc, g, c): # load appropriate module for working with objects on CPU / GPU if c.use_gpu: if not c.linear_solver is 'amgx': raise ValueError("Invalid solver choice.") import cupy as xp from cupyx.scipy.sparse import coo_matrix, csc_matrix, csr_matrix, eye, diags, bmat areaCell_cpu = g.areaCell.get() else: if c.linear_solver is 'amgx': raise ValueError("Invalid solver choice.") import numpy as xp from scipy.sparse import coo_matrix, csc_matrix, csr_matrix, eye, diags, bmat areaCell_cpu = g.areaCell # Construct matrix blocks of the coupled elliptic system # A diagonal matrix representing scaling by cell areas mAreaCell = diags(g.areaCell, 0, format='csr') mAreaCell_phi = mAreaCell.copy() mAreaCell_phi[0, 0] = 0. #mAreaCell_phi.eliminate_zeros( ) if c.on_a_global_sphere: mAreaCell_psi = mAreaCell_phi.copy() else: areaCell_psi = g.areaCell.copy() areaCell_psi[g.cellBoundary - 1] = 0. mAreaCell_psi = diags(areaCell_psi, 0, format='csr') #mAreaCell_psi.eliminate_zeros( ) ## Construct the coefficient matrix for the coupled elliptic ## system for psi and phi, using the normal vector # Left, row 1 self.AMC = mAreaCell_psi * vc.mVertex2cell * vc.mCurl_t self.AC = mAreaCell_psi * vc.mCurl_v #self.AMC.eliminate_zeros( ) self.AMC.sort_indices() #self.AC.eliminate_zeros( ) self.AC.sort_indices() # Left, row 2 self.AMD = mAreaCell_phi * vc.mVertex2cell * vc.mDiv_t self.AD = mAreaCell_phi * vc.mDiv_v #self.AMD.eliminate_zeros( ) self.AMD.sort_indices() #self.AD.eliminate_zeros( ) self.AD.sort_indices() # Right, col 2 self.GN = vc.mGrad_tn * vc.mCell2vertex_n #self.GN.eliminate_zeros( ) self.GN.sort_indices() # Right, col 1 self.SN = vc.mSkewgrad_nd * vc.mCell2vertex_psi #self.SN.eliminate_zeros( ) self.SN.sort_indices() ## Construct an artificial thickness vector thickness_edge = 100 * (10. + xp.random.rand(g.nEdges)) self.thicknessInv = 1. / thickness_edge # self.mThicknessInv = eye(g.nEdges) # self.mThicknessInv.data[0,:] = 1./thickness_edge # Copy certain matrices over from VectorCalculus; maybe unnecessary # in the future. self.mSkewgrad_td = vc.mSkewgrad_td.copy() self.mGrad_n_n = vc.mGrad_n_n.copy() if c.linear_solver is 'amgx': import pyamgx pyamgx.initialize() err_tol = c.err_tol * 1e-5 * np.mean(areaCell_cpu) * np.sqrt( g.nCells) # For vorticity cfg1 = pyamgx.Config().create_from_dict({ "config_version": 2, "determinism_flag": 0, "solver": { "preconditioner": { "print_grid_stats": c.print_stats, "algorithm": "AGGREGATION", "print_vis_data": 0, "solver": "AMG", "smoother": { "relaxation_factor": 0.8, "scope": "jacobi", "solver": "BLOCK_JACOBI", "monitor_residual": 0, "print_solve_stats": 0 }, "print_solve_stats": 0, "presweeps": 2, "selector": "SIZE_2", "coarse_solver": "NOSOLVER", "max_iters": 2, "monitor_residual": 0, "store_res_history": 0, "scope": "amg_solver", "max_levels": 100, "postsweeps": 2, "cycle": "V" }, "solver": "PCGF", "print_solve_stats": c.print_stats, "obtain_timings": c.print_stats, "max_iters": c.max_iters, "monitor_residual": 1, "convergence": "ABSOLUTE", "scope": "main", "tolerance": err_tol, "norm": "L2" } }) # Smaller error tolerance for divergence because geophysical flows # are largely nondivergent err_tol = c.err_tol * 1e-6 * np.mean(areaCell_cpu) * np.sqrt( g.nCells) cfg2 = pyamgx.Config().create_from_dict({ "config_version": 2, "determinism_flag": 0, "solver": { "preconditioner": { "print_grid_stats": c.print_stats, "algorithm": "AGGREGATION", "print_vis_data": 0, "solver": "AMG", "smoother": { "relaxation_factor": 0.8, "scope": "jacobi", "solver": "BLOCK_JACOBI", "monitor_residual": 0, "print_solve_stats": 0 }, "print_solve_stats": 0, "presweeps": 2, "selector": "SIZE_2", "coarse_solver": "NOSOLVER", "max_iters": 2, "monitor_residual": 0, "store_res_history": 0, "scope": "amg_solver", "max_levels": 100, "postsweeps": 2, "cycle": "V" }, "solver": "PCGF", "print_solve_stats": c.print_stats, "obtain_timings": c.print_stats, "max_iters": c.max_iters, "monitor_residual": 1, "convergence": "ABSOLUTE", "scope": "main", "tolerance": err_tol, "norm": "L2" } }) rsc1 = pyamgx.Resources().create_simple(cfg1) rsc2 = pyamgx.Resources().create_simple(cfg2) mode = 'dDDI' # Create solver: self.slv11 = pyamgx.Solver().create(rsc1, cfg1, mode) self.slv22 = pyamgx.Solver().create(rsc2, cfg2, mode) # Create matrices and vectors: self.d_A11 = pyamgx.Matrix().create(rsc1, mode) self.d_x = pyamgx.Vector().create(rsc1, mode) self.d_b1 = pyamgx.Vector().create(rsc1, mode) self.d_A22 = pyamgx.Matrix().create(rsc2, mode) self.d_y = pyamgx.Vector().create(rsc2, mode) self.d_b2 = pyamgx.Vector().create(rsc2, mode) elif c.linear_solver is 'amg': from pyamg import rootnode_solver elif c.linear_solver is 'lu': pass else: raise ValueError("Invalid solver choice.")
def __init__(self, A, linear_solver, env): if linear_solver is 'lu': self.A = A.tocsc() elif linear_solver is 'amgx': import pyamgx pyamgx.initialize() hA = A.tocsr() AMGX_CONFIG_FILE_NAME = 'amgx_config/PCGF_CLASSICAL_AGGRESSIVE_PMIS_JACOBI.json' if False: cfg = pyamgx.Config().create_from_file(AMGX_CONFIG_FILE_NAME) else: cfg = pyamgx.Config().create_from_dict({ "config_version": 2, "determinism_flag": 0, "solver": { "preconditioner": { "print_grid_stats": c.print_stats, "algorithm": "AGGREGATION", "print_vis_data": 0, "solver": "AMG", "smoother": { "relaxation_factor": 0.8, "scope": "jacobi", "solver": "BLOCK_JACOBI", "monitor_residual": 0, "print_solve_stats": 0 }, "print_solve_stats": 0, "presweeps": 2, "selector": "SIZE_2", "coarse_solver": "NOSOLVER", "max_iters": 2, "monitor_residual": 0, "store_res_history": 0, "scope": "amg_solver", "max_levels": 1000, "postsweeps": 2, "cycle": "V" }, "solver": "PCGF", "print_solve_stats": c.print_stats, "obtain_timings": c.print_stats, "max_iters": c.max_iters, "monitor_residual": 1, "convergence": "RELATIVE_INI", "scope": "main", "tolerance": c.err_tol, "norm": "L2" } }) rsc = pyamgx.Resources().create_simple(cfg) mode = 'dDDI' # Create solver: self.amgx = pyamgx.Solver().create(rsc, cfg, mode) # Create matrices and vectors: self.d_A = pyamgx.Matrix().create(rsc, mode) self.d_x = pyamgx.Vector().create(rsc, mode) self.d_b = pyamgx.Vector().create(rsc, mode) self.d_A.upload_CSR(hA) # Setup and solve system: # self.amgx.setup(d_A) ## Clean up: #A.destroy() #x.destroy() #b.destroy() #self.amgx.destroy() #rsc.destroy() #cfg.destroy() #pyamgx.finalize() elif linear_solver is 'cg' or 'amg': pass else: raise ValueError("Invalid solver choice.")