行列ストレージ#

DPC++ 用の oneMKL BLAS および LAPACK ルーチンは、いくつかの行列およびベクトルのストレージ形式を使用します。これらは、従来の Fortran BLAS/LAPACK で使用される形式と同じです。

一般的な行列#

先頭次元 lda を持つ mn 列の一般行列 A は、列優先レイアウトが使用されている場合は lda * n 以上のサイズの 1 次元配列 a として表され、行優先レイアウトが使用されている場合は lda * m 以上のサイズの 1 次元配列 a として表されます。一般行列を使用する BLAS 関数に入る前に、配列 a の先頭の mn 列に行列 A が含まれている必要があります。列 (それぞれ、行) 優先レイアウトの場合、各列 (それぞれ、行) の要素はメモリー内で連続していますが、各行 (それぞれ、列) の要素は、前の行 (それぞれ、列) の同じ要素から距離 lda にあります。

視覚的に、行列

\[\begin{split}A = \begin{bmatrix} A_{11} & A_{12} & A_{13} & \ldots & A_{1n}\\ A_{21} & A_{22} & A_{23} & \ldots & A_{2n}\\ A_{31} & A_{32} & A_{33} & \ldots & A_{3n}\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ A_{m1} & A_{m2} & A_{m3} & \ldots & A_{mn} \end{bmatrix}\end{split}\]

は、配列としてメモリーに保存されます

列優先レイアウトの場合

\[\scriptstyle a = [\underbrace{\underbrace{A_{11},A_{21},A_{31},...,A_{m1},*,...,*}_\text{lda}, \underbrace{A_{12},A_{22},A_{32},...,A_{m2},*,...,*}_\text{lda}, ..., \underbrace{A_{1n},A_{2n},A_{3n},...,A_{mn},*,...,*}_\text{lda}} _\text{lda x n}]\]

行優先レイアウトの場合

\[\scriptstyle a = [\underbrace{\underbrace{A_{11},A_{12},A_{13},...,A_{1n},*,...,*}_\text{lda}, \underbrace{A_{21},A_{22},A_{23},...,A_{2n},*,...,*}_\text{lda}, ..., \underbrace{A_{m1},A_{m2},A_{m3},...,A_{mn},*,...,*}_\text{lda}} _\text{m x lda}]\]

三角行列#

先頭次元 lda を持つ nn 列の三角行列 A は、lda * n 以上のサイズの 1 次元配列 a として表されます。列 (それぞれ、行) 優先レイアウトを使用する場合、各列 (それぞれ、行) の要素はメモリー内で連続していますが、各行 (それぞれ、列) の要素は、前の行 (それぞれ、列) の同じ要素から距離 lda にあります。

