Problem with offload code ( dlopen() and undefined symbol: _ZTVN2cv11_InputArrayE )

Problem with offload code ( dlopen() and undefined symbol: _ZTVN2cv11_InputArrayE )

Hello,

i tried to generete a code with intrinsics, but I having some problems with my code.

So, for publish in here, i generated only a simple code that causes the same problem.

I have three files:

main.cpp

#include <time.h>
#include <sys/time.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include "secondaryFunction.h"

static inline long long timestampInUS();

using namespace cv;
using namespace std;
int main(int argc, char **argv) {

        if (argc != 3) {
                cout << "Usage: ./processImage <im1> <im2>\n" << endl;
                return 0;
        }

        Mat image1 = imread(argv[1], -1);
        Mat image2 = imread(argv[2], -1);

        Mat recon;
        uint64_t t1, t2;

        t1 = timestampInUS();
        recon = internalFunctionTwo<unsigned char>(image1, image2, 8);
        t2 = timestampInUS();
        cout << "Time: " << t2 - t1 << " us" << endl;
        imwrite("finalImage.jpg", recon);
        return 0;

}

static inline long long timestampInUS() {
        struct timeval ts;
        gettimeofday(&ts, NULL);
        return (ts.tv_sec * 1000000LL + (ts.tv_usec));
}

 

secondaryFunction.h

#ifndef SECONDARYFUNCTION_H_
#define SECONDARYFUNCTION_H_
#include "opencv/cv.hpp"

using namespace cv;
template <typename T>
cv::Mat internalFunctionTwo(const cv::Mat& image1, const cv::Mat& image2, int typeImage);

#endif

 

and secondaryFunction.cpp

#include <iostream>
#include <limits>
#include <opencv/cv.h>
#include "secondaryFunction.h"
#include <immintrin.h>

using namespace cv;
using namespace std;
template<typename T>
inline void internalFunctionOne(Mat& imageOne, Mat& imageTwo, int* out,
                int &iniO, int &endO, int &size, int typeImage) {

#pragma offload target(mic)
        {
                __m512i pixels, pval12, vectmp;
                __mmask16 p1mask, p2mask, finalMask;
//              p1mask = _mm512_int2mask(0xFF00);
//              p2mask = _mm512_int2mask(0x00FF);
// ...
        }

}

template<typename T>
Mat internalFunctionTwo(const Mat& image1, const Mat& image2, int typeImage) {

        Mat imageOut(image1.size() + Size(2, 2), imageOut.type());
        copyMakeBorder(image1, imageOut, 1, 1, 1, 1, BORDER_CONSTANT, 0);
        Mat imageIn(image2.size() + Size(2, 2), imageIn.type());
        copyMakeBorder(image2, imageIn, 1, 1, 1, 1, BORDER_CONSTANT, 0);

        int size = 10000;//test

        int* in = new int[size];
        int iniI = 0;
        int endI = 0;

        int* out = new int[size];
        int iniO = 0;
        int endO = 0;

        internalFunctionOne<T>(imageOut, imageIn, out, iniO, endO, size, typeImage);
        return imageOut;

}

template Mat internalFunctionTwo<unsigned char>(const Mat& image1,const Mat& image2, int typeImage);
template Mat internalFunctionTwo<float>(const Mat& image1, const Mat& image2,int typeImage);

The compilation is done with the following lines:

CXX     =       icpc
OPENCV_PATH     =       ${WORK}/opencv/opencv-2.4.5/install

AR      =       xiar
AR_FLAGS        =       -qoffload-build rcs

OPENCV_FLAGS    =       -I${OPENCV_PATH}/include/opencv -I${OPENCV_PATH}/include
OTHER_FLAGS     =       -fPIC -O2 -offload-attribute-target=mic -offload-option,mic,compiler,"-O2 -fma"

CXXFLAGS = ${OPENCV_FLAGS} ${OTHER_FLAGS}
CXXLIBS = ${OPENCV_PATH}/lib/libopencv_calib3d.so ${OPENCV_PATH}/lib/libopencv_contrib.so ${OPENCV_PATH}/lib/libopencv_core.so ${OPENCV_PATH}/lib/libopencv_features2d.so ${OPENCV_PATH}/lib/libopencv_flann.so ${OPENCV_PATH}/lib/libopencv_gpu.so ${OPENCV_PATH}/lib/libopencv_highgui.so ${OPENCV_PATH}/lib/libopencv_imgproc.so ${OPENCV_PATH}/lib/libopencv_legacy.so ${OPENCV_PATH}/lib/libopencv_ml.so ${OPENCV_PATH}/lib/libopencv_nonfree.so ${OPENCV_PATH}/lib/libopencv_objdetect.so ${OPENCV_PATH}/lib/libopencv_ocl.so ${OPENCV_PATH}/lib/libopencv_photo.so ${OPENCV_PATH}/lib/libopencv_stitching.so ${OPENCV_PATH}/lib/libopencv_superres.so ${OPENCV_PATH}/lib/libopencv_ts.so ${OPENCV_PATH}/lib/libopencv_video.so ${OPENCV_PATH}/lib/libopencv_videostab.so -lrt -lpthread -lm -ldl

