ctypes

2010-06-15 18 views
10

के माध्यम से numpy कॉलिंग sse2 संक्षेप में, मैं अजगर से, विशेष रूप से, पायथन से साझा लाइब्रेरी में कॉल करने का प्रयास कर रहा हूं। एसएसई 2 निर्देशों का उपयोग कर साझा पुस्तकालय सी में लागू किया गया है। अनुकूलन को सक्षम करना, यानी पुस्तकालय का निर्माण -ओ 2 या -ओ 1 के साथ, मुझे ctypes के माध्यम से साझा लाइब्रेरी में कॉल करते समय अजीब segfaults का सामना करना पड़ रहा है। ऑप्टिमाइज़ेशन को अक्षम करना (-O0), सबकुछ अपेक्षित रूप से काम करता है, जैसा कि लाइब्रेरी को सी-प्रोग्राम से सीधे जोड़ने (अनुकूलित या नहीं) के मामले में होता है। संलग्न एक स्निप जो मुझे मेरे सिस्टम पर चित्रित व्यवहार प्रदर्शित करता है। ऑप्टिमाइज़ेशन सक्षम होने के साथ, gdb emmintrin.h: 113 पर __builtin_ia32_loadupd (__P) में एक segfault की रिपोर्ट करता है। __P का मान ऑप्टिमाइज़ आउट के रूप में रिपोर्ट किया गया है।ctypes

test.c:

#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; 
} 

संकलक झंडे: जीसीसी -ओ libtest.so कमरा साझा -std = c99 -msse2 -fPIC -O2 जी -lm test.c

परीक्षण। py:

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) 

सी से परीक्षण कॉलिंग की उम्मीद के रूप में काम करता है:

call_from_c.c:

#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; 

} 

संकलित करें और कॉल करें:
जीसीसी -std = c99 -otestc -msse2 एल। -ltest call_from_c.c
निर्यात LD_LIBRARY_PATH = $ {LD_LIBRARY_PATH}:।
./testc
... काम करता है।

मेरे सिस्टम:

  • उबंटू लिनक्स i686 2.6.31-22-सामान्य
  • संकलक: जीसीसी (उबंटू 4.4.1-4ubuntu9)
  • अजगर: अजगर 2.6.4 (r264: 75,706 , 7 दिसंबर 2009, 18:45:15) [जीसीसी 4.4.1]
  • Numpy: 1.4.0

मैं ले लिया है प्रावधानों (सीएफ अजगर कोड) कि y गठबंधन है और एक्स के संरेखण मैट नहीं होना चाहिए आर (मुझे लगता है; एक्स को स्पष्ट रूप से संरेखित करना समस्या को हल नहीं करता है)।

ध्यान दें कि मैं b और f लोड करते समय _mm_load_pd के बजाय _mm_loadu_pd का उपयोग करता हूं। सी-केवल संस्करण _mm_load_pd कार्यों के लिए (अपेक्षित के रूप में)। हालांकि, _mm_load_pd हमेशा segfaults (अनुकूलन से स्वतंत्र) का उपयोग कर ctypes के माध्यम से फ़ंक्शन को कॉल करते समय।

मैंने सफलता के बिना इस मुद्दे को हल करने के लिए कई दिनों की कोशिश की है ... और मैं अपने मॉनीटर को मौत के लिए मारने के कगार पर हूं। कोई इनपुट स्वागत है। डैनियल

+0

आप एक ही त्रुटि मिलती है अगर आप सी से "परीक्षण" फ़ंक्शन को कॉल किया? सी से – Tarantula

+0

नंबर कॉलिंग परीक्षण सुचारू रूप से चलाता है ... मैं सी – Daniel

+0

से एक उदाहरण कॉल समीकरण से numpy को दूर करने और सीधे ctypes का उपयोग कर के बारे में क्या साथ मूल पोस्ट अपडेट किया है? – tonfa

उत्तर

-1

क्या आप Numpy 1.5.0b2 में अपग्रेड करने का प्रयास कर रहे हैं। बस निम्नलिखित चलाने (लेकिन यह अन्य बातों तोड़ सकता सावधान रहना (आप सभी pyrex पुन: संयोजित करने के लिए) होगा:

sudo easy_install -U numpy 

मैं ctypes जब मैं H5PY उपयोग करने के लिए कोशिश कर रहा था के साथ इसी तरह की समस्याओं रहा था (मैं पुन: संयोजित करना पड़ा numde के नवीनतम संस्करण के साथ प्राप्त करने के लिए .deb) और साथ ही साथ नवीनतम अपग्रेड तय किए गए बुनाई के साथ प्रमुख समस्याएं थीं।

2

मैं सिर्फ इस अजगर से कुछ SSE-कोड कॉल करने के लिए कोशिश कर रहा द्वारा काटा गया, समस्या हो जीसीसी चाहता है कि लगता है माना कि ढेर 16-बाइट सीमाओं पर संरेखित है (सबसे बड़ा देशी प्रकार वास्तुकला पर, यानी SSE-प्रकार), और जो कुछ इस धारणा के साथ ऑफसेट गणना करता है। जब वह धारणा झूठी होती है, तो एसएसई-निर्देश फंस जाएंगे।

उत्तर

gcc -mstackrealign
के साथ संकलित करना प्रतीत होता है जो कार्य प्रोजेक्ट को 16 बाइट्स पर हमेशा स्टैक को संरेखित करने के लिए बदलता है।

संबंधित मुद्दे