oneapi::mkl::sparse::matmat#

スパース行列とスパース行列の積を計算します。

説明#

サポートされている <DATA_TYPE><INT_TYPE> データタイプと整数タイプの一覧については、Sparse BLAS でサポートされているデータと整数タイプを参照してください。また、スローされる可能性のある例外の詳細については、エラー処理を参照してください。

oneapi::mkl::sparse::matmat ルーチンは、次のように定義されるスパース行列とスパース行列の積を計算します

\[C = \text{op}(A)\cdot \text{op}(B)\]

ここで、\(A\)\(B\)、および \(C\) は適切なサイズのスパース行列であり、\(\text{op()}\) は行列修飾子です:

\[\begin{split}\text{op}(A) = \begin{cases} A,& \text{ oneapi::mkl::transpose::nontrans}\\ A^{T},& \text{ oneapi::mkl::transpose::trans}\\A^{H},& \text{ oneapi::mkl::transpose::conjtrans.}\end{cases}\end{split}\]

スパース行列は、matrix_handle_t に格納され、現在は圧縮スパース行 (CSR) 行列形式のみをサポートしています。

出力行列 \(C\)sparse::matmat() の終了時にソートされていることは保証されませんが、後にソートが必要な場合にはヘルパー関数 sparse::sort_matrix() が提供されます。

\(B\) 行列は、sparse::matmat() を呼び出す前にソートされた状態である必要があります。

行列 \(A\) はソートされている必要はありませんが、ソートされているとパフォーマンスが向上します。

\(C\) のデータ配列のサイズは通常は事前に不明であるため、matmat ルーチンは複数のステージに分割され、データ配列のサイズを照会し、割り当ててからルーチンに戻して埋めることができます。これにより、すべての \(C\) 行列データの割り当てを制御できるようになります。さらに、\(C\) のスパースパターンのみが必要な場合もありますが、このルーチンを使用すると、値配列なしで \(C\) を計算できます。一般的に、sparse::matmat() アルゴリズムは 3 つの計算ステージに分かれています。

ステージ

説明

work_estimation

ワークと負荷分散の初期の見積もりを行います (C 行列データのサイズの上限を見積もります)。

compute / compute_structure

C 行列データのサイズの計算や C の行ポインター配列の入力など、C 行列を計算するため内部積を実行します。

finalize/finalize_structure

残りの内部積と累算を実行し、最終的な C 行列配列に転送します。

一時ワークスペース配列のサイズや、割り当てられる \(C\) 行列データ (nnz(C)) のサイズを照会できるように、いくつかのヘルパーステージが提供されています。これらは設定され、matmat_request 列挙値として sparse::matmat ルーチンに渡されます。

namespace oneapi::mkl::sparse { 
    enum class matmat_request : std::int32_t { 
        get_work_estimation_buf_size, 
        work_estimation, 

        get_compute_structure_buf_size, 
        compute_structure, 
        finalize_structure, 

        get_compute_buf_size, 
        compute, 
        get_nnz, 
        finalize }; 
}

一般的なワークフローでは、異なる matmat_request を使用して sparse::matmat() を複数回呼び出します。

  1. matmat ステージの前
    1. \(C\) 行列の行ポインター配列を割り当て、\(C\) 行列に入力します。

      列とデータ配列のダミー引数で処理します (サイズが不明であるため)。

  2. work_estimation ステージ
    1. matmat_request::get_work_estimation_buf_size で matmat を呼び出します。

    2. ワークの見積りに対し一時ワークスペース配列を割り当てます。

    3. matmat_request::work_estimation で matmat を呼び出します。

  3. Compute ステージ
    1. matmat_request::get_compute_buf_size で matmat を呼び出します。

    2. 計算の見積りに対し一時ワークスペース配列を割り当てます。

    3. matmat_request::compute で matmat を呼び出します。

  4. Finalize ステージ
    1. matmat_request::get_nnz で matmat を呼び出します。

    2. \(C\)行列の列とデータ配列を割り当て、C 行列ハンドルに入力します。

    3. matmat_request::finalize で matmat を呼び出します。

  5. matmat ステージの後
    1. 別のスパース行列積に対して、matmat 記述子を解放または再利用します。

    2. 特定のスパース行列積の各ステージで割り当てられた一時ワークスペース配列を解放します。

    3. 後続の操作のため、\(C\) 行列ハンドルを解放または使用します。

最終結果が純粋に \(C\) のスパースパターンである場合、compute_structurefinalize_structure およびそれらのヘルパーを使用できることに注意してください。

