0

PowerPC 用にコンパイルおよびテストされた、編集できないレガシー コードを使用しています。一般的な Linux ボックス (Ubuntu 11.10 x64) 用にビルドするビルド システムを作成しようとしています。

clpack (Ver. 3.2.1) に含まれる汎用 blas ライブラリの f2c バージョンをラップする cblas に似たカスタム インターフェイスを備えています。つまり、Linux マシンで clpack ソースから liblapack、libblas、および libf2c をコンパイルし、次のサンプル コードにリンクします。

int main()
{
    double a[3] = {100,200,300};
    // Scale all elements of a by 0.1
    // This uses a custom wrapper that seg. faults
    mycblas_dscal(3,0.1,a,1);
}

void mycblas_dscal(int N, double scale, double* data, int inc)
{
    dscal_((int*) &N, (double*) &scale, data, (int*) &inc);
}

mycblas_dscalblas ライブラリの実装を呼び出すだけdscal_です。ただし、ライブラリはすべてのデータのポインターを想定しており、このラッパーは現在、 と のアドレスをN直接scale渡しincます。これらは値渡しであり、多くの場合リテラルであるため、これは私を怖がらせます。

実行さmycblas_dscalれると、何もしないことがよくあります。つまりa、変更されていないか、セグメント化されています。障害。より高度なコンパイラの最適化 (gcc -O3 など) を使用すると、セグメント化のみが行われます。障害。

blas ライブラリをテストするには、次のコードが正常に機能します。

int main()
{
    // This calls the library directly and works fine but I cannot edit 
    //the rest of the code which is using the wrapped version above.
    int size = 3;
    double scale = 0.1;
    int inc = 1;
    dscal_(&size,&scale,a,&inc);
}

私の唯一の洞察は、seg. コンパイラの最適化により、フォールトの動作が悪化します。詳しく調べるほどの知識はありません。何か案は?

4

2 に答える 2

0

この機能は何ですか

void mycblas_dscal(int N, double scale, double* data, int inc)
{
    dscal_((int*) &N, (double*) &scale, data, (int*) &inc);
}

ローカル変数を宣言しN、それらのアドレスscaleincに渡しますdscal_。変数はローカルであるため、スタック上に存在し、終了すると存在しなくなりmycblas_dscalます。内部dscal_は、アドレスを介してこれらのローカル変数を操作します。この操作はローカル変数にのみ影響し、に渡される元の変数には影響しませんmycblas_dscal。最適化をオンにすると、mycblas_dscal呼び出しがインライン化され、問題がさらに悪化し、セグメンテーション違反が発生すると思います。

変更できる場合は mycblas_dscal、次のように変更してください。

void mycblas_dscal(int &N, double &scale, double*& data, int &inc)
{
    dscal_((int*) &N, (double*) &scale, data, (int*) &inc);
}

つまり、値ではなく参照を使用します。

あなたが言及したそのライブラリの一部であるためにその定義を変更できない場合、あなたができる唯一のことはそのライブラリを使用しないことです。その場合、他に解決策はないと思います。

于 2012-03-09T03:21:09.343 に答える
0

配列を double ポインターとして関数に渡し、関数内で配列のアドレスを使用して配列を処理します。これで問題が解決する可能性があります。

int main() 
{
    double a[3] = {100,200,300};
    // Scale all elements of a by 0.1
    // This uses a custom wrapper that seg. faults     
    mycblas_dscal(3,0.1,&a,1); 
}  

void mycblas_dscal(int N, double scale, double** data, int inc) 
{     
   dscal_((int*) &N, (double*) &scale, *data, (int*) &inc); 
} 
于 2012-03-09T05:03:21.377 に答える