TARGET = program

SOURCE = $(TARGET).cpp secondaryFunction.cpp

TARGET: libMO.a main.o
        ${CXX} ${CXXFLAGS} main.o libMO.a -o program ${CXXLIBS}

libMO.a: main.o secondaryFunction.o
        ${AR} ${AR_FLAGS} libMO.a secondaryFunction.o

main.o: main.cpp secondaryFunction.h
        ${CXX} ${CXXFLAGS} main.cpp -c

secondaryFunction.o: secondaryFunction.cpp
        ${CXX} ${CXXFLAGS} secondaryFunction.cpp -c

clean:
        rm -f *.o *.a *~ $(TARGET)

 

When I try to execute the program, I receive this below error:

host-1303$ ./program image01.jpg image02.jpg 
On the remote process, dlopen() failed. The error message sent back from the sink is /tmp/coi_procs/1/3637/load_lib/icpcoutqtHLqK: undefined symbol: _ZTVN2cv11_InputArrayE
offload error: cannot load library to the device 0 (error code 20)
On the sink, dlopen() returned NULL. The result of dlerror() is "/tmp/coi_procs/1/3637/load_lib/icpcoutqtHLqK: undefined symbol: _ZTVN2cv11_InputArrayE"

This error occurs only when I put some offload code in secondaryFunction.cpp. I was thinking that this problem was in OpenCV libraries, but without her lines doesn't works too. Now I checking of xiar and compilation lines.

If someone can give me a hint, I appreciate it.

 

 

 

 

 

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I do not have openCV headers available so I cannot compile your example so I am checking with our C++ Developers about this one.

The error is typical of something having not been included for the target (coprocessor) compilation. Perhaps what you need is to bracket the #include statements in the secondaryFunction.cpp with the offload_attribute push/pop as in the example below. Maybe at least the headers on lines 3 & 4, but maybe all of lines 1-4 depending on what opencv requires.

#pragma offload_attribute (push, target (mic))
#include <iostream>
#include <limits>
#include <opencv/cv.h>
#include "secondaryFunction.h"
#pragma offload_attribute (pop)

Maybe you could give that a try while we wait to hear from Developers.

The root cause likely is not the headers. Our developers suggest this likely relates to not having the OpenCV built for Xeon Phi™.

They commented:

The undefined symbol is the vtable for an object of InputArray class defined in namespace cv.  This most likely is defined in the opencv source files. While he builds the main.cpp and the secondary.cpp files with -offload-attribute-target=mic, it is not clear if the definition of the class is in those cpp files (unlikely). He needs to have built the file containing the definition with the option.

Does he have the OpenCV libraries built for MIC also since he is using class cv in the offload code?   Then he needs to include the libraries in xiar like how he added to the host linking using -qoffload-ldopts

 

Hi Kevin,

I tried to do this before, but I had the same error. Now I removed all openCV headers and functions, but I received the same error.

Anyway, thanks for your quick answer.

Ok. What compiler are you using (icpc -V)?  What changes do I make to your example to remove the openCV functions?

I don't have the OpenCV libraries built for MIC, then I removed any code that could uses their functions.

I reduced the code for not using cv namespace in secondaryFunction.cpp, but I received the same error. Even when I don't use the openCV functions in offload region, I need to built their libraries for MIC?

#pragma offload_attribute(push, target(mic))
  #include <iostream>
  #include <limits>
  #include "secondaryFunction.h"
#pragma offload_attribute(pop)
#include <immintrin.h>

void internalFunctionTwo(const unsigned char* image1, const unsigned char* image2, int typeImage){

#pragma offload target(mic)
        {
                __m512i pixels, pval12, vectmp;
                __mmask16 p1mask, p2mask, finalMask;
//              p1mask = _mm512_int2mask(0xFF00);
//              p2mask = _mm512_int2mask(0x00FF);
        }

}

 

#ifndef SECONDARYFUNCTION_H_
#define SECONDARYFUNCTION_H_
void internalFunctionTwo(const unsigned char* image1, const unsigned char* image2, int typeImage);
#endif

main.cpp

#include <opencv2/opencv.hpp>
#include <iostream>
#include "secondaryFunction.h"

int main(int argc, char **argv) {

        if (argc != 3) {
                std::cout << "Usage: ./processImage <im1> <im2>\n" << std::endl;
                return 0;
        }

        cv::Mat image1 = cv::imread(argv[1], -1);
        cv::Mat image2 = cv::imread(argv[2], -1);

        unsigned char *im1 = image1.data;
        unsigned char *im2 = image2.data;

        internalFunctionTwo(im1, im2, 8);

        return 0;

}

 

 

 

 

 

 

If openCV is not used within the offload then those functions should not require being built with offload.

Try removing -offload-attribute-target=mic from OTHER_FLAGS.

Leave a Comment

Please sign in to add a comment. Not a member? Join today