一般行列を使用する BLAS 関数に入る前に、upper_lower = uplo::upper の場合、配列 a の先頭の n x n 上三角部分に、行列 A の上三角部分が含まれている必要があります。

  • 配列 a の下三角部分は厳密に参照されません。つまり、行列

    \[\begin{split}A = \begin{bmatrix} A_{11} & A_{12} & A_{13} & \ldots & A_{1n}\\ * & A_{22} & A_{23} & \ldots & A_{2n}\\ * & * & A_{33} & \ldots & A_{3n}\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ * & * & * & \ldots & A_{nn} \end{bmatrix}\end{split}\]

    は、配列としてメモリーに保存されます

    • 列優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{\underbrace{A_{11},*,...,*}_\text{lda}, \underbrace{A_{12},A_{22},*,...,*}_\text{lda}, ..., \underbrace{A_{1n},A_{2n},A_{3n},...,A_{nn},*,...,*}_\text{lda}} _\text{lda x n}]\]
    • 行優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{\underbrace{A_{11},A_{12},A_{13},...,A_{1n},*,...,*}_\text{lda}, \underbrace{*,A_{22},A_{23},...,A_{2n},*,...,*}_\text{lda}, ..., \underbrace{*,...,*,A_{nn},*,...,*}_\text{lda}} _\text{lda x n}]\]
  • upper_lower = uplo::lower の場合、配列 a の先頭の n × n 下三角部分には、行列 A の下三角部分が含まれている必要があります。配列 a の上三角部分は厳密に参照されません。つまり、行列

    \[\begin{split}A = \begin{bmatrix} A_{11} & * & * & \ldots & * \\ A_{21} & A_{22} & * & \ldots & * \\ A_{31} & A_{32} & A_{33} & \ldots & * \\ \vdots & \vdots & \vdots & \ddots & \vdots\\ A_{n1} & A_{n2} & A_{n3} & \ldots & A_{nn} \end{bmatrix}\end{split}\]

    は、配列としてメモリーに保存されます

    • 列優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{\underbrace{A_{11},A_{21},A_{31},..,A_{n1},*,...,*}_\text{lda}, \underbrace{*,A_{22},A_{32},...,A_{n2},*,...,*}_\text{lda}, ..., \underbrace{*,...,*,A_{nn},*,...,*}_\text{lda}} _\text{lda x n}]\]
    • 行優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{\underbrace{A_{11},*,...,*}_\text{lda}, \underbrace{A_{21},A_{22},*,...,*}_\text{lda}, ..., \underbrace{A_{n1},A_{n2},A_{n3},...,A_{nn},*,...,*}_\text{lda}} _\text{lda x n}]\]

帯行列#

kl 個の副対角要素、ku 個の上対角要素、および主要次元 lda を持つ mn 列の一般帯行列 A は、列 (​​または行) 優先レイアウトが使用される場合、lda * n (または lda * m) 以上のサイズの 1 次元配列 a として表されます。

一般帯行列を使用する BLAS 関数に入る前に、配列 a の先頭の (kl + ku + 1) x n (それぞれ m) の部分に行列 A が含まれている必要があります。この行列は列ごとに (それぞれ行ごとに) 指定する必要があり、行列の主対角線は配列の行 ku (それぞれ列 kl) にあり (0 ベースのインデックス)、最初の上対角線は行 (ku – 1) (それぞれ列 (kl + 1)) の位置 1 (それぞれ 0) から始まり、最初の下対角線は行 (ku + 1) (それぞれ列 (kl – 1)) の位置 0 (それぞれ 1) から始まり、以下同様に続きます。帯行列の要素に対応しない配列 a の要素 (左上の kuku 列の三角形など) は参照されません。

視覚的に、行列 A

\[\begin{split}A = \left[\begin{smallmatrix} A_{11} & A_{12} & A_{13} & \ldots & A_{1,ku+1} & * & \ldots & \ldots & \ldots & \ldots & \ldots & * \\ A_{21} & A_{22} & A_{23} & A_{24} & \ldots & A_{2,ku+2} & * & \ldots & \ldots & \ldots & \ldots & * \\ A_{31} & A_{32} & A_{33} & A_{34} & A_{35} & \ldots & A_{3,ku+3} & * & \ldots & \ldots & \ldots & * \\ \vdots & A_{42} & A_{43} & \ddots & \ddots & \ddots & \ddots & \ddots & * & \ldots & \ldots & \vdots \\ A_{kl+1,1} & \vdots & A_{53} & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & * & \ldots & \vdots \\ * & A_{kl+2,2} & \vdots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \vdots \\ \vdots & * & A_{kl+3,3} & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & * \\ \vdots & \vdots & * & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & A_{n-ku,n}\\ \vdots & \vdots & \vdots & * & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \vdots \\ \vdots & \vdots & \vdots & \vdots & * & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & A_{m-2,n} \\ \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & A_{m-1,n} \\ * & * & * & \ldots & \ldots & \ldots & * & A_{m,m-kl} & \ldots & A_{m,n-2} & A_{m,n-1} & A_{m,n} \end{smallmatrix}\right]\end{split}\]

