मैं अपने C++ कोड में Lapack का उपयोग कर रहा हूं। मैं काफी उलझन में हूं कि पुस्तकालय से ठीक से कैसे लिंक किया जाए। लैपैक से फ़ंक्शन को कॉल करने वाले मेरे कोड से संबंधित एक छोटा सा उदाहरण यहां दिया गया है:

#include <iostream>

namespace lapack { extern "C" {
  void ilaver(int* major, int* minor, int* patch); } }

int main()
{
    int major = 0;
    int minor = 0;
    int patch = 0;
    lapack::ilaver(&major, &minor, &patch);
    std::cout << major << "." << minor << "." << patch << std::endl;
    return 0;
}

अगर मैं इसे जीसीसी 4.8.5 (लिनक्स ओपनएसयूएसई) के साथ संकलित करने का प्रयास करता हूं, तो मुझे निम्न त्रुटि मिलती है:

> g++ ilaver.cpp -o ilaver -L /softs/lapack/3.7.1/64/gcc/4.8.5/lib64 -l lapack
/tmp/ccHvDCAh.o: In function `main':
ilaver.cpp:(.text+0x33): undefined reference to `ilaver'
collect2: error: ld returned 1 exit status

मैं समझ गया कि यह एक नाम उलझन समस्या है। अगर मैं फ़ंक्शन नाम के अंत में अंडरस्कोर जोड़कर अपना कोड बदलता हूं, तो यह जीसीसी के साथ ठीक से संकलित होता है:

#include <iostream>

namespace lapack { extern "C" {
  void ilaver_(int* major, int* minor, int* patch); } }

int main()
{
    int major = 0;
    int minor = 0;
    int patch = 0;
    lapack::ilaver_(&major, &minor, &patch);
    std::cout << major << "." << minor << "." << patch << std::endl;
    return 0;
}

लेकिन यह विंडोज़ के तहत इंटेल के कंपाइलर्स के साथ संकलित नहीं होता है। वहां, मैंगलिंग अलग है, मुझे इसे lapack::ILAVER में बदलना है, और फिर यह संकलित करता है।

मेरा कोड कई कंपाइलर्स (जीसीसी, इंटेल, एमएसवीसी) के साथ कई कॉन्फ़िगरेशन (लिनक्स/मैक/विंडोज) के तहत संकलित किया जाना चाहिए। मैं और अधिक सामान्य कैसे हो सकता हूं और यह सुनिश्चित कर सकता हूं कि यह संकलक के एक बड़े पैनल के तहत संकलित होगा?

4
Caduchon 11 सितंबर 2017, 15:29
2
बस लैपैक का इस्तेमाल करें। उन्होंने इसे काम करने के लिए आवश्यक सभी घृणित मैक्रो चालबाजी पहले ही कर ली है और यह आधिकारिक सी इंटरफ़ेस है।
 – 
Baum mit Augen
11 सितंबर 2017, 15:34

1 उत्तर

सबसे बढ़िया उत्तर

जैसा कि आप पहले ही खोज चुके हैं, अंडरस्कोर जोड़ने जैसे हैक अपने स्वभाव से प्लेटफ़ॉर्म-विशिष्ट होते हैं। "हाथ से" प्लेटफॉर्म और कंपाइलर की एक बड़ी श्रृंखला का समर्थन करने के लिए बड़ी मात्रा में अप्रिय और थकाऊ काम की आवश्यकता होती है।

पोर्टेबिलिटी प्राप्त करने का सबसे आसान तरीका LAPACKE का उपयोग करना है, LAPACK का आधिकारिक C इंटरफ़ेस। इसमें आपको आवश्यक सभी कार्यों को फिर से घोषित करने से बचाने का अतिरिक्त लाभ भी है।

यहाँ एक सरल उदाहरण है:

#include <iostream>
#include <lapacke.h>    

int main()
{
    // By using lapack_int, we also support LAPACK-ILP64
    lapack_int major = 0;
    lapack_int minor = 0;
    lapack_int patch = 0;
    LAPACKE_ilaver(&major, &minor, &patch);
    std::cout << major << "." << minor << "." << patch << std::endl;
    return 0;
}

अधिक जानकारी आधिकारिक दस्तावेज में पाई जा सकती है।

ध्यान दें कि LAPACKE केवल LAPACK को संभालता है, यदि आपको BLAS रूटीन की भी आवश्यकता है, तो आप उन्हें CBLAS.

2
Baum mit Augen 11 सितंबर 2017, 18:41
यह एक समाधान हो सकता है, लेकिन हमारे द्वारा उपयोग किए जाने वाले विभिन्न कॉन्फ़िगरेशन पर लैपैक डिफ़ॉल्ट रूप से स्थापित नहीं होता है। यह सभी कॉन्फ़िगरेशन पर लैपैक की सभी स्थापना को अद्यतन करने के लिए एक अतिरिक्त लागत उत्पन्न करता है।
 – 
Caduchon
11 सितंबर 2017, 15:47
2
मैंने उस तर्क को पहले भी सुना है, लेकिन मैं आपको बता सकता हूं कि लैपैक को स्थापित करना और अपडेट करना अपने आप में कुछ होम-ब्रूड लैपैक को लिखने और बनाए रखने की तुलना में तेज़ और आसान है।
 – 
Baum mit Augen
11 सितंबर 2017, 15:49
क्या लैपैक में बीएलएएस फ़ंक्शन भी होते हैं (जब मैंने इसे संकलित किया तो लैपैक के साथ ब्लैस दिया गया था)? मुझे dgemm नहीं मिल रहा है (मैं इसका इस्तेमाल करता हूं)।
 – 
Caduchon
11 सितंबर 2017, 15:53
2
Blas रूटीन CBLAS में हैं, लैपैक जस्ट हैंडल लैपैक।
 – 
Baum mit Augen
11 सितंबर 2017, 15:55