首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过ctype调用sse2

通过ctype调用sse2
EN

Stack Overflow用户
提问于 2010-06-15 12:39:52
回答 2查看 1.3K关注 0票数 10

简而言之,我试图从python调用一个共享库,更具体地说,从numpy调用。共享库是用C语言使用sse2指令实现的。启用优化,即使用-O2或-O1构建库时,当通过ctype调用共享库时,我将面临奇怪的分段错误。禁用优化(-O0),一切都按预期进行,就像将库直接链接到c程序(优化与否)一样。附件中,你发现了一个片段,它显示了我的系统所描述的行为。在启用优化的情况下,gdb在__builtin_ia32_loadupd (__P)的emmintrin.h:113中报告了一个分段错误。据报告,__P的值是优化的。

测试.c:

代码语言:javascript
复制
#include <emmintrin.h>
#include <complex.h>
void test(const int m, const double* x, double complex* y) {

    int i;
    __m128d _f, _x, _b;
    double complex f __attribute__( (aligned(16)) );
    double complex b __attribute__( (aligned(16)) );
    __m128d* _p;

    b = 1;
    _b = _mm_loadu_pd( (double *) &b );

    _p = (__m128d*) y;

    for(i=0; i<m; ++i) {
        f = cexp(-I*x[i]);
        _f = _mm_loadu_pd( (double *) &f );
        _x = _mm_loadu_pd( (double *) &x[i] );      
        _f = _mm_shuffle_pd(_f, _f, 1);
        *_p = _mm_add_pd(*_p, _f);
        *_p = _mm_add_pd(*_p, _x); 
        *_p = _mm_mul_pd(*_p,_b);
        _p++;
    }
    return;
}

编译器标志: gcc -o libtest.so -shared -std=c99 -msse2 -fPIC -O2 -g -lm test.c

test.py:

代码语言:javascript
复制
import numpy as np
import os

def zerovec_aligned(nr, dtype=np.float64, boundary=16):
    '''Create an aligned array of zeros.
    '''
    size = nr * np.dtype(dtype).itemsize
    tmp = np.zeros(size + boundary, dtype=np.uint8)
    address = tmp.__array_interface__['data'][0]
    offset = boundary - address % boundary
    return tmp[offset:offset + size].view(dtype=dtype)


lib = np.ctypeslib.load_library('libtest', '.' )
lib.test.restype = None
lib.test.argtypes = [np.ctypeslib.ctypes.c_int,
                     np.ctypeslib.ndpointer(np.float64, flags=('C', 'A') ),
                     np.ctypeslib.ndpointer(np.complex128, flags=('C', 'A', 'W') )]


n = 13
y = zerovec_aligned(n, dtype=np.complex128)
x = np.ones(n, dtype=np.float64)
# x = zerovec_aligned(n, dtype=np.float64)
# x[:] = 1.

lib.test(n,x,y)

从C调用测试如预期的那样工作:

call_from_c.c:

代码语言:javascript
复制
#include <stdio.h>
#include <complex.h>
#include <stdlib.h>
#include <emmintrin.h>

void test(const int m, const double* x, double complex* y);

int main() {

    int i; 
    const int n = 11;
    double complex *y = (double complex*) _mm_malloc(n*sizeof(double complex), 16);
    double *x = (double *) malloc(n*sizeof(double));
    for(i=0; i<n; ++i) {
        x[i] = 1;
        y[i] = 0;
    }

    test(n, x, y);
    for(i=0; i<n; ++i)
            printf("[%f %f]\n", creal(y[i]), cimag(y[i]));

    return 1;

}

编译和调用:

gcc -std=c99 -otestc -msse2 -L。-ltest call_from_c.c

导出LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:。

./测试c

..。很管用。

我的系统:

  • Ubuntu 2.6.31-22-通用
  • 编译器: gcc (Ubuntu
  • Python2.6.4(r 264:75706,2009年12月7日,18:45:15) GCC 4.4.1
  • Numpy: 1.4.0

我已经采取了措施。python代码)y是对齐的,x的对齐应该无关紧要(我认为,显式地对x并不能解决问题)。

还要注意的是,当加载b和f时,我使用的是_mm_loadu_pd而不是_mm_load_pd,因为只有C版本的_mm_load_pd工作(如预期的那样)。但是,当使用_mm_load_pd通过ctype调用函数时,总是分段错误(独立于优化)。

我已经试了好几天来解决这个问题,但没有成功.我差点把我的班长打死。欢迎任何意见。丹尼尔

EN

回答 2

Stack Overflow用户

发布于 2010-08-28 20:32:44

尝试使用numpy构建系统构建您的扩展,以减少潜在的c173/ to标志差异:http://projects.scipy.org/numpy/wiki/NumpySconsExtExamples

票数 1
EN

Stack Overflow用户

发布于 2010-08-28 03:22:01

您是否尝试升级到Numpy 1.5.0b2。只需运行以下命令(但是要小心,它可能会破坏其他东西(您必须重新编译所有pyrex):

代码语言:javascript
复制
sudo easy_install -U numpy

当我尝试使用H5PY (我必须重新编译.deb以获得最新版本的numpy)时,ctype也出现了类似的问题,而且最近的升级修复了weave的一些主要问题。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3045158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档