2

Mex ブリッジを使用して、Matlab のスパース行列に対していくつかの操作を実行しています。そのためには、Matlab が CSC (圧縮列ストレージ) にスパース行列を格納するため、入力行列を CSR (圧縮行ストレージ) 形式に変換する必要があります。

値配列と column_indices 配列を取得できました。ただし、CSR 形式の row_pointer 配列を取得するのに苦労しています。CSC から CSR への変換に役立つ C ライブラリはありますか?

さらに、CUDA カーネルを作成している間、スパース操作に CSR 形式を使用するのは効率的でしょうか、それとも次の配列を使用する必要がありますか: 行インデックス、列インデックス、および値?

カスタム カーネルの for ループの数を最小限に抑えて、データをより詳細に制御できるのはどれですか?

4

3 に答える 3

4

圧縮された行ストレージは、圧縮された列ストレージに似ていますが、単に転置されています。したがって、最も簡単な方法は、MATLAB を使用して行列を転置してから、MEX ファイルに渡すことです。次に、関数を使用します

Ap = mxGetJc(spA);
Ai = mxGetIr(spA);
Ax = mxGetPr(spA);

内部ポインターを取得し、それらを行ストレージとして扱います。Ap は行ポインタ、Ai はゼロ以外のエントリの列インデックス、Ax はゼロ以外の値です。対称行列の場合、何もする必要がないことに注意してください! CSC と CSR は同じです。

どの形式を使用するかは、後でマトリックスをどうしたいかによって異なります。たとえば、スパース行列ベクトル乗算の行列形式を見てください。これは古典的な論文の 1 つです。それ以来、研究は進んでいるので、さらに詳しく調べることができます。

于 2012-09-05T09:08:23.257 に答える
1

次のようにCUSPライブラリを使用して、CSC形式をMatlabからCSRに変換することになりました。

Amatlab から行列を取得した後、そのrowcolおよびベクトルを取得し、それぞれに作成されvaluesたそれぞれにコピーしました。thrust::host_vector

その後、次の と の 2 つのタイプを作成しましcusp::array1dた。IndicesValues

    typedef typename cusp::array1d<int,cusp::host_memory>Indices;   
    typedef typename cusp::array1d<float,cusp::host_memory>Values;
    Indices row_indices(rows.begin(),rows.end());
    Indices col_indices(cols.begin(),cols.end());
    Values  Vals(Val.begin(),Val.end());

とはrows、Matlab から取得したものです。colsValthrust::host_vector

その後、cusp::coo_matrix_view以下のように作成しました。

typedef cusp::coo_matrix_view<Indices,Indices,Values>HostView;
HostView Ah(m,n,NNZa,row_indices,col_indices,Vals);

ここでmnとは、疎行列の関数NNZaから取得したパラメーターです。mex

cusp::csr_matrix以下に示すように、適切な寸法を設定して、このビュー マトリックスをデバイス メモリにコピーしました。

    cusp::csr_matrix<int,float,cusp::device_memory>CSR(m,n,NNZa);
    CSR = Ah;   

その後、以下に示すようthrust::raw_pointer_castに、適切な次元の配列が既にmxCalloc編集されている場所を使用して、この CSR マトリックスの 3 つの個別のコンテンツ配列をホストにコピーしました。

 cudaMemcpy(Acol,thrust::raw_pointer_cast(&CSR.column_indices[0]),sizeof(int)*(NNZa),cudaMemcpyDeviceToHost);
 cudaMemcpy(Aptr,thrust::raw_pointer_cast(&CSR.row_offsets[0]),sizeof(int)*(n+1),cudaMemcpyDeviceToHost);
 cudaMemcpy(Aval,thrust::raw_pointer_cast(&CSR.values[0]),sizeof(float)*(NNZa),cudaMemcpyDeviceToHost);

CUSPこれがで使用しているすべての人に役立つことを願っていますMatlab

于 2012-09-13T04:19:29.793 に答える