は、配列としてメモリーに保存されます

列優先レイアウトの場合

列優先レイアウト

行優先レイアウトの場合

行優先レイアウト

次のプログラムセグメントは、帯行列を従来の完全な行列ストレージ (先頭の次元が ldm の変数 matrix) から帯ストレージ (先頭の次元が lda の変数 a) に転送します。

  • 列優先レイアウトを使用

    for (j = 0; j < n; j++) { 
        k = ku – j; 
        for (i = max(0, j – ku); i < min(m, j + kl + 1); i++) { 
            a[(k + i) + j * lda] = matrix[i + j * ldm]; 
        } 
    }
  • 行優先レイアウトを使用

    for (i = 0; i < m; i++) { 
        k = kl – i; 
        for (j = max(0, i – kl); j < min(n, i + ku + 1); j++) { 
            a[(k + j) + i * lda] = matrix[j + i * ldm]; 
        } 
    }

三角帯行列#

k 個のサブ/スーパー対角要素と主要次元 lda を持つ nn 列の三角帯行列 A は、lda * n 以上のサイズの 1 次元配列 a として表されます。

三角帯行列を使用する BLAS 関数に入る前に、upper_lower = uplo::upper の場合、配列 a の先頭の (k + 1) x n 部分に行列 A の上三角帯部分が含まれている必要があります。

  • 列優先レイアウトを使用する場合、この行列は、配列の行 (k) (列 0) に行列の主対角線、行 (k - 1) (列 1) の位置 1 (0) から始まる最初の上対角線などを使用して、列ごとに (行ごとに) 指定する必要があります。三角帯行列の要素に対応しない配列 a の要素 (左下の kk 列の三角形など) は参照されません。

視覚的に、行列

\[\begin{split}A = \left[\begin{smallmatrix} A_{11} & A_{12} & A_{13} & \ldots & A_{1,k+1} & * & \ldots & \ldots & \ldots & \ldots & \ldots & * \\ * & A_{22} & A_{23} & A_{24} & \ldots & A_{2,k+2} & * & \ldots & \ldots & \ldots & \ldots & * \\ \vdots & * & A_{33} & A_{34} & A_{35} & \ldots & A_{3,k+3} & * & \ldots & \ldots & \ldots & * \\ \vdots & \vdots & * & \ddots & \ddots & \ddots & \ddots & \ddots & * & \ldots & \ldots & \vdots \\ \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & * & \ldots & \vdots \\ \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \vdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & * \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & \ddots & \ddots & A_{n-k,n}\\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & \ddots & \vdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & A_{n-2,n} \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & A_{n-1,n} \\ * & * & * & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & * & A_{n,n} \end{smallmatrix}\right]\end{split}\]

は、配列として保存されます

  • 列優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{ \underbrace{\underbrace{*,...,*}_\text{ku},A_{11},*,...,*}_\text{lda}, \underbrace{\underbrace{*,...,*}_\text{ku-1},A_{max(1,2-k),2},...,A_{2,2},*,...*}_\text{lda}, ..., \underbrace{\underbrace{*,...,*}_\text{max(0,k-n+1)},A_{max(1,n-k),n},...,A_{n,n},*,...*}_\text{lda} }_\text{lda x n}]\]
  • 行優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{ \underbrace{A_{11},A_{21},...,A_{min(k+1,n),1},*,...,*}_\text{lda}, \underbrace{A_{2,2},...,A_{min(k+2,n),2},*,...,*}_\text{lda}, ..., \underbrace{A_{n,n},*,...*}_\text{lda} }_\text{lda x n}]\]

