0

我正在使用一些我无法编​​辑的遗留代码,这些代码最初是在 PowerPC 上编译和测试的。我正在尝试创建一个构建系统,它将为通用 linux 机器(Ubuntu 11.10 x64)构建它。

它有一个类似于 cblas 的自定义接口,它包装了 clapack(版本 3.2.1)中包含的通用 blas 库的 f2c 版本。即我在 linux 机器上从 clapack 源编译 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_dscal只需调用 blas 库实现dscal_。但是,该库需要所有数据的指针,并且此包装器当前直接传递N,scale和的地址inc。这让我很害怕,因为它们是按值传递的并且通常是文字。

执行时mycblas_dscal通常什么都不做,即a没有改变或它seg。故障。使用更高的编译器优化(例如 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

Pass the array as double pointer to the function, and handle the array using array's address in function. This could solve you problem.

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 回答
0

这是什么功能

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

要做的是声明局部变量Nscale并将inc它们的地址传递给dscal_. 由于变量是本地的,它们存在于堆栈中,一旦mycblas_dscal完成就不再存在。内部dscal_通过它们的地址来操作这些局部变量。该操作仅影响局部变量,它对传递给的原始变量没有影响mycblas_dscal。一旦你打开优化,我猜mycblas_dscal调用是inlined,进一步恶化问题并导致段错误。

如果可以更改 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 回答