/// <summary> /// Do symbolic factorization for current type. /// </summary> protected virtual int DoSymbolic() { int n = matrix.ColumnCount; int nrhs = 1; int error = 0; var iparm = options.iparm; var h = new List <GCHandle>(); try { var a = InteropHelper.Pin(matrix.Values, h); var ia = InteropHelper.Pin(matrix.ColumnPointers, h); var ja = InteropHelper.Pin(matrix.RowIndices, h); // Reordering and Symbolic Factorization. This step also allocates // all memory that is necessary for the factorization. int phase = 11; NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase, ref n, a, ia, ja, perm, ref nrhs, iparm, ref msglvl, IntPtr.Zero, IntPtr.Zero, out error); } finally { InteropHelper.Free(h); } return(error); }
/// <summary> /// Solves a system of linear equations, Ax = b. /// </summary> /// <param name="input">Right hand side vector b.</param> /// <param name="result">Solution vector x.</param> public void Solve(T[] input, T[] result) { if (!factorized) { Factorize(); } var handles = new List <GCHandle>(); try { var h_b = InteropHelper.Pin(input, handles); var h_x = InteropHelper.Pin(result, handles); int rows = input.Length; int columns = result.Length; Cuda.CopyToDevice(d_b, h_b, sizeT * rows); // Solve A*x = b. Check(Solve(rows, columns)); Cuda.CopyToHost(h_x, d_x, sizeT * columns); } finally { InteropHelper.Free(handles); } }
protected void Dispose(bool disposing) { if (pt != null && pt.Any(p => p != IntPtr.Zero)) { int n = matrix.ColumnCount; int nrhs = 1; int error = 0; var iparm = options.iparm; var h = new List <GCHandle>(); try { var ia = InteropHelper.Pin(matrix.ColumnPointers, h); var ja = InteropHelper.Pin(matrix.RowIndices, h); // Release internal memory. int phase = -1; NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase, ref n, IntPtr.Zero, ia, ja, null, ref nrhs, iparm, ref msglvl, IntPtr.Zero, IntPtr.Zero, out error); } finally { InteropHelper.Free(h); } pt = null; } }
protected virtual int DoNumeric() { if (qr == IntPtr.Zero) { throw new Exception("A call to DoNumeric() must be preceeded by DoSymbolic()."); } var h = new List <GCHandle>(); try { var A = CreateSparse(matrix, h); double tol = Constants.SPQR_DEFAULT_TOL; int status = NativeMethods.SuiteSparseQR_C_numeric(tol, ref A, qr, ref common); if (common.status != Constants.CHOLMOD_OK) { throw new CholmodException(common.status); } return(status); } finally { InteropHelper.Free(h); } }
/// <summary> /// Solve multiple systems of linear equations. /// </summary> /// <param name="sys">The system to solve.</param> /// <param name="input">Right hand side B</param> /// <param name="result">Solution matrix X.</param> protected virtual int DoSolve(CholmodSolve sys, DenseColumnMajorStorage <T> input, DenseColumnMajorStorage <T> result) { var h = new List <GCHandle>(); try { var B = CreateDense(input, h); var ptr = NativeMethods.cholmod_solve((int)sys, ref L, ref B, ref common); if (common.status != Constants.CHOLMOD_OK) { throw new CholmodException(common.status); } var X = (CholmodDense)Marshal.PtrToStructure(ptr, typeof(CholmodDense)); CopyDense(X, result); NativeMethods.cholmod_free_dense(ref ptr, ref common); return(1); } finally { InteropHelper.Free(h); } }
/// <summary> /// Solve the standard eigenvalue problem in shift-invert mode. /// </summary> public override IEigenSolverResult SolveStandard(int k, Complex sigma, Spectrum job = Spectrum.LargestMagnitude) { if (!CheckSquare(A)) { throw new InvalidOperationException("Cannot solve eigenvalue problem with non-square matrix."); } if (!Job.Validate(symmetric, job)) { throw new ArgumentException("Invalid job for given eigenvalue problem.", "job"); } var result = new ArpackResult(k, size, ComputeEigenVectors); var handles = new List <GCHandle>(); var a = GetMatrix(A, handles); var e = result.GetEigenvalueStorage(handles); int conv = NativeMethods.ar_zi_ns_shift(GetJob(job), k, ArnoldiCount, Iterations, Tolerance, sigma, ref a, ref e); result.IterationsTaken = e.iterations; result.ArnoldiCount = e.ncv; result.ConvergedEigenValues = conv; result.ErrorCode = e.info; InteropHelper.Free(handles); return(result); }
/// <summary> /// Do symbolic and numeric factorization for current type. /// </summary> protected virtual int DoFactorize() { int n = matrix.ColumnCount; int nrhs = 1; int error = 0; var iparm = options.iparm; var h = new List <GCHandle>(); try { var a = InteropHelper.Pin(matrix.Values, h); var ia = InteropHelper.Pin(matrix.ColumnPointers, h); var ja = InteropHelper.Pin(matrix.RowIndices, h); // Analysis and numerical factorization. int phase = 12; NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase, ref n, a, ia, ja, perm, ref nrhs, iparm, ref msglvl, IntPtr.Zero, IntPtr.Zero, out error); } finally { InteropHelper.Free(h); } return(error); }
/// <summary> /// Solve the generalized eigenvalue problem in user-defined shift-invert mode. /// </summary> public IEigenSolverResult SolveGeneralized(int k, double sigma, ShiftMode mode, Spectrum job = Spectrum.LargestMagnitude) { if (!symmetric && !(mode == ShiftMode.None || mode == ShiftMode.Regular)) { throw new InvalidOperationException("This mode is only available for symmetric eigenvalue problems."); } if (!CheckSquare(A)) { throw new InvalidOperationException("Cannot solve eigenvalue problem with non-square matrix."); } if (!Job.Validate(symmetric, job)) { throw new ArgumentException("Invalid job for symmetric eigenvalue problem.", "job"); } var result = new ArpackResult(k, size, ComputeEigenVectors, symmetric); var handles = new List <GCHandle>(); var a = GetMatrix(A, handles); var b = GetMatrix(B, handles); var e = result.GetEigenvalueStorage(handles); int conv = 0; if (symmetric) { char m = 'S'; if (mode == ShiftMode.Buckling) { m = 'B'; } else if (mode == ShiftMode.Cayley) { m = 'C'; } conv = NativeMethods.ar_di_sg_shift(GetJob(job), m, k, ArnoldiCount, Iterations, Tolerance, sigma, ref a, ref b, ref e); } else { conv = NativeMethods.ar_di_ng_shift(GetJob(job), k, ArnoldiCount, Iterations, Tolerance, sigma, ref a, ref b, ref e); } result.IterationsTaken = e.iterations; result.ArnoldiCount = e.ncv; result.ConvergedEigenValues = conv; result.ErrorCode = e.info; InteropHelper.Free(handles); return(result); }
private MetisStatus Partition(int nparts, int[] part, MetisOptions options, bool kway) { int objval = 0; if (part == null || part.Length < this.nvtxs) { return(MetisStatus.ERROR_INPUT); } var handles = new List <GCHandle>(); // Pin array data. var p_part = InteropHelper.Pin(part, handles); var p_xadj = InteropHelper.Pin(xadj, handles); var p_adjncy = InteropHelper.Pin(adjncy, handles); var p_vwgt = InteropHelper.Pin(vwgt, handles); var p_ewgt = InteropHelper.Pin(adjwgt, handles); var p_vsize = InteropHelper.Pin(vsize, handles); var p_opts = options == null ? IntPtr.Zero : InteropHelper.Pin(options.raw, handles); int l_nv = nvtxs; int l_nw = ncon; int status = 0; try { if (kway) { status = NativeMethods.PartGraphKway(ref l_nv, ref l_nw, p_xadj, p_adjncy, p_vwgt, p_vsize, p_ewgt, ref nparts, IntPtr.Zero, IntPtr.Zero, p_opts, ref objval, p_part); } else { status = NativeMethods.PartGraphRecursive(ref l_nv, ref l_nw, p_xadj, p_adjncy, p_vwgt, p_vsize, p_ewgt, ref nparts, IntPtr.Zero, IntPtr.Zero, p_opts, ref objval, p_part); } } catch (Exception) { throw; } finally { InteropHelper.Free(handles); } return((MetisStatus)status); }
/// <inheritdoc /> public override FeastResult <double> SolveGeneralized(int m0, double emin, double emax, DenseColumnMajorStorage <double> subspace) { // TODO: check subspace matrix dimensions. char uplo = 'F'; // Full matrix. int n = A.RowCount; double epsout; // Relative error on the trace. int loop; // Number of refinement loops. int m = m0; // Total number of eigenvalues found in the interval. int info; var E = new double[m0]; // Eigenvalues var R = new double[m0]; // Residual var X = subspace.Values; // Eigenvectors var fpm = this.Options.fpm; var h = new List <GCHandle>(); try { Increment(A); Increment(B); var a = InteropHelper.Pin(A.Values, h); var ia = InteropHelper.Pin(A.ColumnPointers, h); var ja = InteropHelper.Pin(A.RowIndices, h); var b = InteropHelper.Pin(B.Values, h); var ib = InteropHelper.Pin(B.ColumnPointers, h); var jb = InteropHelper.Pin(B.RowIndices, h); var pe = InteropHelper.Pin(E, h); var px = InteropHelper.Pin(X, h); var pr = InteropHelper.Pin(R, h); NativeMethods.dfeast_scsrgv(ref uplo, ref n, a, ia, ja, b, ib, jb, fpm, out epsout, out loop, ref emin, ref emax, ref m0, pe, px, out m, pr, out info); Decrement(A); Decrement(B); return(new FeastResult(info, m0, n, loop, epsout, m, E, subspace, R)); } finally { InteropHelper.Free(h); } }
/// <summary> /// Special case solving the standard real generalized eigenvalue problem with complex shift. /// </summary> /// <param name="k">The number of eigenvalues to compute.</param> /// <param name="sigma_r">The real part of the complex shift.</param> /// <param name="sigma_i">The imaginary part of the complex shift.</param> /// <param name="part">Part to apply ('R' for real, 'I' for imaginary).</param> /// <param name="job">The part of the spectrum to compute.</param> /// <returns>The number of converged eigenvalues.</returns> public IEigenSolverResult SolveGeneralized(int k, double sigma_r, double sigma_i, char part, Spectrum job = Spectrum.LargestMagnitude) { if (symmetric) { throw new InvalidOperationException("Complex shift doesn't apply to real symmetric eigenvalue problems."); } if (!CheckSquare(A)) { throw new InvalidOperationException("Cannot solve eigenvalue problem with non-square matrix."); } if (!Job.ValidateGeneral(job)) { throw new ArgumentException("Invalid job for non-symmetric eigenvalue problem.", "job"); } part = char.ToUpperInvariant(part); if (part != 'R' && part != 'I') { throw new ArgumentException("Invalid part specified for complex shift.", "part"); } var result = new ArpackResult(k, size, ComputeEigenVectors, symmetric); var handles = new List <GCHandle>(); var a = GetMatrix(A, handles); var b = GetMatrix(B, handles); var e = result.GetEigenvalueStorage(handles); int conv = 0; conv = NativeMethods.ar_di_ng_shift_cx(GetJob(job), k, ArnoldiCount, Iterations, Tolerance, part, sigma_r, sigma_i, ref a, ref b, ref e); result.IterationsTaken = e.iterations; result.ArnoldiCount = e.ncv; result.ConvergedEigenValues = conv; result.ErrorCode = e.info; InteropHelper.Free(handles); return(result); }
protected virtual void Dispose(bool disposing) { if (disposing) { InteropHelper.Free(handles); } if (Lp != IntPtr.Zero) { NativeMethods.cholmod_free_factor(ref Lp, ref common); NativeMethods.cholmod_finish(ref common); L = default(CholmodFactor); } }
public override void Solve(double[] input, double[] result) { if (!factorized && DoFactorize() != 0) { throw new Exception(); // TODO: exception } var n = matrix.RowCount; var h = new List <GCHandle>(); var b = InteropHelper.Pin(input, h); var x = InteropHelper.Pin(result, h); var t = InteropHelper.Pin(w, h); try { // x = b(p) if (NativeMethods.cs_di_ipvec(N.pinv, b, t, n) == 0) { return; } // x = L\x if (NativeMethods.cs_di_lsolve(N.L, t) == 0) { return; } // x = U\x if (NativeMethods.cs_di_usolve(N.U, t) == 0) { return; } // b(q) = x if (NativeMethods.cs_di_pvec(S.q, t, x, n) == 0) { return; } } finally { InteropHelper.Free(h); } }
/// <summary> /// Compute singular values and the partial singular value decomposition. /// </summary> /// <param name="k">The number of singular values to compute.</param> /// <param name="normal">Use normal equation to compute (squared) singular values.</param> /// <param name="job">The part of the spectrum to compute.</param> /// <returns>The number of converged singular values.</returns> /// <remarks> /// If <paramref name="normal"/> is true, the normal equation <c>(A'*A)*v = sigma*v</c> /// is considered, where A is an m-by-n real matrix. This formulation is appropriate /// when m >= n. The roles of A and A' must be reversed in the case that m < n. /// /// The eigenvalues returned are the squared singular values of A. If requested, the /// returned eigenvectors correspond to the right singular vectors, if <c>A = U*S*V'</c>. /// The left singular vectors can be computed from the equation <c>A*v - sigma*u = 0</c>. /// /// If <paramref name="normal"/> is false, the symmetric system <c>[0 A; A' 0]</c> is /// considered (size m + n), where A is an m-by-n real matrix. /// /// This problem can be used to obtain the decomposition <c>A = U*S*V'</c>. The positive /// eigenvalues of this problem are the singular values of A (the eigenvalues come in /// pairs, the negative eigenvalues have the same magnitude of the positive ones and /// can be discarded). The columns of U can be extracted from the first m components /// of the eigenvectors y, while the columns of V can be extracted from the remaining /// n components. /// </remarks> public IEigenSolverResult SingularValues(int k, bool normal, Spectrum job = Spectrum.LargestMagnitude) { if (!Job.ValidateSymmetric(job)) { throw new ArgumentException("Invalid job for singular value decomposition.", "job"); } int m = A.RowCount; int n = A.ColumnCount; if (normal && m < n) { throw new InvalidOperationException("Number of columns must not be smaller than number of rows (use transposed matrix)."); } int size = normal ? n : m + n; var result = new ArpackResult(k, size, ComputeEigenVectors, true); var handles = new List <GCHandle>(); var a = GetMatrix(A, handles); var e = result.GetEigenvalueStorage(handles); int conv = 0; if (normal) { conv = NativeMethods.ar_di_svd_nrm(GetJob(job), k, ArnoldiCount, Iterations, Tolerance, ref a, ref e); } else { conv = NativeMethods.ar_di_svd(GetJob(job), k, ArnoldiCount, Iterations, Tolerance, ref a, ref e); } result.IterationsTaken = e.iterations; result.ArnoldiCount = e.ncv; result.ConvergedEigenValues = conv; result.ErrorCode = e.info; InteropHelper.Free(handles); return(result); }
public override void Solve(Complex[] input, Complex[] result) { if (!factorized && DoFactorize() != 0) { throw new Exception(); // TODO: exception } var n = matrix.RowCount; var h = new List <GCHandle>(); var b = InteropHelper.Pin(input, h); var x = InteropHelper.Pin(result, h); var t = InteropHelper.Pin(w, h); try { // x = P*b if (NativeMethods.cs_ci_ipvec(S.pinv, b, t, n) == 0) { return; } // x = L\x if (NativeMethods.cs_ci_lsolve(N.L, t) == 0) { return; } // x = L'\x if (NativeMethods.cs_ci_ltsolve(N.L, t) == 0) { return; } // b = P'*x if (NativeMethods.cs_ci_pvec(S.pinv, t, x, n) == 0) { return; } } finally { InteropHelper.Free(h); } }
protected virtual void Dispose(bool disposing) { if (disposing) { InteropHelper.Free(handles); } if (L.Store != IntPtr.Zero) { NativeMethods.Destroy_SuperNode_Matrix(ref L); L.Store = IntPtr.Zero; } if (U.Store != IntPtr.Zero) { NativeMethods.Destroy_CompCol_Matrix(ref U); U.Store = IntPtr.Zero; } }
protected virtual int DoSolve(int sys, int method, DenseColumnMajorStorage <T> input, DenseColumnMajorStorage <T> result) { if (!factorized) { DoFactorize(); } var h = new List <GCHandle>(); try { var B = CreateDense(input, h); // Y = Q'*B var Yp = NativeMethods.SuiteSparseQR_C_qmult(method, qr, ref B, ref common); if (Yp == IntPtr.Zero) { return(-1000); } // X = R\(E*Y) var Xp = NativeMethods.SuiteSparseQR_C_solve(sys, qr, Yp, ref common); if (Xp == IntPtr.Zero) { return(-1000); } var X = (CholmodDense)Marshal.PtrToStructure(Xp, typeof(CholmodDense)); CopyDense(X, result); Cholmod.NativeMethods.cholmod_free_dense(ref Yp, ref common); Cholmod.NativeMethods.cholmod_free_dense(ref Xp, ref common); return(1); } finally { InteropHelper.Free(h); } }
/// <summary> /// Solve system of linear equations. /// </summary> /// <param name="sys">The system to solve.</param> /// <param name="input">Right-hand side b.</param> /// <param name="result">The solution x.</param> /// <returns></returns> /// <remarks> /// Parameter sys corresponds to iparm[11]: /// sys = 0: non-transposed /// sys = 1: conjugate transposed /// sys = 2: transposed /// </remarks> protected virtual int DoSolve(int sys, DenseColumnMajorStorage <T> input, DenseColumnMajorStorage <T> result) { int n = matrix.ColumnCount; // The number of right-hand sides. int nrhs = input.ColumnCount; if (nrhs != result.ColumnCount) { throw new ArgumentException("result"); } int error = 0; var iparm = options.iparm; var h = new List <GCHandle>(); try { var a = InteropHelper.Pin(matrix.Values, h); var ia = InteropHelper.Pin(matrix.ColumnPointers, h); var ja = InteropHelper.Pin(matrix.RowIndices, h); var b = InteropHelper.Pin(input.Values, h); var x = InteropHelper.Pin(result.Values, h); iparm[11] = sys; // Solve system. int phase = 33; NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase, ref n, a, ia, ja, perm, ref nrhs, iparm, ref msglvl, b, x, out error); } finally { InteropHelper.Free(h); } return(error); }
/// <summary> /// Solve the generalized eigenvalue problem. /// </summary> public override IEigenSolverResult SolveGeneralized(int k, Spectrum job = Spectrum.LargestMagnitude) { if (!Job.Validate(symmetric, job)) { throw new ArgumentException("Invalid job for given eigenvalue problem.", "job"); } if (ArnoldiCount < k) { ArnoldiCount = Math.Min(3 * k, A.RowCount); } var result = new SpectraResult(k, size, ComputeEigenVectors, symmetric); var handles = new List <GCHandle>(); var a = GetMatrix(A, handles); var b = GetMatrix(B, handles); var e = result.GetEigenvalueStorage(handles); int conv = 0; if (symmetric) { conv = NativeMethods.spectra_di_sg(GetJob(job), k, ArnoldiCount, Iterations, Tolerance, ref a, ref b, ref e); } else { throw new NotImplementedException(); //conv = NativeMethods.spectra_di_ng(GetJob(job), k, ArnoldiCount, // Iterations, Tolerance, ref a, ref b, ref e); } result.IterationsTaken = e.iterations; result.ConvergedEigenValues = conv; result.ErrorCode = e.info; InteropHelper.Free(handles); return(result); }
/// <inheritdoc /> public override ExtendedEigensolverResult <double> SolveStandard(int k0, Job job, DenseColumnMajorStorage <double> eigenvectors) { // TODO: check eigenvectors matrix dimensions. string which = job == Job.Smallest ? "S" : "L"; int n = A.RowCount; int k = 0; // Total number of eigenvalues found in the interval. var E = new double[k0]; // Eigenvalues var R = new double[k0]; // Residual var X = eigenvectors.Values; // Eigenvectors var h = new List <GCHandle>(); try { var pe = InteropHelper.Pin(E, h); var px = InteropHelper.Pin(X, h); var pr = InteropHelper.Pin(R, h); var h_A = CreateMatrixHandle(A, h); var desc = CreateMatrixDecriptor(); var info = NativeMethods.mkl_sparse_d_ev(new StringBuilder(which), pm, h_A, desc, k0, ref k, pe, px, pr); //if (info != sparse_status.SUCCESS) //{ // throw new Exception(info.ToString()); //} return(new ExtendedEigensolverResult(info, n, k, E, eigenvectors, R)); } finally { InteropHelper.Free(h); } }
/// <summary> /// Computes fill reducing orderings of sparse matrices using the multilevel nested dissection algorithm. /// </summary> /// <param name="perm">Target array storing the fill-reducing permutaion (size nvtxs).</param> /// <param name="iperm">Target array storing the fill-reducing inverse permutaion (size nvtxs).</param> /// <param name="options">Partitioning options.</param> /// <returns></returns> public MetisStatus NestedDissection(int[] perm, int[] iperm, MetisOptions options = null) { if (perm.Length != nvtxs || iperm.Length != nvtxs) { return(MetisStatus.ERROR_INPUT); } var handles = new List <GCHandle>(); // Pin array data. var p_xadj = InteropHelper.Pin(xadj, handles); var p_adjncy = InteropHelper.Pin(adjncy, handles); var p_vwgt = InteropHelper.Pin(vwgt, handles); var p_opts = options == null ? IntPtr.Zero : InteropHelper.Pin(options.raw, handles); var p_perm = InteropHelper.Pin(perm, handles); var p_iperm = InteropHelper.Pin(iperm, handles); int l_nv = nvtxs; int status = 0; try { status = NativeMethods.NodeND(ref l_nv, p_xadj, p_adjncy, p_vwgt, p_opts, p_perm, p_iperm); } catch (Exception) { throw; } finally { InteropHelper.Free(handles); } return((MetisStatus)status); }
protected override int DoFactorize() { int info = 0; var mem_usage = new mem_usage(); var stat = new SuperLUStat(); int m = A.nrow; int n = A.ncol; var h = new List <GCHandle>(); // Create matrix with ncol = 0 to indicate not to solve the system. var B = CreateEmptyDense(Dtype.SLU_D, m, h); var X = CreateEmptyDense(Dtype.SLU_D, n, h); try { var o = options.Raw; NativeMethods.StatInit(ref stat); NativeMethods.dgssvx(ref o, ref A, perm_c, perm_r, etree, equed, (double[])R, (double[])C, ref L, ref U, IntPtr.Zero, 0, ref B, ref X, out rpg, out rcond, null, null, ref glu, ref mem_usage, ref stat, out info); NativeMethods.StatFree(ref stat); options.Raw.Fact = Constants.FACTORED; } finally { InteropHelper.Free(h); } return(info); }
protected virtual void DoFactorize() { var h = new List <GCHandle>(); try { var A = CreateSparse(matrix, h); int ordering = (int)SpqrOrdering.Default; double tol = Constants.SPQR_DEFAULT_TOL; qr = NativeMethods.SuiteSparseQR_C_factorize(ordering, tol, ref A, ref common); if (common.status != Constants.CHOLMOD_OK) { throw new CholmodException(common.status); } } finally { InteropHelper.Free(h); } }
protected virtual void Dispose(bool disposing) { if (disposing) { InteropHelper.Free(handles); } // NOTE: cs_di_*free and cs_ci_*free both do the same, so there's // no need to move this method to the derived classes. if (N.L != IntPtr.Zero) { cs_nfree(ref N); N.L = IntPtr.Zero; } if (S.pinv != IntPtr.Zero || S.q != IntPtr.Zero) { cs_sfree(ref S); S.pinv = IntPtr.Zero; S.q = IntPtr.Zero; } }
protected virtual void DoSymbolic() { var h = new List <GCHandle>(); try { var A = CreateSparse(matrix, h); int ordering = (int)SpqrOrdering.Default; int allow_tol = 1; qr = NativeMethods.SuiteSparseQR_C_symbolic(ordering, allow_tol, ref A, ref common); if (common.status != Constants.CHOLMOD_OK) { throw new CholmodException(common.status); } } finally { InteropHelper.Free(h); } }
/// <summary> /// Initializes a new instance of the <see cref="CuSparseContext{T}"/> class. /// </summary> /// <param name="stream">The <see cref="CudaStream"/>.</param> /// <param name="A">The sparse matrix.</param> /// <param name="type">The matrix type.</param> /// <param name="transpose">A value indicating, whether the storage should be transposed.</param> public CuSparseContext(CudaStream stream, CompressedColumnStorage <T> A, MatrixType type, bool transpose) { Check(NativeMethods.cusparseCreate(ref _p)); Check(NativeMethods.cusparseSetStream(_p, stream.Pointer)); Check(NativeMethods.cusparseCreateMatDescr(ref _matDescr)); Check(NativeMethods.cusparseSetMatType(_matDescr, type)); Check(NativeMethods.cusparseSetMatIndexBase(_matDescr, IndexBase.Zero)); var sizeT = Marshal.SizeOf(typeof(T)); int rows = A.RowCount; int nnz = A.NonZerosCount; Cuda.Malloc(ref d_ap, sizeof(int) * (rows + 1)); Cuda.Malloc(ref d_ai, sizeof(int) * nnz); Cuda.Malloc(ref d_ax, sizeT * nnz); var handles = new List <GCHandle>(); try { // Convert storage to CSR format. var C = transpose ? A.Transpose(true) : A; var h_ap = InteropHelper.Pin(C.ColumnPointers, handles); var h_ai = InteropHelper.Pin(C.RowIndices, handles); var h_ax = InteropHelper.Pin(C.Values, handles); Cuda.CopyToDevice(d_ap, h_ap, sizeof(int) * (rows + 1)); Cuda.CopyToDevice(d_ai, h_ai, sizeof(int) * nnz); Cuda.CopyToDevice(d_ax, h_ax, sizeT * nnz); } finally { InteropHelper.Free(handles); } }
protected override int DoSolve(DenseColumnMajorStorage <double> input, DenseColumnMajorStorage <double> result) { int info = 0; var mem_usage = new mem_usage(); var stat = new SuperLUStat(); int nrhs = input.ColumnCount; var ferr = new double[nrhs]; var berr = new double[nrhs]; var h = new List <GCHandle>(); var B = CreateDense(Dtype.SLU_D, input, h); var X = CreateDense(Dtype.SLU_D, result, h); try { var o = options.Raw; NativeMethods.StatInit(ref stat); NativeMethods.dgssvx(ref o, ref A, perm_c, perm_r, etree, equed, (double[])R, (double[])C, ref L, ref U, IntPtr.Zero, 0, ref B, ref X, out rpg, out rcond, ferr, berr, ref glu, ref mem_usage, ref stat, out info); NativeMethods.StatFree(ref stat); } finally { InteropHelper.Free(h); } return(info); }
protected override int DoFactorize() { var h = new List <GCHandle>(); var A = CreateSparse(matrix, h); try { int order = (int)ordering; // ordering and symbolic analysis var pS = NativeMethods.cs_di_sqr(order, ref A, 0); if (pS == IntPtr.Zero) { return(-1); } S = Marshal.PtrToStructure <css>(pS); // numeric LU factorization var pN = NativeMethods.cs_di_lu(ref A, ref S, tol); if (pN == IntPtr.Zero) { return(-1); } N = Marshal.PtrToStructure <csn>(pN); } finally { InteropHelper.Free(h); } return(0); }
protected override int DoFactorize() { var h = new List <GCHandle>(); var A = CreateSparse(matrix, h); int m = matrix.RowCount; int n = matrix.ColumnCount; try { int order = (int)ordering; if (m >= n) { // ordering and symbolic analysis var pS = NativeMethods.cs_di_sqr(order, ref A, 1); if (pS == IntPtr.Zero) { return(-1); } S = Marshal.PtrToStructure <css>(pS); // numeric QR factorization var pN = NativeMethods.cs_di_qr(ref A, ref S); if (pN == IntPtr.Zero) { return(-1); } N = Marshal.PtrToStructure <csn>(pN); beta = new double[n]; // Copy beta values for later access. Marshal.Copy(N.B, beta, 0, n); } else { // Ax=b is underdetermined var pAT = NativeMethods.cs_di_transpose(ref A, 1); AT = Marshal.PtrToStructure <cs>(pAT); // ordering and symbolic analysis var pS = NativeMethods.cs_di_sqr(order, ref AT, 1); if (pS == IntPtr.Zero) { return(-1); } S = Marshal.PtrToStructure <css>(pS); // numeric QR factorization of A' var pN = NativeMethods.cs_di_qr(ref AT, ref S); if (pN == IntPtr.Zero) { return(-1); } N = Marshal.PtrToStructure <csn>(pN); beta = new double[m]; // Copy beta values for later access. Marshal.Copy(N.B, beta, 0, m); } if (w.Length < S.m2) { // Fix workspace length, if neccessary. w = new double[S.m2]; } } finally { InteropHelper.Free(h); } return(0); }
public override void Solve(double[] input, double[] result) { if (!factorized && DoFactorize() != 0) { throw new Exception(); // TODO: exception } var m = matrix.RowCount; var n = matrix.ColumnCount; var h = new List <GCHandle>(); var b = InteropHelper.Pin(input, h); var x = InteropHelper.Pin(result, h); var t = InteropHelper.Pin(w, h); try { // x = b(p) if (NativeMethods.cs_di_ipvec(N.pinv, b, t, n) == 0) { return; } // x = L\x if (NativeMethods.cs_di_lsolve(N.L, t) == 0) { return; } // x = U\x if (NativeMethods.cs_di_ltsolve(N.U, t) == 0) { return; } // b(q) = x if (NativeMethods.cs_di_pvec(S.q, t, x, n) == 0) { return; } } finally { InteropHelper.Free(h); } if (m >= n) { // x(0:m-1) = b(p(0:m-1) NativeMethods.cs_di_ipvec(S.pinv, b, x, m); // apply Householder refl. to x for (int k = 0; k < n; k++) { NativeMethods.cs_di_happly(N.L, k, beta[k], x); } // x = R\x NativeMethods.cs_di_usolve(N.U, x); // b(q(0:n-1)) = x(0:n-1) NativeMethods.cs_di_ipvec(S.q, x, b, n); } else { // x(q(0:m-1)) = b(0:m-1) NativeMethods.cs_di_pvec(S.q, b, x, m); // x = R'\x NativeMethods.cs_di_utsolve(N.U, x); // apply Householder refl. to x for (int k = m - 1; k >= 0; k--) { NativeMethods.cs_di_happly(N.L, k, beta[k], x); } // b(0:n-1) = x(p(0:n-1)) NativeMethods.cs_di_pvec(S.pinv, x, b, n); } }