मेरे पास एक छोटी परियोजना है जो SWIG के साथ खूबसूरती से काम करती है। विशेष रूप से, मेरे कुछ फ़ंक्शन std::vector
एस लौटते हैं, जिन्हें पायथन में टुपल्स में अनुवादित किया जाता है। अब, मैं बहुत संख्यात्मक संख्या करता हूं, इसलिए सीडीआईजी को सी ++ कोड से वापस आने के बाद इन्हें नुकीले सरणी में परिवर्तित कर दिया गया है। ऐसा करने के लिए, मैं SWIG में निम्न की तरह कुछ उपयोग करता हूं।क्या SWIG की नई बिल्टिन सुविधा के साथ Pythonappend का उपयोग करने का कोई तरीका है?
%feature("pythonappend") My::Cool::Namespace::Data() const %{ if isinstance(val, tuple) : val = numpy.array(val) %}
(वास्तव में, डाटा नामित कई कार्य, जिनमें से कुछ तैरता वापसी, जिसके कारण मैं जाँच करें कि val
वास्तव में एक टपल है कर रहे हैं।) यह सिर्फ खूबसूरती से काम करता है।
लेकिन, मैं भी -builtin
झंडा है कि अब उपलब्ध है का उपयोग करना चाहते हैं। इन डेटा कार्यों के लिए कॉल दुर्लभ और अधिकतर इंटरैक्टिव हैं, इसलिए उनकी धीमी गति कोई समस्या नहीं है, लेकिन अन्य धीमी लूप भी हैं जो बिल्टिन विकल्प के साथ महत्वपूर्ण रूप से बढ़ती हैं।
समस्या यह है कि जब मुझे लगता है कि झंडा उपयोग करते हैं, pythonappend सुविधा चुपचाप नजरअंदाज कर दिया जाता है। अब, डेटा फिर से एक टुपल देता है। क्या कोई रास्ता है कि मैं अभी भी numpy arrays वापस कर सकता है? मैंने टाइपमैप का उपयोग करने की कोशिश की, लेकिन यह एक विशाल गड़बड़ में बदल गया।
संपादित करें:
बोरेलिद ने इस सवाल का जवाब बहुत अच्छी तरह से दिया है। बस पूर्णता के लिए, मैं एक जोड़े से संबंधित लेकिन संक्षेप में अलग-अलग टाइपमैप शामिल करता हूं जो मुझे चाहिए क्योंकि मैं कॉन्स्ट संदर्भ द्वारा लौटाता हूं और मैं वैक्टरों के वैक्टर का उपयोग करता हूं (शुरू नहीं करें!)। ये काफी अलग है कि मैं किसी और मामूली अंतर पता लगाने की कोशिश के आसपास ठोकर नहीं करना चाहते हैं।
%typemap(out) std::vector<int>& {
npy_intp result_size = $1->size();
npy_intp dims[1] = { result_size };
PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(1, dims, NPY_INT);
int* dat = (int*) PyArray_DATA(npy_arr);
for (size_t i = 0; i < result_size; ++i) { dat[i] = (*$1)[i]; }
$result = PyArray_Return(npy_arr);
}
%typemap(out) std::vector<std::vector<int> >& {
npy_intp result_size = $1->size();
npy_intp result_size2 = (result_size>0 ? (*$1)[0].size() : 0);
npy_intp dims[2] = { result_size, result_size2 };
PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_INT);
int* dat = (int*) PyArray_DATA(npy_arr);
for (size_t i = 0; i < result_size; ++i) { for (size_t j = 0; j < result_size2; ++j) { dat[i*result_size2+j] = (*$1)[i][j]; } }
$result = PyArray_Return(npy_arr);
}
संपादित करें 2:
मैं के लिए, इसी तरह की समस्याओं का उपयोग करके भी @ भिक्षु दृष्टिकोण (explained here) को हल किया जा सकता है वह नहीं है देख रहा था हालांकि।
मुझे नहीं लगता कि आप टाइपमैप लिखने और सी पक्ष पर ऐसा किए बिना ऐसा कर सकते हैं, ठीक है क्योंकि -बिल्टिन उस कोड को हटा देता है जहां सामान्य रूप से पाइथोनएपेंड रखा जाता है। क्या आप निश्चित हैं-बिल्टिन बहुत तेज है (यानी आप इसका उपयोग करने के लिए प्रोफाइलिंग का नेतृत्व कर रहे थे?) मैं दो मॉड्यूल का उपयोग करने के लिए लुभाना चाहता हूं, एक के साथ-साथ एक -बिल्टिन। – Flexo
मुझे आश्चर्य है कि कोई चेतावनी नहीं है कि '-बिल्टिन' पायथन अपेंड को अनदेखा करता है। मैं 'std :: vector की numpy arrays में टाइपमैपिंग की चुनौती पर नहीं हूं। मैंने प्रोफ़ाइल की, और यह मेरे इंटरफ़ेस में सबसे कष्टप्रद लूप को काफी हद तक बढ़ा दिया (ब्रेक लेने के लिए पर्याप्त समय नहीं, अक्सर प्रतीक्षा करने में बहुत लंबा)। लेकिन मुझे यह भी एहसास हुआ कि मैं इस लूप को अपने सी ++ कोड में ले जा सकता हूं - हालांकि कुछ हद तक अजीब तरह से। तो मैं इस तरह जाऊंगा। फिर भी, आपके 'दो मॉड्यूल' सुझाव दिलचस्प है, और अन्य मामलों में उपयोगी हो सकता है। – Mike
क्या आपने SWIG को -Wall के साथ बुलाया था? मैंने माना कि यह उस मामले में चेतावनी देगा। – Flexo