次のプログラムセグメントは、帯行列を従来の完全な行列ストレージ (先頭の次元が ldm の変数 matrix) から帯ストレージ (先頭の次元が lda の変数 a) に転送します。

  • 列優先レイアウトを使用

    for (j = 0; j < n; j++) { 
        m = k – j; 
        for (i = max(0, j – k); i <= j; i++) { 
            a[(m + i) + j * lda] = matrix[i + j * ldm]; 
        } 
    }
  • 行優先レイアウトを使用

    for (i = 0; i < n; i++) { 
        m = –i; 
        for (j = i; j < min(n, i + k + 1); j++) { 
            a[(m + j) + i * lda] = matrix[j + i * ldm]; 
        } 
    }
  • upper_lower = uplo::lower の場合、配列 a の先頭の (k + 1) x n 部分には、行列 A の上三角帯部分が含まれている必要があります。この行列は、行列の主対角線を配列の行 0 に、最初の副対角線を行 1 の位置 0 から開始するなどして、列ごとに指定する必要があります。三角帯行列の要素に対応しない配列 a の要素 (右下の kk 列の三角形など) は参照されません。

つまり、行列

\[\begin{split}A = \left[\begin{smallmatrix} A_{11} & * & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & * \\ A_{21} & A_{22} & * & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & * \\ A_{31} & A_{32} & A_{33} & * & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & * \\ \vdots & A_{42} & A_{43} & \ddots & \ddots & \ldots & \ldots & \ldots & \ldots & \ldots & \ldots & \vdots \\ A_{k+1,1} & \vdots & A_{53} & \ddots & \ddots & \ddots & \ldots & \ldots & \ldots & \ldots & \ldots & \vdots \\ * & A_{k+2,2} & \vdots & \ddots & \ddots & \ddots & \ddots & \ldots & \ldots & \ldots & \ldots & \vdots \\ \vdots & * & A_{k+3,3} & \ddots & \ddots & \ddots & \ddots & \ddots & \ldots & \ldots & \ldots & \vdots \\ \vdots & \vdots & * & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ldots & \ldots & \vdots \\ \vdots & \vdots & \vdots & * & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \ldots & \vdots \\ \vdots & \vdots & \vdots & \vdots & * & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & \vdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots & \ddots & \ddots & \ddots & \ddots & * \\ * & * & * & \ldots & \ldots & \ldots & * & A_{n,n-k} & \ldots & A_{n,n-2} & A_{n,n-1} & A_{n,n} \end{smallmatrix}\right]\end{split}\]

は、配列として保存されます

  • 列優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{ \underbrace{A_{11},A_{21},...,A_{min(k+1,n),1},*,...,*}_\text{lda}, \underbrace{A_{2,2},...,A_{min(k+2,n),2},*,...,*}_\text{lda}, ..., \underbrace{A_{n,n},*,...*}_\text{lda} }_\text{lda x n}]\]
  • 行優先レイアウトの場合

    \[\scriptstyle a = [\underbrace{ \underbrace{\underbrace{*,...,*}_\text{k},A_{11},*,...,*}_\text{lda}, \underbrace{\underbrace{*,...,*}_\text{k-1},A_{max(1,2-k),2},...,A_{2,2},*,...*}_\text{lda}, ..., \underbrace{\underbrace{*,...,*}_\text{max(0,k-n+1)},A_{max(1,n-k),n},...,A_{n,n},*,...*}_\text{lda} }_\text{lda x n}]\]

次のプログラムセグメントは、帯行列を従来の完全な行列ストレージ (先頭の次元が ldm の変数 matrix) から帯ストレージ (先頭の次元が lda の変数 a) に転送します。

  • 列優先レイアウトを使用

    for (j = 0; j < n; j++) { 
        m = –j; 
        for (i = j; i < min(n, j + k + 1); i++) { 
            a[(m + i) + j * lda] = matrix[i + j * ldm]; 
        } 
    }
  • 行優先レイアウトを使用

    for (i = 0; i < n; i++) { 
        m = k – i; 
        for (j = max(0, i – k); j <= i; j++) { 
            a[(m + j) + i * lda] = matrix[j + i * ldm]; 
        } 
    }