一時ワークスペース配列の割り当てとメモリー管理を処理したくない場合は、work_estimationcompute/compute_structure ステージの get_xxx_buf_size クエリーをスキップして、ステージの API で sizeTempBuffertempBuffer 引数に null ポインターを渡す簡素化したオプションがあります。この場合、ライブラリは一時配列自体の割り当てとメモリー管理を行います。内部的に割り当てられた一時配列は、\(C\) 行列ハンドルが破棄されるまで存続します。ただし、常に \(C\) 行列データのサイズを照会し、\(C\) 行列配列自体を割り当てる必要があります。

この簡略化されたワークフローは次のように反映されます。

  1. matmat ステージの前
    1. \(C\) 行列の row_pointer 配列を割り当て、列とデータ配列のダミー引数を使用して \(C\) 行列ハンドルに入力します (サイズが不明であるため)。

  2. work_estimation ステージ
    1. matmat_request::work_estimation および、sizeTempBuffertempBuffer 引数の nullptr を使用して matmat を呼び出します。

  3. Compute ステージ
    1. matmat_request::compute および、sizeTempBuffertempBuffer 引数の nullptr を使用して matmat を呼び出します。

  4. Finalize ステージ
    1. matmat_request::get_nnz で matmat を呼び出します。

    2. \(C\)行列の列とデータ配列を割り当てて、\(C\) 行列ハンドルに入力します。

    3. matmat_request::finalize で matmat を呼び出します。

  5. matmat ステージの後
    1. 別のスパース行列積に対して、matmat 記述子を解放または再利用します。

    2. 後続の操作のため、\(C\) 行列ハンドルを解放または使用します。

これら 2 つのワークフローと、さらに \(C\) のスパースパターンのみを計算する例を、以下の oneMKL DPC++ の例で示します。

API#

構文#

SYCL* バッファーを使用:

namespace oneapi::mkl::sparse { 
    void matmat(sycl::queue &queue, 
                sparse::matrix_handle_t A, 
                sparse::matrix_handle_t B, 
                sparse::matrix_handle_t C, 
                sparse::matmat_request req, 
                sparse::matmat_descr_t descr, 
                sycl::buffer<std::int64_t, 1> *sizeTempBuffer, 
                sycl::buffer<std::uint8_t, 1> *tempBuffer); 
}

USM ポインターを使用:

namespace oneapi::mkl::sparse { 
    sycl::event matmat(sycl::queue &queue, 
                       sparse::matrix_handle_t A, 
                       sparse::matrix_handle_t B, 
                       sparse::matrix_handle_t C, 
                       sparse::matmat_request req, 
                       sparse::matmat_descr_t descr, 
                       std::int64_t *sizeTempBuffer, 
                       void *tempBuffer, 
                       const std::vector<sycl::event> &dependencies); 
}

インクルード・ファイル#

  • oneapi/mkl/spblas.hpp

入力パラメーター#

queue

SYCL* カーネルの実行に使用される SYCL* コマンドキューを指定します。

A

スパース行列 - スパース行列積の最初の行列ハンドル。行列 \(A\) は、sparse::matmt() への入力前にソートされている必要はありませんが、ソートされているとパフォーマンスが向上する可能性があります。

B

スパース行列 - スパース行列積の 2 番目の行列ハンドル。行列 \(B\) は現在、sparse::matmat() への入力としてソートされている必要があります。ソートされたプロパティーを確実にするには、sparse::sort_matrix() を使用します。

今後のリリースでは、このソートの制限は削除される予定です。

C

matmat 操作からの出力行列ハンドル。スパース行列形式の配列はユーザ​​ーによって割り当てられ、sparse::set_<xyz>_data ルーチンによって行列ハンドルに格納されます。データは、matmat 操作の一部としてライブラリーによって入力されます。出力行列はソートされない可能性があるので注意してください。そのため、ユーザーが自身でソートできる sparse::sort_matrix() API が提供されています。

request

マルチステージ・アルゴリズムの matmat_request ステージ。上記の一般的なワークフローの説明を参照してください。

descr

実行されるスパース行列 - スパース行列演算を記述する matmat_descr_t オブジェクト。これは、sparse::init_matmat_descrsparse::set_matmat_data、および sparse::release_matmat_descr ルーチンを使用して操作されます。

sizeTempBuffer

