/// <summary> /// Linear system solution x = inv(A) * b, with A being a triangular matrix in Skyline format. See /// https://software.intel.com/node/0a9d506f-d424-4651-8e68-16625ed412e7#0A9D506F-D424-4651-8E68-16625ED412E7 /// Warning: Intel MKL's Skyline format uses 1-based indexing and the non zero entries of each column are ordered from /// the top to the diagonal, if the upper triangle is stored. See /// https://software.intel.com/en-us/mkl-developer-reference-c-sparse-blas-skyline-matrix-storage-format /// In constrast, in the current version of our Skyline matrix, 0-based indexing is used and the entries of each column /// are ordered from the diagonal to the top. /// </summary> public void Dskysv(bool upper, int orderA, double[] valuesA, int[] colOffsetsA, double[] b, double[] x) { string trans = "N"; //TODO: not sure about this string matdscrA = "SUNF"; // symmetric, upper, non-unit, fortran indexing double alpha = 1.0; SpBlas.MklDskysv(trans, ref orderA, ref alpha, matdscrA, ref valuesA[0], ref colOffsetsA[0], ref b[0], ref x[0]); }
/// <summary> /// See /// https://software.intel.com/en-us/mkl-developer-reference-fortran-mkl-cspblas-csrgemv#9E1032C5-F844-42D4-A0F0-D62E52D77020 /// </summary> public void Dcsrgemv(bool transposeA, int numRowsA, int numColsA, double[] valuesA, int[] rowOffsetsA, int[] colIndicesA, double[] vectorX, int offsetX, double[] vectorY, int offsetY) { //TODO: For some reason, the resultis added to vector y, instead of overwritting it. Perhaps this behaviour is // different in the non-deprecated routines. if (transposeA) { Array.Clear(vectorY, offsetY, numColsA); // This MKL function is only for square CSR matrices. We can use it for rectangular too, but it overwrites memory // of the rhs vector y equal to the number of matrix rows. If the rhs vector is shorter than that, then the // remaining entries are overwritten with 0. However, this messes up the managed vector objects, since // important data is overwritten (why doesn't it throw access violation exception?). For now I am going to // use a temp array and then copy the relevant part. This problem does not seem to appear in the untransposeAd // version of the method. //TODO: Try using the SparseBLAS inspector-executor routines, instead of the deprecated dcsrgemv(). if (numColsA < numRowsA) // Do not use y.Length, since y can be an unrolled matrix { var temp = new double[numRowsA]; SpBlas.MklCspblasDcsrgemv("T", ref numRowsA, ref valuesA[0], ref rowOffsetsA[0], ref colIndicesA[0], ref vectorX[offsetX], ref temp[0]); Array.Copy(temp, 0, vectorY, offsetY, numColsA); } else { SpBlas.MklCspblasDcsrgemv("T", ref numRowsA, ref valuesA[0], ref rowOffsetsA[0], ref colIndicesA[0], ref vectorX[offsetX], ref vectorY[offsetY]); } } else { Array.Clear(vectorY, offsetY, numRowsA); SpBlas.MklCspblasDcsrgemv("N", ref numRowsA, ref valuesA[0], ref rowOffsetsA[0], ref colIndicesA[0], ref vectorX[offsetX], ref vectorY[offsetY]); } }