パックド三角行列#

nn 列の三角行列 A は、(n*(n + 1))/2 以上のサイズの 1 次元配列 a としてパック形式で表されます。行列 A の上部または下部のすべての要素は、配列 a に連続して格納されます。

三角パック行列を使用する BLAS 関数に入る前に、upper_lower = uplo::upper である場合、配列 a の最初の (n*(n + 1))/2 要素に、行列 A の上三角部分が列ごとに順番にパックされて含まれている必要があります。つまり、a[0] には A11 が含まれ、a[1] と a[2] にはそれぞれ A12A22 が含まれ、以下同様に続きます。

  • したがって、行列

    \[\begin{split}A = \begin{bmatrix} A_{11} & A_{12} & A_{13} & \ldots & A_{1n}\\ * & A_{22} & A_{23} & \ldots & A_{2n}\\ * & * & A_{33} & \ldots & A_{3n}\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ * & * & * & \ldots & A_{nn} \end{bmatrix}\end{split}\]

    は、配列として保存されます

  • 列優先レイアウトの場合

    \[\scriptstyle a = [A_{11},A_{12},A_{22},A_{13},A_{23},A_{33},...,A_{(n-1),n},A_{nn}]\]
  • 行優先レイアウトの場合

    \[\scriptstyle a = [A_{11},A_{12},A_{13},...,A_{1n}, A_{22},A_{23},...,A_{2n},..., A_{(n-1),(n-1)},A_{(n-1),n},A_{nn}]\]
  • upper_lower = uplo::lower である場合、列 (または行) 優先レイアウトが使用されると、配列 a の最初の (n*(n + 1))/2 要素には、a[0] に A11a[1] と a[2] にそれぞれ A21A31 が含まれるように、列ごとに (または行ごとに) 順番にパックされた行列 A の下三角部分が含まれる必要があります。行列

    \[\begin{split}A = \begin{bmatrix} A_{11} & * & * & \ldots & * \\ A_{21} & A_{22} & * & \ldots & * \\ A_{31} & A_{32} & A_{33} & \ldots & * \\ \vdots & \vdots & \vdots & \ddots & \vdots\\ A_{n1} & A_{n2} & A_{n3} & \ldots & A_{nn} \end{bmatrix}\end{split}\]

    は、配列として保存されます

  • 列優先レイアウトの場合

    \[\scriptstyle a = [A_{11},A_{21},A_{31},...,A_{n1}, A_{22},A_{32},...,A_{n2},..., A_{(n-1),(n-1)},A_{n,(n-1)},A_{nn}]\]
  • 行優先レイアウトの場合

    \[\scriptstyle a = [A_{11},A_{21},A_{22},A_{31},A_{32},A_{33},...,A_{n,(n-1)},A_{nn}]\]

ベクトル#

増分 incx を持つ n 要素のベクトル X は、(1 + (n - 1) * abs(incx)) 以上のサイズの 1 次元配列 x として表されます。

視覚的には、ベクトル

\[X = (X_{1},X_{2}, X_{3},...,X_{n})\]

は、配列としてメモリーに保存されます

\[\scriptstyle x = [\underbrace{ \underbrace{X_{1},*,...,*}_\text{incx}, \underbrace{X_{2},*,...,*}_\text{incx}, ..., \underbrace{X_{n-1},*,...,*}_\text{incx},X_{n} }_\text{1 + (n-1) x incx}] \quad if \:incx \:> \:0\]
\[\scriptstyle x = [\underbrace{ \underbrace{X_{n},*,...,*}_\text{|incx|}, \underbrace{X_{n-1},*,...,*}_\text{|incx|}, ..., \underbrace{X_{2},*,...,*}_\text{|incx|},X_{1} }_\text{1 + (1-n) x incx}] \quad if \:incx \:< \:0\]