tempBuffer のサイズをバイト単位で表す、std::int64_t の長さの SYCL* 対応コンテナー (sycl::buffer またはホストからアクセス可能な USM ポインター)。get_xyz 命名規則を持つ matmat_request ステージでは、一時バッファーに割り当てるメモリーの量を通知するため、値はライブラリーによって設定されます。その他の work_estimation および compute/comute_structure ステージでは、一時バッファー tempBuffer とともに渡され、ライブラリーにバイト単位でスペースの量を通知します。

sycl::buffer 入力の場合、sizeTempBuffersycl::buffer<std::int64_t> タイプになります。

USM 入力の場合、sizeTempBuffer はホストからアクセス可能で、std::int64_t * タイプである必要があります。推奨される USM メモリーのタイプを次の表に示します。一般的に、USM ホストメモリーを使用すると USM 共有よりもパフォーマンスが向上しますが、どちらもホストアクセス可能であり、両方ともサポートされます。

sizeTempBuffer

満たされたステージ

配列のサイズ (バイト単位)

USM メモリータイプ

size_temp_buffer1

get_work_estimation_buf_size

work_estimation の temp_buffer1

ホストアクセス可能 (USM ホストまたは USM 共有)

size_temp_buffer2

get_compute_buf_size または get_compute_structure_buf_size

compute または compute_structure の temp_buffer2

ホストアクセス可能 (USM ホストまたは USM 共有)

nnz_buffer

get_nnz

C の colind/values 配列 (finalize|finalize_structure 用)

ホストアクセス可能 (USM ホストまたは USM 共有)

tempBuffer

アルゴリズム内の一時ワークスペースとして使用される、sizeTempBuffer バイトの SYCL* 対応コンテナー (sycl::buffer またはデバイスアクセス可能な USM ポインター)。別々のワークスペースを matmat API に渡すステージが 2 つあります (work_estimationcompute/compute_structure)。最後の finalize/finalize_structure 要求が完了するまで両方とも使用される可能性があるため、これらは matmat マルチステージ・アルゴリズムの実行中は有効なままである必要があります。

sycl::buffer 入力の場合、tempBufferssycl::buffer<std::uint8_t> タイプになります。

USM 入力の場合、tempBuffers はデバイスからアクセス可能である必要があり、void * タイプとして渡されます。推奨される USM メモリーのタイプを次の表に示します。一般に、USM デバイスメモリーを使用すると、USM 共有よりも優れたパフォーマンスが得られ、また USM 共有は sparse::matmat() の USM ホストよりも優れたパフォーマンスが得られますが、すべてデバイスがアクセス可能でありすべてサポートされます。

tempBuffer

ステージで提供される配列

ステージに設定された配列のサイズ

USM メモリータイプ

temp_buffer1

work_estimation

get_work_estimation_buf_size

デバイスにアクセス可能(USM デバイス、または USM 共有、または USM ホスト)

temp_buffer2

compute または compute_structure

get_compute_buf_size または get_compute_structure_buf_size

デバイスにアクセス可能(USM デバイス、または USM 共有、または USM ホスト)

dependencies (USM API のみ)

oneapi::mkl::sparse::matmat ルーチンが依存するイベントのリストを含む、std::vector<sycl::event> タイプのベクトル。

出力パラメーター#

C

\(C\) のデータ配列はユーザ​​ーによって割り当てられ、matmat アルゴリズムの一部としてライブラリーによって設定されます。

\(C\) の出力スパース行列データ配列のソートは保証されておらず、出力スパース行列を使用する後続の操作でソートされたプロパティーが必要な場合に備えて、sparse::sort_matrix() が用意されています。

戻り値 (USM のみ)#

sycl::event

matmat ルーチンのステージの完了を待機したり、依存関係としてできる SYCL* イベント。

#

SYCL* バッファーまたは USM で oneapi::mkl::sparse::matmat を使用する方法の例は、oneMKL インストール・ディレクトリーの次の場所にあります。

share/doc/mkl/examples/sycl/sparse_blas/source/csr_matmat.cpp 
share/doc/mkl/examples/sycl/sparse_blas/source/csr_matmat_simplified.cpp 
share/doc/mkl/examples/sycl/sparse_blas/source/csr_matmat_structure_only.cpp
share/doc/mkl/examples/sycl/sparse_blas/source/csr_matmat_usm.cpp 
share/doc/mkl/examples/sycl/sparse_blas/source/csr_matmat_simplified_usm.cpp 
share/doc/mkl/examples/sycl/sparse_blas/source/csr_matmat_structure_only_usm.cpp