/// <summary> /// Create new sparse solve instance /// </summary> public CudaSolveSparse() { _handle = new cusolverSpHandle(); res = CudaSolveNativeMethods.Sparse.cusolverSpCreate(ref _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpDestroy", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// Create new refactorization solve instance /// </summary> public CudaSolveRefactorization() { _handle = new cusolverRfHandle(); res = CudaSolveNativeMethods.Refactorization.cusolverRfCreate(ref _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfCreate", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine allows direct access to the lower L and upper U triangular factors stored in /// the cuSolverRF library handle. The factors are compressed into a single matrix M=(LI)+ /// U, where the unitary diagonal of L is not stored. It is assumed that a prior call to the /// cusolverRfRefactor() was done in order to generate these triangular factors. /// </summary> /// <param name="n">Size of Matrix M (n x n)</param> /// <param name="h_nnzM">the number of non-zero elements of matrix M.</param> /// <param name="h_Mp">the array of offsets corresponding to the start of each row in the arrays Mi and Mx. /// This array has also an extra entry at the end that stores the number of non-zero elements in the matrix $M$. The array size is n+1.</param> /// <param name="h_Mi">the array of column indices corresponding to the non-zero elements in the matrix M. It is assumed that this array is sorted by row and by column within each row. The array size is nnzM.</param> /// <param name="h_Mx">the array of values corresponding to the non-zero elements in the matrix M. It is assumed that this array is sorted by row and by column within each row. The array size is nnzM.</param> public void ExtractBundledFactorsHost(int n, out int h_nnzM, out int[] h_Mp, out int[] h_Mi, out double[] h_Mx) { h_nnzM = 0; IntPtr mp = new IntPtr(); IntPtr mi = new IntPtr(); IntPtr mx = new IntPtr(); res = CudaSolveNativeMethods.Refactorization.cusolverRfExtractBundledFactorsHost(_handle, ref h_nnzM, ref mp, ref mi, ref mx); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfExtractBundledFactorsHost", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } if (h_nnzM == 0) { h_Mp = null; h_Mi = null; h_Mx = null; } else { h_Mp = new int[n + 1]; h_Mi = new int[h_nnzM]; h_Mx = new double[h_nnzM]; Marshal.Copy(mp, h_Mp, 0, n + 1); Marshal.Copy(mi, h_Mi, 0, h_nnzM); Marshal.Copy(mx, h_Mx, 0, h_nnzM); } }
/// <summary> /// To solve A_j * x_j = b_j, first we reform the equation by M_j * Q * x_j = P * b_j. Then do refactorization by /// cusolverRfBatch_Refactor(). Further cusolverRfBatch_Solve() takes over the remaining steps. /// </summary> /// <param name="P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="Q">the right permutation (often associated with reordering). The array size in n.</param> /// <param name="nrhs">the number right-hand-sides to be solved.</param> /// <param name="Temp">the dense matrix that contains temporary workspace (of size ldt*nrhs).</param> /// <param name="ldt">the leading dimension of dense matrix Temp (ldt >= n).</param> /// <param name="XF_array">array of pointers of size batchSize, each pointer points to the dense matrix that contains the right-hand-sides F and solutions X (of size ldxf*nrhs).</param> /// <param name="ldxf">the leading dimension of dense matrix XF (ldxf >= n).</param> public void cusolverRfBatchSolve(CudaDeviceVariable <int> P, CudaDeviceVariable <int> Q, int nrhs, double[] Temp, int ldt, double[][] XF_array, int ldxf) { int batchSize = XF_array.Length; IntPtr[] XF = new IntPtr[batchSize]; GCHandle[] handles = new GCHandle[batchSize]; try { for (int i = 0; i < batchSize; i++) { handles[i] = GCHandle.Alloc(XF_array[i], GCHandleType.Pinned); XF[i] = handles[i].AddrOfPinnedObject(); } res = CudaSolveNativeMethods.Refactorization.cusolverRfBatchSolve(_handle, P.DevicePointer, Q.DevicePointer, nrhs, Temp, ldt, XF, ldxf); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfBatchSolve", res)); } catch { throw; } finally { for (int i = 0; i < batchSize; i++) { handles[i].Free(); } } if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public CsrQrInfo() { _info = new csrqrInfo(); res = CudaSolveNativeMethods.Sparse.cusolverSpCreateCsrqrInfo(ref _info); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpCreateCsrqrInfo", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// </summary> public void SetSolverLowestPrecision(cusolverPrecType solver_main_precision) { res = CudaSolveNativeMethods.Dense.cusolverDnIRSParamsSetSolverLowestPrecision(_params, solver_main_precision); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSParamsSetSolverLowestPrecision", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void DisableFallback() { res = CudaSolveNativeMethods.Dense.cusolverDnIRSParamsDisableFallback(_params); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSParamsDisableFallback", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine sets the matrix format used in the cusolverRfSetup(), /// cusolverRfSetupHost(), cusolverRfResetValues(), cusolverRfExtractBundledFactorsHost() and cusolverRfExtractSplitFactorsHost() routines. /// </summary> /// <param name="format">the enumerated matrix format type.</param> /// <param name="diag">the enumerated unit diagonal type.</param> public void SetMatrixFormat(MatrixFormat format, UnitDiagonal diag) { res = CudaSolveNativeMethods.Refactorization.cusolverRfSetMatrixFormat(_handle, format, diag); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfSetMatrixFormat", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void SetSortEig(int sort_eig) { res = CudaSolveNativeMethods.Dense.cusolverDnXsyevjSetSortEig(_info, sort_eig); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnXsyevjSetSortEig", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void SetTol(double val) { res = CudaSolveNativeMethods.Dense.cusolverDnIRSParamsSetTol(_params, val); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSParamsSetTol", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine sets the mode used in the cusolverRfResetValues routine. /// </summary> /// <param name="fastMode">the enumerated mode type.</param> public void SetResetValuesFastMode(ResetValuesFastMode fastMode) { res = CudaSolveNativeMethods.Refactorization.cusolverRfSetResetValuesFastMode(_handle, fastMode); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfSetResetValuesFastMode", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine performs the LU re-factorization /// </summary> public void Refactor(cusolverRfHandle handle) { res = CudaSolveNativeMethods.Refactorization.cusolverRfRefactor(_handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfRefactor", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine performs the forward and backward solve with the lower and upper /// triangular factors resulting from the LU re-factorization /// </summary> /// <param name="P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="Q">the right permutation (often associated with reordering). The array size in n.</param> /// <param name="nrhs">the number right-hand-sides to be solved.</param> /// <param name="Temp">the dense matrix that contains temporary workspace (of size ldt*nrhs).</param> /// <param name="ldt">the leading dimension of dense matrix Temp (ldt >= n).</param> /// <param name="XF">the dense matrix that contains the righthand-sides F and solutions X (of size ldxf*nrhs).</param> /// <param name="ldxf">the leading dimension of dense matrix XF (ldxf >= n).</param> public void Solve(CudaDeviceVariable <int> P, CudaDeviceVariable <int> Q, int nrhs, double[] Temp, int ldt, double[] XF, int ldxf) { res = CudaSolveNativeMethods.Refactorization.cusolverRfSolve(_handle, P.DevicePointer, Q.DevicePointer, nrhs, Temp, ldt, XF, ldxf); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfSolve", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// The user can query which matrix failed LU refactorization by checking /// corresponding value in position array. The input parameter position is an integer array of size batchSize. /// </summary> /// <param name="position">integer array of size batchSize. The value of position(j) reports singularity /// of matrix Aj, -1 if no structural / numerical zero, k >= 0 if Aj(k,k) is either structural zero or numerical zero.</param> public void BatchZeroPivot(int[] position) { res = CudaSolveNativeMethods.Refactorization.cusolverRfBatchZeroPivot(_handle, position); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfBatchZeroPivot", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void SetMaxItersInner(int maxiters) { res = CudaSolveNativeMethods.Dense.cusolverDnIRSParamsSetMaxItersInner(_params, maxiters); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSParamsSetMaxItersInner", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void SetRefinementSolver(cusolverIRSRefinement refinement_solver) { res = CudaSolveNativeMethods.Dense.cusolverDnIRSParamsSetRefinementSolver(_params, refinement_solver); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSParamsSetRefinementSolver", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
public void SetAdvOptions(cusolverDnFunction function, cusolverAlgMode algo) { res = CudaSolveNativeMethods.Dense.cusolverDnSetAdvOptions(_params, function, algo); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnSetAdvOptions", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void RequestResidual() { res = CudaSolveNativeMethods.Dense.cusolverDnIRSInfosRequestResidual(_infos); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSInfosRequestResidual", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine gets the algorithm used for the refactorization in cusolverRfRefactor() /// and the triangular solve in cusolverRfSolve(). It may be called once prior to /// cusolverRfAnalyze() routine. /// </summary> /// <param name="factAlg">the enumerated algorithm type.</param> /// <param name="solveAlg">the enumerated algorithm type.</param> public void GetAlgs(ref Factorization factAlg, ref TriangularSolve solveAlg) { res = CudaSolveNativeMethods.Refactorization.cusolverRfGetAlgs(_handle, ref factAlg, ref solveAlg); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfGetAlgs", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine gets the report whether numeric boosting was used in the /// cusolverRfRefactor() and cusolverRfSolve() routines. /// </summary> /// <param name="report">the enumerated boosting report type.</param> public void GetNumericBoostReport(ref NumericBoostReport report) { res = CudaSolveNativeMethods.Refactorization.cusolverRfGetNumericBoostReport(_handle, ref report); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfGetNumericBoostReport", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine gets the numeric values used for checking for "zero" pivot and for boosting /// it in the cusolverRfRefactor() and cusolverRfSolve() routines. It may be called /// multiple times prior to cusolverRfRefactor() and cusolverRfSolve() routines. /// The numeric boosting will be used only if boost > 0.0. /// </summary> /// <param name="zero">the value below which zero pivot is flagged.</param> /// <param name="boost">the value which is substituted for zero pivot (if the later is flagged).</param> public void GetNumericProperties(ref double zero, ref double boost) { res = CudaSolveNativeMethods.Refactorization.cusolverRfGetNumericProperties(_handle, ref zero, ref boost); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfGetNumericProperties", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void SetMaxSweeps(int max_sweeps) { res = CudaSolveNativeMethods.Dense.cusolverDnXsyevjSetMaxSweeps(_info, max_sweeps); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnXsyevjSetMaxSweeps", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public void SetTolerance(double tolerance) { res = CudaSolveNativeMethods.Dense.cusolverDnXsyevjSetTolerance(_info, tolerance); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnXsyevjSetTolerance", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public CsrQrInfo() { _info = new csrqrInfo(); res = CudaSolveNativeMethods.Sparse.cusolverSpCreateCsrqrInfo(ref _info); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpCreateCsrqrInfo", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public IRSParams() { _params = new cusolverDnIRSParams(); res = CudaSolveNativeMethods.Dense.cusolverDnIRSParamsCreate(ref _params); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSParamsCreate", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// Create new refactorization solve instance /// </summary> public CudaSolveRefactorization() { _handle = new cusolverRfHandle(); res = CudaSolveNativeMethods.Refactorization.cusolverRfCreate(ref _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfCreate", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public GesvdjInfo() { _info = new gesvdjInfo(); res = CudaSolveNativeMethods.Dense.cusolverDnCreateGesvdjInfo(ref _info); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnCreateGesvdjInfo", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// For IDisposable /// </summary> /// <param name="fDisposing"></param> protected virtual void Dispose(bool fDisposing) { if (fDisposing && !disposed) { res = CudaSolveNativeMethods.Refactorization.cusolverRfDestroy(_handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfDestroy", res)); disposed = true; } if (!fDisposing && !disposed) Debug.WriteLine(String.Format("ManagedCUDA not-disposed warning: {0}", this.GetType())); }
/// <summary>This routine assembles the internal data structures of the cuSolverRF library. It is often /// the first routine to be called after the call to the cusolverRfCreate() routine. /// </summary> /// <param name="n">the number of rows (and columns) of matrix A.</param> /// <param name="nnzA">the number of non-zero elements of matrix A.</param> /// <param name="h_csrRowPtrA">the array of offsets corresponding to /// the start of each row in the arrays h_csrColIndA and h_csrValA. This /// array has also an extra entry at the end that stores the number of non-zero /// elements in the matrix. The array size is n+1.</param> /// <param name="h_csrColIndA">the array of column indices corresponding /// to the non-zero elements in the matrix. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzA.</param> /// <param name="h_csrValA">the array of values corresponding to the /// non-zero elements in the matrix. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzA.</param> /// <param name="nnzL">the number of non-zero elements of matrix L.</param> /// <param name="h_csrRowPtrL">the array of offsets corresponding to /// the start of each row in the arrays h_csrColIndL and h_csrValL. This /// array has also an extra entry at the end that stores the number of non-zero /// elements in the matrix L. The array size is n+1.</param> /// <param name="h_csrColIndL">the array of column indices corresponding /// to the non-zero elements in the matrix L. It is assumed that this array is sorted by /// row and by column within each row. The array size is nnzL.</param> /// <param name="h_csrValL">the array of values corresponding to the /// non-zero elements in the matrix L. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzL.</param> /// <param name="nnzU">the number of non-zero elements of matrix U.</param> /// <param name="h_csrRowPtrU">the array of offsets corresponding to /// the start of each row in the arrays h_csrColIndU and h_csrValU. This /// array has also an extra entry at the end that stores the number of non-zero elements in the matrix U. The array size is n+1.</param> /// <param name="h_csrColIndU">the array of column indices corresponding /// to the non-zero elements in the matrix U. It is assumed that this array is sorted by row and by column within each row. The array size is nnzU.</param> /// <param name="h_csrValU">the array of values corresponding to the non-zero elements in the matrix U. It is /// assumed that this array is sorted by row and by column within each row. The array size is nnzU.</param> /// <param name="h_P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="h_Q">the right permutation (often associated with reordering). The array size in n.</param> public void SetupHost(int n, int nnzA, int[] h_csrRowPtrA, int[] h_csrColIndA, double[] h_csrValA, int nnzL, int[] h_csrRowPtrL, int[] h_csrColIndL, double[] h_csrValL, int nnzU, int[] h_csrRowPtrU, int[] h_csrColIndU, double[] h_csrValU, int[] h_P, int[] h_Q) { res = CudaSolveNativeMethods.Refactorization.cusolverRfSetupHost(n, nnzA, h_csrRowPtrA, h_csrColIndA, h_csrValA, nnzL, h_csrRowPtrL, h_csrColIndL, h_csrValL, nnzU, h_csrRowPtrU, h_csrColIndU, h_csrValU, h_P, h_Q, _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfSetupHost", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// This routine updates internal data structures with the values of the new coefficient /// matrix. It is assumed that the arrays csrRowPtrA, csrColIndA, P and Q have not /// changed since the last call to the cusolverRfSetup[Host] routine. This assumption /// reflects the fact that the sparsity pattern of coefficient matrices as well as reordering to /// minimize fill-in and pivoting remain the same in the set of linear systems /// </summary> /// <param name="n">the number of rows (and columns) of matrix A.</param> /// <param name="nnzA">the number of non-zero elements of matrix A.</param> /// <param name="csrRowPtrA">the array of offsets corresponding to the start of each row in the arrays /// csrColIndA and csrValA. This array has also an extra entry at the end that stores the number of non-zero elements in the /// matrix. The array size is n+1.</param> /// <param name="csrColIndA">the array of column indices corresponding to the non-zero elements in the matrix. It /// is assumed that this array is sorted by row and by column within each row. The array size is nnzA.</param> /// <param name="csrValA">the array of values corresponding to the non-zero elements in the matrix. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzA.</param> /// <param name="P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="Q">the right permutation (often associated with reordering). The array size in n.</param> public void ResetValues(int n, int nnzA, CudaDeviceVariable <int> csrRowPtrA, CudaDeviceVariable <int> csrColIndA, CudaDeviceVariable <double> csrValA, CudaDeviceVariable <double> P, CudaDeviceVariable <double> Q) { res = CudaSolveNativeMethods.Refactorization.cusolverRfResetValues(n, nnzA, csrRowPtrA.DevicePointer, csrColIndA.DevicePointer, csrValA.DevicePointer, P.DevicePointer, Q.DevicePointer, _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfResetValues", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> internal IRSInfos(IRSParams aParams) { _params = aParams; _infos = new cusolverDnIRSInfos(); res = CudaSolveNativeMethods.Dense.cusolverDnIRSInfosCreate(aParams.Params, ref _infos); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSInfosCreate", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } }
/// <summary> /// </summary> public int GetMaxIters() { int val = 0; res = CudaSolveNativeMethods.Dense.cusolverDnIRSParamsGetMaxIters(_params, ref val); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSParamsGetMaxIters", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } return(val); }
/// <summary> /// </summary> public IntPtr GetResidualHistory() { IntPtr val = new IntPtr(); res = CudaSolveNativeMethods.Dense.cusolverDnIRSInfosGetResidualHistory(_infos, ref val); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverDnIRSInfosGetResidualHistory", res)); if (res != cusolverStatus.Success) { throw new CudaSolveException(res); } return(val); }
/// <summary> /// For IDisposable /// </summary> /// <param name="fDisposing"></param> protected virtual void Dispose(bool fDisposing) { if (fDisposing && !disposed) { //Ignore if failing res = CudaSolveNativeMethods.Sparse.cusolverSpDestroyCsrqrInfo(_info); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpDestroyCsrqrInfo", res)); disposed = true; } if (!fDisposing && !disposed) Debug.WriteLine(String.Format("ManagedCUDA not-disposed warning: {0}", this.GetType())); }
/// <summary> /// For IDisposable /// </summary> /// <param name="fDisposing"></param> protected virtual void Dispose(bool fDisposing) { if (fDisposing && !disposed) { res = CudaSolveNativeMethods.Refactorization.cusolverRfDestroy(_handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfDestroy", res)); disposed = true; } if (!fDisposing && !disposed) { Debug.WriteLine(String.Format("ManagedCUDA not-disposed warning: {0}", this.GetType())); } }
/// <summary> /// This routine gets the report whether numeric boosting was used in the /// cusolverRfRefactor() and cusolverRfSolve() routines. /// </summary> /// <param name="report">the enumerated boosting report type.</param> public void GetNumericBoostReport(ref NumericBoostReport report) { res = CudaSolveNativeMethods.Refactorization.cusolverRfGetNumericBoostReport(_handle, ref report); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfGetNumericBoostReport", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine gets the algorithm used for the refactorization in cusolverRfRefactor() /// and the triangular solve in cusolverRfSolve(). It may be called once prior to /// cusolverRfAnalyze() routine. /// </summary> /// <param name="factAlg">the enumerated algorithm type.</param> /// <param name="solveAlg">the enumerated algorithm type.</param> public void GetAlgs(ref Factorization factAlg, ref TriangularSolve solveAlg) { res = CudaSolveNativeMethods.Refactorization.cusolverRfGetAlgs(_handle, ref factAlg, ref solveAlg); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfGetAlgs", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine performs the forward and backward solve with the lower and upper /// triangular factors resulting from the LU re-factorization /// </summary> /// <param name="P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="Q">the right permutation (often associated with reordering). The array size in n.</param> /// <param name="nrhs">the number right-hand-sides to be solved.</param> /// <param name="Temp">the dense matrix that contains temporary workspace (of size ldt*nrhs).</param> /// <param name="ldt">the leading dimension of dense matrix Temp (ldt >= n).</param> /// <param name="XF">the dense matrix that contains the righthand-sides F and solutions X (of size ldxf*nrhs).</param> /// <param name="ldxf">the leading dimension of dense matrix XF (ldxf >= n).</param> public void Solve(CudaDeviceVariable<int> P, CudaDeviceVariable<int> Q, int nrhs, double[] Temp, int ldt, double[] XF, int ldxf) { res = CudaSolveNativeMethods.Refactorization.cusolverRfSolve(_handle, P.DevicePointer, Q.DevicePointer, nrhs, Temp, ldt, XF, ldxf); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfSolve", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This function solves the following least-square problem x = argmin||A*z-b|| /// </summary> /// <param name="m">number of rows of matrix A.</param> /// <param name="n">number of columns of matrix A.</param> /// <param name="nnz">number of nonzeros of matrix A.</param> /// <param name="descrA">the descriptor of matrix A. The supported matrix type is /// CUSPARSE_MATRIX_TYPE_GENERAL. Also, the supported index bases are CUSPARSE_INDEX_BASE_ZERO and CUSPARSE_INDEX_BASE_ONE.</param> /// <param name="csrValA">array of nnz (= csrRowPtrA(n) * csrRowPtrA(0)) nonzero elements of matrix A.</param> /// <param name="csrRowPtrA">integer array of n + 1 elements that contains the start of every row and the end of the last row plus one.</param> /// <param name="csrColIndA">integer array of nnz (=csrRowPtrA(n) * csrRowPtrA(0)) column indices of the nonzero elements of matrix A.</param> /// <param name="b">right hand side vector of size m.</param> /// <param name="tol">tolerance to decide rank of A.</param> /// <param name="rankA">numerical rank of A.</param> /// <param name="x">solution vector of size n, x=pinv(A)*b.</param> /// <param name="p">a vector of size n, which represents the permuation matrix P satisfying A*P^T=Q*R.</param> /// <param name="min_norm">||A*x-b||, x=pinv(A)*b.</param> public void CsrlsqvqrHost(int m, int n, int nnz, CudaSparseMatrixDescriptor descrA, cuDoubleComplex[] csrValA, int[] csrRowPtrA, int[] csrColIndA, cuDoubleComplex[] b, double tol, ref int rankA, cuDoubleComplex[] x, int[] p, ref double min_norm) { res = CudaSolveNativeMethods.Sparse.cusolverSpZcsrlsqvqrHost(_handle, m, n, nnz, descrA.Descriptor, csrValA, csrRowPtrA, csrColIndA, b, tol, ref rankA, x, p, ref min_norm); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpZcsrlsqvqrHost", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine gets the matrix format used in the cusolverRfSetup(), /// cusolverRfSetupHost(), cusolverRfResetValues(), cusolverRfExtractBundledFactorsHost() and cusolverRfExtractSplitFactorsHost() routines. /// </summary> /// <param name="format">the enumerated matrix format type.</param> /// <param name="diag">the enumerated unit diagonal type.</param> public void GetMatrixFormat(ref MatrixFormat format, ref UnitDiagonal diag) { res = CudaSolveNativeMethods.Refactorization.cusolverRfGetMatrixFormat(_handle, ref format, ref diag); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfGetMatrixFormat", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary/> public void CsreigsHost(int m, int nnz, CudaSparseMatrixDescriptor descrA, cuDoubleComplex[] csrValA, int[] csrRowPtrA, int[] csrColIndA, cuDoubleComplex left_bottom_corner, cuDoubleComplex right_upper_corner, ref int num_eigs) { res = CudaSolveNativeMethods.Sparse.cusolverSpZcsreigsHost(_handle, m, nnz, descrA.Descriptor, csrValA, csrRowPtrA, csrColIndA, left_bottom_corner, right_upper_corner, ref num_eigs); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpZcsreigsHost", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// /// </summary> /// <param name="error"></param> public CudaSolveException(cusolverStatus error) : base(GetErrorMessageFromCUResult(error)) { this._solverStatus = error; }
/// <summary> /// This routine performs the LU re-factorization /// </summary> public void Refactor(cusolverRfHandle handle) { res = CudaSolveNativeMethods.Refactorization.cusolverRfRefactor(_handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfRefactor", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine allows direct access to the lower L and upper U triangular factors stored in /// the cuSolverRF library handle. The factors are compressed into a single matrix M=(LI)+ /// U, where the unitary diagonal of L is not stored. It is assumed that a prior call to the /// cusolverRfRefactor() was done in order to generate these triangular factors. /// </summary> /// <param name="nnzM">the number of non-zero elements of matrix M.</param> /// <param name="Mp">the array of offsets corresponding to the start of each row in the arrays Mi and Mx. /// This array has also an extra entry at the end that stores the number of non-zero elements in the matrix $M$. The array size is n+1.</param> /// <param name="Mi">the array of column indices corresponding to the non-zero elements in the matrix M. It is assumed that this array is sorted by row and by column within each row. The array size is nnzM.</param> /// <param name="Mx">the array of values corresponding to the non-zero elements in the matrix M. It is assumed that this array is sorted by row and by column within each row. The array size is nnzM.</param> public void AccessBundledFactorsDevice(out int nnzM, out CudaDeviceVariable<int> Mp, out CudaDeviceVariable<int> Mi, out CudaDeviceVariable<double> Mx) { CUdeviceptr d_mp = new CUdeviceptr(); CUdeviceptr d_mi = new CUdeviceptr(); CUdeviceptr d_mx = new CUdeviceptr(); nnzM = 0; res = CudaSolveNativeMethods.Refactorization.cusolverRfAccessBundledFactorsDevice(_handle, ref nnzM, ref d_mp, ref d_mi, ref d_mx); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfAccessBundledFactorsDevice", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); Mp = new CudaDeviceVariable<int>(d_mp); Mi = new CudaDeviceVariable<int>(d_mi); Mx = new CudaDeviceVariable<double>(d_mx); }
/// <summary> /// This routine allows direct access to the lower L and upper U triangular factors stored in /// the cuSolverRF library handle. The factors are compressed into a single matrix M=(LI)+ /// U, where the unitary diagonal of L is not stored. It is assumed that a prior call to the /// cusolverRfRefactor() was done in order to generate these triangular factors. /// </summary> /// <param name="n">Size of Matrix M (n x n)</param> /// <param name="h_nnzM">the number of non-zero elements of matrix M.</param> /// <param name="h_Mp">the array of offsets corresponding to the start of each row in the arrays Mi and Mx. /// This array has also an extra entry at the end that stores the number of non-zero elements in the matrix $M$. The array size is n+1.</param> /// <param name="h_Mi">the array of column indices corresponding to the non-zero elements in the matrix M. It is assumed that this array is sorted by row and by column within each row. The array size is nnzM.</param> /// <param name="h_Mx">the array of values corresponding to the non-zero elements in the matrix M. It is assumed that this array is sorted by row and by column within each row. The array size is nnzM.</param> public void ExtractBundledFactorsHost(int n, out int h_nnzM, out int[] h_Mp, out int[] h_Mi, out double[] h_Mx) { h_nnzM = 0; IntPtr mp = new IntPtr(); IntPtr mi = new IntPtr(); IntPtr mx = new IntPtr(); res = CudaSolveNativeMethods.Refactorization.cusolverRfExtractBundledFactorsHost(_handle, ref h_nnzM, ref mp, ref mi, ref mx); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfExtractBundledFactorsHost", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); if (h_nnzM == 0) { h_Mp = null; h_Mi = null; h_Mx = null; } else { h_Mp = new int[n+1]; h_Mi = new int[h_nnzM]; h_Mx = new double[h_nnzM]; Marshal.Copy(mp, h_Mp, 0, n + 1); Marshal.Copy(mi, h_Mi, 0, h_nnzM); Marshal.Copy(mx, h_Mx, 0, h_nnzM); } }
/// <summary> /// This routine extracts lower (L) and upper (U) triangular factors from the /// cuSolverRF library handle into the host memory. It is assumed that a prior call to the /// cusolverRfRefactor() was done in order to generate these triangular factors. /// </summary> /// <param name="n">Size of Matrix M (n x n)</param> /// <param name="h_nnzL">the number of non-zero elements of matrix L.</param> /// <param name="h_csrRowPtrL">the array of offsets corresponding to the start of each row in the arrays h_Li and /// h_Lx. This array has also an extra entry at the end that stores the number of nonzero elements in the matrix L. The array size is n+1.</param> /// <param name="h_csrColIndL">the array of column indices corresponding to the non-zero elements in the matrix L. It is assumed that this array is sorted by /// row and by column within each row. The array size is h_nnzL.</param> /// <param name="h_csrValL">the array of values corresponding to the non-zero elements in the matrix L. It is assumed that this array is sorted by row /// and by column within each row. The array size is h_nnzL.</param> /// <param name="h_nnzU">the number of non-zero elements of matrix U.</param> /// <param name="h_csrRowPtrU">the array of offsets corresponding to the start of each row in the arrays h_Ui and h_Ux. This array has also an extra entry /// at the end that stores the number of nonzero elements in the matrix U. The array size is n+1.</param> /// <param name="h_csrColIndU">the array of column indices corresponding to the non-zero elements in the matrix U. It is assumed that this array is sorted by /// row and by column within each row. The array size is h_nnzU.</param> /// <param name="h_csrValU">the array of values corresponding to the non-zero elements in the matrix U. It is assumed that this array is sorted by row /// and by column within each row. The array size is h_nnzU.</param> public void ExtractSplitFactorsHost(int n, out int h_nnzL, out int[] h_csrRowPtrL, out int[] h_csrColIndL, out double[] h_csrValL, out int h_nnzU, out int[] h_csrRowPtrU, out int[] h_csrColIndU, out double[] h_csrValU) { h_nnzL = 0; h_nnzU = 0; IntPtr RowPtrL = new IntPtr(); IntPtr ColIndL = new IntPtr(); IntPtr ValL = new IntPtr(); IntPtr RowPtrU = new IntPtr(); IntPtr ColIndU = new IntPtr(); IntPtr ValU = new IntPtr(); res = CudaSolveNativeMethods.Refactorization.cusolverRfExtractSplitFactorsHost(_handle, ref h_nnzL, ref RowPtrL, ref ColIndL, ref ValL, ref h_nnzU, ref RowPtrU, ref ColIndU, ref ValU); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfExtractSplitFactorsHost", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); if (h_nnzL == 0) { h_csrRowPtrL = null; h_csrColIndL = null; h_csrValL = null; } else { h_csrRowPtrL = new int[n + 1]; h_csrColIndL = new int[h_nnzL]; h_csrValL = new double[h_nnzL]; Marshal.Copy(RowPtrL, h_csrRowPtrL, 0, n + 1); Marshal.Copy(ColIndL, h_csrColIndL, 0, h_nnzL); Marshal.Copy(ValL, h_csrValL, 0, h_nnzL); } if (h_nnzU == 0) { h_csrRowPtrU = null; h_csrColIndU = null; h_csrValU = null; } else { h_csrRowPtrU = new int[n + 1]; h_csrColIndU = new int[h_nnzU]; h_csrValU = new double[h_nnzU]; Marshal.Copy(RowPtrU, h_csrRowPtrU, 0, n + 1); Marshal.Copy(ColIndU, h_csrColIndU, 0, h_nnzU); Marshal.Copy(ValU, h_csrValU, 0, h_nnzU); } }
/// <summary> /// This routine updates internal data structures with the values of the new coefficient /// matrix. It is assumed that the arrays csrRowPtrA, csrColIndA, P and Q have not /// changed since the last call to the cusolverRfbatch_setup_host routine. /// </summary> /// <param name="batchSize">the number of matrices in batched mode.</param> /// <param name="n">the number of rows (and columns) of matrix A.</param> /// <param name="nnzA">the number of non-zero elements of matrix A.</param> /// <param name="csrRowPtrA">the array of offsets corresponding to the start of each row in the arrays csrColIndA and csrValA. /// This array has also an extra entry at the end that stores the number of non-zero elements in the matrix. The array size is n+1.</param> /// <param name="csrColIndA">the array of column indices corresponding to the non-zero elements in the matrix. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzA.</param> /// <param name="csrValA_array">array of pointers of size batchSize, each pointer points to the array of values corresponding to the non-zero elements in the matrix.</param> /// <param name="P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="Q">the right permutation (often associated with reordering). The array size in n.</param> public void BatchResetValues(int batchSize, int n, int nnzA, CudaDeviceVariable<int> csrRowPtrA, CudaDeviceVariable<int> csrColIndA, CudaDeviceVariable<double>[] csrValA_array, CudaDeviceVariable<int> P, CudaDeviceVariable<int> Q) { if (batchSize > csrValA_array.Length) { throw new ArgumentException("batchSize must be smaller or equal to the length of csrValA_array."); } CUdeviceptr[] valA = new CUdeviceptr[batchSize]; for (int i = 0; i < batchSize; i++) { valA[i] = csrValA_array[i].DevicePointer; } res = CudaSolveNativeMethods.Refactorization.cusolverRfBatchResetValues(batchSize, n, nnzA, csrRowPtrA.DevicePointer, csrColIndA.DevicePointer, valA, P.DevicePointer, Q.DevicePointer, _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfBatchResetValues", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine gets the numeric values used for checking for "zero" pivot and for boosting /// it in the cusolverRfRefactor() and cusolverRfSolve() routines. It may be called /// multiple times prior to cusolverRfRefactor() and cusolverRfSolve() routines. /// The numeric boosting will be used only if boost > 0.0. /// </summary> /// <param name="zero">the value below which zero pivot is flagged.</param> /// <param name="boost">the value which is substituted for zero pivot (if the later is flagged).</param> public void GetNumericProperties(ref double zero, ref double boost) { res = CudaSolveNativeMethods.Refactorization.cusolverRfGetNumericProperties(_handle, ref zero, ref boost); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfGetNumericProperties", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// Symmetric Approximate minimum degree algorithm based on quotient graph.<para/> /// This function implements Symmetric Approximate Minimum Degree Algorithm based /// on Quotient Graph. It returns a permutation vector p such that A(p,p) would have less /// zero fill-in during Cholesky factorization. /// </summary> /// <param name="n">number of rows and columns of matrix A.</param> /// <param name="nnzA">number of nonzeros of matrix A. It is the size of csrValA and csrColIndA.</param> /// <param name="descrA">the descriptor of matrix A. The supported matrix type is /// CUSPARSE_MATRIX_TYPE_GENERAL. Also, the supported index bases are CUSPARSE_INDEX_BASE_ZERO and CUSPARSE_INDEX_BASE_ONE.</param> /// <param name="csrRowPtrA">integer array of n + 1 elements that contains the start of every row and the end of the last row plus one.</param> /// <param name="csrColIndA">integer array of nnz (=csrRowPtrA(n) * csrRowPtrA(0)) column indices of the nonzero elements of matrix A.</param> /// <param name="p">permutation vector of size n.</param> public void CsrsymamdHost(int n, int nnzA, CudaSparseMatrixDescriptor descrA, int[] csrRowPtrA, int[] csrColIndA, int[] p) { res = CudaSolveNativeMethods.Sparse.cusolverSpXcsrsymamdHost(_handle, n, nnzA, descrA.Descriptor, csrRowPtrA, csrColIndA, p); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpXcsrsymamdHost", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// To solve A_j * x_j = b_j, first we reform the equation by M_j * Q * x_j = P * b_j. Then do refactorization by /// cusolverRfBatch_Refactor(). Further cusolverRfBatch_Solve() takes over the remaining steps. /// </summary> /// <param name="P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="Q">the right permutation (often associated with reordering). The array size in n.</param> /// <param name="nrhs">the number right-hand-sides to be solved.</param> /// <param name="Temp">the dense matrix that contains temporary workspace (of size ldt*nrhs).</param> /// <param name="ldt">the leading dimension of dense matrix Temp (ldt >= n).</param> /// <param name="XF_array">array of pointers of size batchSize, each pointer points to the dense matrix that contains the right-hand-sides F and solutions X (of size ldxf*nrhs).</param> /// <param name="ldxf">the leading dimension of dense matrix XF (ldxf >= n).</param> public void cusolverRfBatchSolve(CudaDeviceVariable<int> P, CudaDeviceVariable<int> Q, int nrhs, double[] Temp, int ldt, double[][] XF_array, int ldxf) { int batchSize = XF_array.Length; IntPtr[] XF = new IntPtr[batchSize]; GCHandle[] handles = new GCHandle[batchSize]; try { for (int i = 0; i < batchSize; i++) { handles[i] = GCHandle.Alloc(XF_array[i], GCHandleType.Pinned); XF[i] = handles[i].AddrOfPinnedObject(); } res = CudaSolveNativeMethods.Refactorization.cusolverRfBatchSolve(_handle, P.DevicePointer, Q.DevicePointer, nrhs, Temp, ldt, XF, ldxf); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfBatchSolve", res)); } catch { throw; } finally { for (int i = 0; i < batchSize; i++) { handles[i].Free(); } } if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
private static string GetErrorMessageFromCUResult(cusolverStatus error) { string message = string.Empty; string correct = string.Empty; switch (error) { case cusolverStatus.Success: message = "No Error."; break; case cusolverStatus.NotInititialized: message = "The cuSolver library was not initialized. This is usually caused by the lack of a prior call, an error in the CUDA Runtime API called by the cuSolver routine, or an error in the hardware setup."; correct = "\nTo correct: call cusolverCreate() prior to the function call; and check that the hardware, an appropriate version of the driver, and the cuSolver library are correctly installed."; break; case cusolverStatus.AllocFailed: message = "Resource allocation failed inside the cuSolver library. This is usually caused by a cudaMalloc() failure."; correct = "\nTo correct: prior to the function call, deallocate previously allocated memory as much as possible."; break; case cusolverStatus.InvalidValue: message = "An unsupported value or parameter was passed to the function (a negative vector size, for example)."; correct = "\nTo correct: ensure that all the parameters being passed have valid values."; break; case cusolverStatus.ArchMismatch: message = "The function requires a feature absent from the device architecture; usually caused by the lack of support for atomic operations or double precision."; correct = "\nTo correct: compile and run the application on a device with compute capability 2.0 or above."; break; case cusolverStatus.MappingError: message = ""; correct = ""; break; case cusolverStatus.ExecutionFailed: message = "The GPU program failed to execute. This is often caused by a launch failure of the kernel on the GPU, which can be caused by multiple reasons."; correct = "\nTo correct: check that the hardware, an appropriate version of the driver, and the cuSolver library are correctly installed."; break; case cusolverStatus.InternalError: message = "An internal cuSolver operation failed. This error is usually caused by a cudaMemcpyAsync() failure."; correct = "\nTo correct: check that the hardware, an appropriate version of the driver, and the cuSolver library are correctly installed. Also, check that the memory passed as a parameter to the routine is not being deallocated prior to the routine’s completion."; break; case cusolverStatus.MatrixTypeNotSupported: message = "The matrix type is not supported by this function. This is usually caused by passing an invalid matrix descriptor to the function."; correct = "\nTo correct: check that the fields in descrA were set correctly."; break; case cusolverStatus.NotSupported: message = ""; correct = ""; break; case cusolverStatus.ZeroPivot: message = ""; correct = ""; break; case cusolverStatus.InvalidLicense: message = ""; correct = ""; break; default: break; } return error.ToString() + ": " + message + correct; }
/// <summary>This routine assembles the internal data structures of the cuSolverRF library. It is often /// the first routine to be called after the call to the cusolverRfCreate() routine. /// </summary> /// <param name="n">the number of rows (and columns) of matrix A.</param> /// <param name="nnzA">the number of non-zero elements of matrix A.</param> /// <param name="h_csrRowPtrA">the array of offsets corresponding to /// the start of each row in the arrays h_csrColIndA and h_csrValA. This /// array has also an extra entry at the end that stores the number of non-zero /// elements in the matrix. The array size is n+1.</param> /// <param name="h_csrColIndA">the array of column indices corresponding /// to the non-zero elements in the matrix. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzA.</param> /// <param name="h_csrValA">the array of values corresponding to the /// non-zero elements in the matrix. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzA.</param> /// <param name="nnzL">the number of non-zero elements of matrix L.</param> /// <param name="h_csrRowPtrL">the array of offsets corresponding to /// the start of each row in the arrays h_csrColIndL and h_csrValL. This /// array has also an extra entry at the end that stores the number of non-zero /// elements in the matrix L. The array size is n+1.</param> /// <param name="h_csrColIndL">the array of column indices corresponding /// to the non-zero elements in the matrix L. It is assumed that this array is sorted by /// row and by column within each row. The array size is nnzL.</param> /// <param name="h_csrValL">the array of values corresponding to the /// non-zero elements in the matrix L. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzL.</param> /// <param name="nnzU">the number of non-zero elements of matrix U.</param> /// <param name="h_csrRowPtrU">the array of offsets corresponding to /// the start of each row in the arrays h_csrColIndU and h_csrValU. This /// array has also an extra entry at the end that stores the number of non-zero elements in the matrix U. The array size is n+1.</param> /// <param name="h_csrColIndU">the array of column indices corresponding /// to the non-zero elements in the matrix U. It is assumed that this array is sorted by row and by column within each row. The array size is nnzU.</param> /// <param name="h_csrValU">the array of values corresponding to the non-zero elements in the matrix U. It is /// assumed that this array is sorted by row and by column within each row. The array size is nnzU.</param> /// <param name="h_P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="h_Q">the right permutation (often associated with reordering). The array size in n.</param> public void SetupHost(int n, int nnzA, int[] h_csrRowPtrA, int[] h_csrColIndA, double[] h_csrValA, int nnzL, int[] h_csrRowPtrL, int[] h_csrColIndL, double[] h_csrValL, int nnzU, int[] h_csrRowPtrU, int[] h_csrColIndU, double[] h_csrValU, int[] h_P, int[] h_Q) { res = CudaSolveNativeMethods.Refactorization.cusolverRfSetupHost(n, nnzA, h_csrRowPtrA, h_csrColIndA, h_csrValA, nnzL, h_csrRowPtrL, h_csrColIndL, h_csrValL, nnzU, h_csrRowPtrU, h_csrColIndU, h_csrValU, h_P, h_Q, _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfSetupHost", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This function solves the simple eigenvalue problem A*x=lambda*x by shift-inverse method. /// </summary> /// <param name="m">number of rows and columns of matrix A.</param> /// <param name="nnz">number of nonzeros of matrix A.</param> /// <param name="descrA">the descriptor of matrix A. The supported matrix type is /// CUSPARSE_MATRIX_TYPE_GENERAL. Also, the supported index bases are CUSPARSE_INDEX_BASE_ZERO and CUSPARSE_INDEX_BASE_ONE.</param> /// <param name="csrValA">array of nnz (= csrRowPtrA(n) * csrRowPtrA(0)) nonzero elements of matrix A.</param> /// <param name="csrRowPtrA">integer array of n + 1 elements that contains the start of every row and the end of the last row plus one.</param> /// <param name="csrColIndA">integer array of nnz (=csrRowPtrA(n) * csrRowPtrA(0)) column indices of the nonzero elements of matrix A.</param> /// <param name="mu0">initial guess of eigenvalue.</param> /// <param name="x0">initial guess of eigenvector, a vecotr of size m.</param> /// <param name="maxite">maximum iterations in shift-inverse method.</param> /// <param name="tol">tolerance for convergence.</param> /// <param name="mu">approximated eigenvalue nearest mu0 under tolerance.</param> /// <param name="x">approximated eigenvector of size m.</param> public void Csreigvsi(int m, int nnz, CudaSparseMatrixDescriptor descrA, CudaDeviceVariable<cuDoubleComplex> csrValA, CudaDeviceVariable<int> csrRowPtrA, CudaDeviceVariable<int> csrColIndA, cuDoubleComplex mu0, CudaDeviceVariable<cuDoubleComplex> x0, int maxite, double tol, ref cuDoubleComplex mu, CudaDeviceVariable<cuDoubleComplex> x) { res = CudaSolveNativeMethods.Sparse.cusolverSpZcsreigvsi(_handle, m, nnz, descrA.Descriptor, csrValA.DevicePointer, csrRowPtrA.DevicePointer, csrColIndA.DevicePointer, mu0, x0.DevicePointer, maxite, tol, ref mu, x.DevicePointer); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpZcsreigvsi", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// /// </summary> /// <param name="error"></param> /// <param name="message"></param> /// <param name="exception"></param> public CudaSolveException(cusolverStatus error, string message, Exception exception) : base(message, exception) { this._solverStatus = error; }
/// <summary> /// This function solves the simple eigenvalue problem A*x=lambda*x by shift-inverse method. /// </summary> /// <param name="m">number of rows and columns of matrix A.</param> /// <param name="nnz">number of nonzeros of matrix A.</param> /// <param name="descrA">the descriptor of matrix A. The supported matrix type is /// CUSPARSE_MATRIX_TYPE_GENERAL. Also, the supported index bases are CUSPARSE_INDEX_BASE_ZERO and CUSPARSE_INDEX_BASE_ONE.</param> /// <param name="csrValA">array of nnz (= csrRowPtrA(n) * csrRowPtrA(0)) nonzero elements of matrix A.</param> /// <param name="csrRowPtrA">integer array of n + 1 elements that contains the start of every row and the end of the last row plus one.</param> /// <param name="csrColIndA">integer array of nnz (=csrRowPtrA(n) * csrRowPtrA(0)) column indices of the nonzero elements of matrix A.</param> /// <param name="mu0">initial guess of eigenvalue.</param> /// <param name="x0">initial guess of eigenvector, a vecotr of size m.</param> /// <param name="maxite">maximum iterations in shift-inverse method.</param> /// <param name="tol">tolerance for convergence.</param> /// <param name="mu">approximated eigenvalue nearest mu0 under tolerance.</param> /// <param name="x">approximated eigenvector of size m.</param> public void CsreigvsiHost(int m, int nnz, CudaSparseMatrixDescriptor descrA, cuDoubleComplex[] csrValA, int[] csrRowPtrA, int[] csrColIndA, cuDoubleComplex mu0, cuDoubleComplex[] x0, int maxite, double tol, ref cuDoubleComplex mu, cuDoubleComplex[] x) { res = CudaSolveNativeMethods.Sparse.cusolverSpZcsreigvsiHost(_handle, m, nnz, descrA.Descriptor, csrValA, csrRowPtrA, csrColIndA, mu0, x0, maxite, tol, ref mu, x); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpZcsreigvsiHost", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine sets the mode used in the cusolverRfResetValues routine. /// </summary> /// <param name="fastMode">the enumerated mode type.</param> public void SetResetValuesFastMode(ResetValuesFastMode fastMode) { res = CudaSolveNativeMethods.Refactorization.cusolverRfSetResetValuesFastMode(_handle, fastMode); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfSetResetValuesFastMode", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This function solves the linear system A*x=b /// </summary> /// <param name="m">number of rows and columns of matrix A.</param> /// <param name="nnz">number of nonzeros of matrix A.</param> /// <param name="descrA">the descriptor of matrix A. The supported matrix type is /// CUSPARSE_MATRIX_TYPE_GENERAL. Also, the supported index bases are CUSPARSE_INDEX_BASE_ZERO and CUSPARSE_INDEX_BASE_ONE.</param> /// <param name="csrValA">array of nnz (= csrRowPtrA(n) * csrRowPtrA(0)) nonzero elements of matrix A.</param> /// <param name="csrRowPtrA">integer array of n + 1 elements that contains the start of every row and the end of the last row plus one.</param> /// <param name="csrColIndA">integer array of nnz (=csrRowPtrA(n) * csrRowPtrA(0)) column indices of the nonzero elements of matrix A.</param> /// <param name="b">right hand side vector of size m.</param> /// <param name="tol">tolerance to decide singularity.</param> /// <param name="reorder">no effect.</param> /// <param name="x">solution vector of size m, x = inv(A)*b.</param> /// <returns>-1 if A is invertible. Otherwise, first index j such that U(j,j)≈0</returns> public int Csrlsvchol(int m, int nnz, CudaSparseMatrixDescriptor descrA, CudaDeviceVariable<cuDoubleComplex> csrValA, CudaDeviceVariable<int> csrRowPtrA, CudaDeviceVariable<int> csrColIndA, CudaDeviceVariable<cuDoubleComplex> b, float tol, int reorder, CudaDeviceVariable<cuDoubleComplex> x) { int singularity = 0; res = CudaSolveNativeMethods.Sparse.cusolverSpZcsrlsvchol(_handle, m, nnz, descrA.Descriptor, csrValA.DevicePointer, csrRowPtrA.DevicePointer, csrColIndA.DevicePointer, b.DevicePointer, tol, reorder, x.DevicePointer, ref singularity); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverSpZcsrlsvchol", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); return singularity; }
/// <summary> /// This routine assembles the internal data structures of the cuSolverRF library for batched /// operation. It is called after the call to the cusolverRfCreate() routine, and before any /// other batched routines. /// </summary> /// <param name="batchSize">the number of matrices in the batched mode.</param> /// <param name="n">the number of rows (and columns) of matrix A.</param> /// <param name="nnzA">the number of non-zero elements of matrix A.</param> /// <param name="h_csrRowPtrA">the array of offsets corresponding to /// the start of each row in the arrays h_csrColIndA and h_csrValA. This array has also an extra entry at the /// end that stores the number of non-zero elements in the matrix. The array size is n+1.</param> /// <param name="h_csrColIndA">the array of column indices corresponding /// to the non-zero elements in the matrix. It is assumed that this array is sorted by row and by column within each row. The array size is nnzA.</param> /// <param name="h_csrValA_array">array of pointers of size batchSize, each pointer points to the array of values corresponding to the non-zero elements in the matrix.</param> /// <param name="nnzL">the number of non-zero elements of matrix L.</param> /// <param name="h_csrRowPtrL">the array of offsets corresponding to the start of each row in the arrays h_csrColIndL and h_csrValL. This /// array has also an extra entry at the end that stores the number of non-zero elements in the matrix L. The array size is n+1.</param> /// <param name="h_csrColIndL">the array of column indices corresponding to the non-zero elements in the matrix L. It is assumed that this array is sorted by /// row and by column within each row. The array size is nnzL.</param> /// <param name="h_csrValL">the array of values corresponding to the non-zero elements in the matrix L. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzL.</param> /// <param name="nnzU">the number of non-zero elements of matrix U.</param> /// <param name="h_csrRowPtrU">the array of offsets corresponding to the start of each row in the arrays h_csrColIndU and h_csrValU. This /// array has also an extra entry at the end that stores the number of non-zero elements in the matrix U. The array size is n+1.</param> /// <param name="h_csrColIndU">the array of column indices corresponding to the non-zero elements in the matrix U. It is assumed that this array is sorted by /// row and by column within each row. The array size is nnzU.</param> /// <param name="h_csrValU">the array of values corresponding to the non-zero elements in the matrix U. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzU.</param> /// <param name="h_P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="h_Q">the right permutation (often associated with reordering). The array size in n.</param> /// <param name="handle">the pointer to the cuSolverRF library handle.</param> public void BatchSetupHost(int batchSize, int n, int nnzA, int[] h_csrRowPtrA, int[] h_csrColIndA, double[][] h_csrValA_array, int nnzL, int[] h_csrRowPtrL, int[] h_csrColIndL, double[] h_csrValL, int nnzU, int[] h_csrRowPtrU, int[] h_csrColIndU, double[] h_csrValU, int[] h_P, int[] h_Q, cusolverRfHandle handle) { if (batchSize > h_csrValA_array.Length) { throw new ArgumentException("batchSize must be smaller or equal to the length of h_csrValA_array."); } IntPtr[] valA = new IntPtr[batchSize]; GCHandle[] handles = new GCHandle[batchSize]; try { for (int i = 0; i < batchSize; i++) { handles[i] = GCHandle.Alloc(h_csrValA_array[i], GCHandleType.Pinned); valA[i] = handles[i].AddrOfPinnedObject(); } res = CudaSolveNativeMethods.Refactorization.cusolverRfBatchSetupHost(batchSize, n, nnzA, h_csrRowPtrA, h_csrColIndA, valA, nnzL, h_csrRowPtrL, h_csrColIndL, h_csrValL, nnzU, h_csrRowPtrU, h_csrColIndU, h_csrValU, h_P, h_Q, _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfBatchSetupHost", res)); } catch { throw; } finally { for (int i = 0; i < batchSize; i++) { handles[i].Free(); } } if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// This routine updates internal data structures with the values of the new coefficient /// matrix. It is assumed that the arrays csrRowPtrA, csrColIndA, P and Q have not /// changed since the last call to the cusolverRfSetup[Host] routine. This assumption /// reflects the fact that the sparsity pattern of coefficient matrices as well as reordering to /// minimize fill-in and pivoting remain the same in the set of linear systems /// </summary> /// <param name="n">the number of rows (and columns) of matrix A.</param> /// <param name="nnzA">the number of non-zero elements of matrix A.</param> /// <param name="csrRowPtrA">the array of offsets corresponding to the start of each row in the arrays /// csrColIndA and csrValA. This array has also an extra entry at the end that stores the number of non-zero elements in the /// matrix. The array size is n+1.</param> /// <param name="csrColIndA">the array of column indices corresponding to the non-zero elements in the matrix. It /// is assumed that this array is sorted by row and by column within each row. The array size is nnzA.</param> /// <param name="csrValA">the array of values corresponding to the non-zero elements in the matrix. It is assumed that this array is sorted by row /// and by column within each row. The array size is nnzA.</param> /// <param name="P">the left permutation (often associated with pivoting). The array size in n.</param> /// <param name="Q">the right permutation (often associated with reordering). The array size in n.</param> public void ResetValues(int n, int nnzA, CudaDeviceVariable<int> csrRowPtrA, CudaDeviceVariable<int> csrColIndA, CudaDeviceVariable<double> csrValA, CudaDeviceVariable<double> P, CudaDeviceVariable<double> Q) { res = CudaSolveNativeMethods.Refactorization.cusolverRfResetValues(n, nnzA, csrRowPtrA.DevicePointer, csrColIndA.DevicePointer, csrValA.DevicePointer, P.DevicePointer, Q.DevicePointer, _handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfResetValues", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }
/// <summary> /// The user can query which matrix failed LU refactorization by checking /// corresponding value in position array. The input parameter position is an integer array of size batchSize. /// </summary> /// <param name="position">integer array of size batchSize. The value of position(j) reports singularity /// of matrix Aj, -1 if no structural / numerical zero, k >= 0 if Aj(k,k) is either structural zero or numerical zero.</param> public void BatchZeroPivot(int[] position) { res = CudaSolveNativeMethods.Refactorization.cusolverRfBatchZeroPivot(_handle, position); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cusolverRfBatchZeroPivot", res)); if (res != cusolverStatus.Success) throw new CudaSolveException(res); }