5

Mac OS X 10.7で集中的な行列とベクトルの乗算を行うプログラムを作成するために、vecLibフレームワークの使用を開始しました。私はこのような簡単なプログラムを作成しました。行列aにベクトルxを掛け、その結果をベクトルyに加算します。

#include <vecLib/vectorOps.h>
#include <stdio.h>

float a[8][4] =     // the matrix to be multiplied
{
    {1.0f, 0.0f, 0.0f, 0.0f},
    {0.0f, 1.0f, 0.0f, 0.0f},
    {1.0f, 1.0f, 0.0f, 0.0f},
    {0.0f, 0.0f, 1.0f, 1.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 1.0f, 1.0f, 0.0f},
    {0.0f, 0.0f, 0.0f, 1.0f},
};

float x[4] = {1.0f, 2.0f, 4.0f, 8.0f};  // the vector to be multiplied
float y[8] = {0.f, 0.f, 0.f, 0.f,       // the result vector
              0.f, 0.f, 0.f, 0.f};


int main() {
    int i;
    vSgemv('n', 8, 4, 1.0f, (const vFloat *)a, (const vFloat *)x, 1.0f, (vFloat *)y);

    for (i = 0; i < 8; i++) {
        printf("%.4f\n", y[i]);
    }

    return 0;
}

プログラムをコンパイルしてコンソールで実行しました

gcc -framework vecLib -o test test.c && ./test

しかし、結果は次のようになりました。操作は行われず、結果ベクトルはまだ空でした。

0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000

vecLibフレームワークでマトリックス関数とベクトル関数を実行するための初期化が欠落していますか?

4

1 に答える 1

11

まず、実際のバグは非常に単純ですが、知る方法がありませんでした。最初の引数を渡します'n'が、実際には渡す必要があります'N'(ヘッダーに何が書かれていても)。この修正により、コードは機能します。

さて、そうは言っても、あなたはさらにいくつかの微妙なことを「間違った」ことをしているのです。

まず、vecLibを使用しないでください。Accelerate.frameworkに置き換えられました(10.4で!)。vecLib.frameworkは、レガシーサポートのためにのみ保持されています。新しい開発は、代わりにAccelerateに対してリンクする必要があります。

次に、で定義されているv*関数を使用しないでくださいvectorOps.h。それらも、で定義されている業界標準のBLAS関数に置き換えられましたcblas.h。それらは標準であるため、それらの使用方法に関する多くの公開ドキュメントがあり、はるかに高速な実装にも支えられています。vectorOps関数は、レガシーサポートのためにのみ維持されます。cblas.hさらに多くの操作とデータ型もサポートします。それだけでは不十分な場合、コードをiOSに移植することにした場合、vectorOps関数がまったく使用できないことがわかります。関数を使用しcblas.hます。

提案どおりに例を書き直します。

#include <Accelerate/Accelerate.h>
#include <stdio.h>

float a[8][4] =     // the matrix to be multiplied
{
    {1.0f, 0.0f, 0.0f, 0.0f},
    {0.0f, 1.0f, 0.0f, 0.0f},
    {1.0f, 1.0f, 0.0f, 0.0f},
    {0.0f, 0.0f, 1.0f, 1.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 1.0f, 1.0f, 0.0f},
    {0.0f, 0.0f, 0.0f, 1.0f},
};

float x[4] = {1.0f, 2.0f, 4.0f, 8.0f};  // the vector to be multiplied
float y[8] = {0.f, 0.f, 0.f, 0.f,       // the result vector
    0.f, 0.f, 0.f, 0.f};


int main() {
    int i;
    cblas_sgemv(CblasRowMajor, CblasNoTrans, 8, 4, 1.0f, (float*)a, 4, x, 1, 1.0f, y, 1);

    for (i = 0; i < 8; i++) {
        printf("%.4f\n", y[i]);
    }

    return 0;
}

そしてそれを実行すると:

scanon$ gcc test.c -framework Accelerate -o test
scanon$ ./test
1.0000
2.0000
3.0000
12.0000
5.0000
5.0000
7.0000
8.0000
于 2011-07-31T03:02:38.577 に答える