यह जीसीसी में एक बग जैसा दिखता है, जो std::vector<int, std::allocator<int> >
के लिए एक प्रतिलिपि बनाने में विफल रहता है। ध्यान दें कि त्रुटि लिंकर से आती है और संकलन चरण के दौरान नहीं होती है। कॉपी कन्स्ट्रक्टर का उपयोग कॉपी फ़ंक्शन में किया जाता है जो उल्लिखित कार्य फ़ंक्शन के firstprivate
पैरामीटर प्रारंभ करता है। संकलक को उत्पन्न करने के लिए मजबूर करना, उदा।
std::vector<int> a;
बदलते
std::vector<int> a, b(a);
समस्या फिक्स करने के लिए।
यहां एक और विस्तृत विवरण दिया गया है।
struct omp_data_a data_o;
data_o.vec = vec;
data_o.sum = ∑
GOMP_task(omp_fn_0, &data_o, omp_cpyfn_1, 32, 8, 1, 0, 0, 0);
// --- outlined task body ---
void omp_fn_0(struct omp_data_s & restrict data_i)
{
struct vector & vec = &data_i->vec;
*data_i->sum = recursiveSumBody<int>(vec);
std::vector<int>::~vector(vec);
}
// --- task firstprivate initialisation function ---
void omp_cpyfn_1(struct omp_data_s *data_o, struct omp_data_a *data_i)
{
data_o->sum = data_i->sum;
struct vector &d40788 = data_i->vec;
struct vector *this = &data_o->vec;
std::vector<int>::vector(this, d40788); // <--- invocation of the copy constructor
}
omp_cpyfn_1
आदेश firstprivate तर्क आरंभ करने के लिए GOMP_task()
से बुलाया जाता है: जीसीसी की तरह कुछ में निम्न कोड बदल देती है
#pragma omp task shared(sum)
{
sum = recursiveSumBody(vec);
}
। यह std::vector<int>
की कॉपी कन्स्ट्रक्टर को कॉल करता है, क्योंकि (first-)private
टी को टाइप टी के रूप में टाइप करने के संदर्भों का व्यवहार करता है, लेकिन कन्स्ट्रक्टर उत्पन्न नहीं होता है, इसलिए ऑब्जेक्ट कोड लिंक करने में विफल रहता है। यह शायद gimplifier कोड में एक बग है के रूप में प्रति निर्माता इस तरह जब एक गैर संदर्भ std::vector<T, A>
निजीकरण हो जाता है बनाया जाता है, उदाहरण के लिए, कोड के साथ:
...
std::vector<T, A> b;
#pragma omp task shared(sum)
{
sum = recursiveSumBody(b);
}
...
कोड इंटेल 18.0b साथ संकलित करता है। स्पष्ट रूप से vec
को firstprivate
के रूप में निर्दिष्ट करना जीसीसी के साथ उसी तरह टूट जाता है (आईसीपीसी vec
एक अधूरा प्रकार होने के बारे में शिकायत करता है)। निम्नलिखित तरीके को इस्तेमाल किया जा सकता:
template<typename T, typename A>
T recursiveSumBody(std::vector<T, A> &vec) {
T sum = 0;
std::vector<T, A> *ptr = &vec;
#pragma omp task shared(sum)
{
sum = recursiveSumBody(*ptr);
}
return vec[0];
}
इस मामले ptr
में सूचक है। इसका firstprivate
संस्करण एक और सूचक है जो एक ही स्थान पर इंगित करता है, यानी वेक्टर उदाहरण। अर्थशास्त्र मूल कोड से अलग है क्योंकि यहां पूरे वेक्टर की कोई निजी प्रति नहीं बनाई गई है, बल्कि मूल वेक्टर का उपयोग किया जाता है।
किसी ने भी ऐसा कुछ देखा है? मुझे लगता है कि मैं 'std :: vector' की बजाय वेक्टर के 0 वें तत्व में पॉइंटर का उपयोग कर सकता हूं, लेकिन यदि संभव हो तो मैं सीधे पॉइंटर्स का उपयोग नहीं करूंगा। –
ध्यान दें कि 'libomp-dev' एलएलवीएम ओपनएमपी रनटाइम है जो 'gomp' से असंबंधित है, जो' gcc' द्वारा बंडल ओपनएमपी रनटाइम है। – Zulan