undefined symbol in offload code

undefined symbol in offload code

When running my executable, I get an error message as follows:

On the remote process, dlopen() failed. The error message sent back from the sink is /tmp/coi_procs/1/5145/load_lib/iccoutNYiJgR: undefined symbol: _ZN12boost_1_48_012basic_formatIcSt11char_traitsIcESaIcEErmImEERS4_RKT_
On the sink, dlopen() returned NULL. The result of dlerror() is "/tmp/coi_procs/1/5145/load_lib/iccoutNYiJgR: undefined symbol: _ZN12boost_1_48_012basic_formatIcSt11char_traitsIcESaIcEErmImEERS4_RKT_"
offload error: cannot load library to the device 0 (error code 20)
Segmentation fault (core dumped)

I know which symbol it is, and most likely this is caused by a missing "#pragma offload_attribute(push, target(mic))" before "#include <boost/format.hpp>" in one of my 10000 files that create 150 shared libraries. Question:

Is there any way that I can convice the mic-side dlopen() to tell me which shared library (.so files) is causing this message. Maybe it can even identify the source file?!?

Georg

8 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项
robert-reed (Intel)的头像

The last time I saw a similar question there were a coupl answers available.  Perhaps they'll serve you.  The first is a compilation option to add to "identify unresolved symbols in a MIC binary": add     -offload-option,mic,compiler,"-z defs"

If this fails to reveal the culprit, you might fall back onto this alternate scheme using the loader:

Set these environment variables on the host:

    export MIC_ENV_PREFIX=MIC

    export MIC_LD_DEBUG=all

    export MIC_LD_DEBUG_OUTPUT=/tmp/myldout

Then try running your program from the host.  When you get the COI error, ssh to the card (via miccmd or your favorite method) and look in /tmp.  A file called myldout.<pid> (substituting the process ID for <pid>) should appear as part of the load operation.  Issue the command "grep fatal /tmp/myldout.<pid>" (filling the proper number) to catch the line or lines that cause the load to fail.  Unresolved symbols in the load will pop out using this method.

I've never tried this on a project that builds 150 SOs and the latter might generate a large file in the coprocessor /tmp, so all I can do further is wish you good luck.

Robert (nice portrait, btw),

The   -offload-option,mic,compiler,"-z defs" really helps to some extent. Using MIC_LD_DEBUG did not uncover additional information-it just confirms that the symbol is undefined. The file mentioned in the log has some artificial name, so it is not useful as a hint for finding the culprit.

It appears that the runtime loader on the MIC side is more sensitive to undefined symbols that the host side. I investigated in our host only .so's, and there the symbol was also undefined in some .so (without having any .so that actually defines it -it is a header only library). Could that be the case?

What exactly happens when I run offload code that is using "fat" shared libraries? Does the runtime system automatically transfer the necessary code to the accelerator? That's what I believe to see with a short test program.

Georg

robert-reed (Intel)的头像

Yes, when you are using the offload model, SOs linked into the a.out will be preloaded along with the coprocessor targeted a.out image, but I think the SOs provided are separate.  For example, on the machine I'm looking at, all the Intel Xeon Phi coprocessor SOs are in /opt/intel/composexe/lib/mic while their host-side equivalents are in /opt/intel/composerxe/lib/intel64 and ../ia32.  That's where all the "system libraries" go.  The relavent text from the compiler manual:

When the target is available, the target executable is loaded when the CPU version of the executable is loaded, or when the first offload is attempted. At this time the libraries linked with the target code are initialized. The loaded target executable remains in the target memory until the host program terminates. Thus, any global state maintained by the library is maintained across offload instances.

Note

Separate copies of libraries are linked or loaded with the host program and the offloaded target code. So there are two sets of global state: One on the host CPU and one on the target. The host CPU code only sees the host CPU state and the offloaded code only sees the state of the library on the target.

Ravi Narayanaswamy (Intel)的头像

The host code with main program is generated as an executable and not shared library.  So during linking phase the linker makes sure all references in the main executable and its dependent .so have all their symbols resolved.  On MIC the main program is actually generated as a .so,  so the linker does not have to resolve all symbols hence you don't get a link time error for unresolved symbol but get it at load time.  The use of -z defs forces the linker to resolve all symbol and hence you see the error when you use the flag.  The symbol has to be defined in some file and you probably missing annotating it with declspec(target(mic)) 

You said it is in a header only library.  Is there a MIC version of that library, if so can you also add that library to mic options.

Your hints helped me track down one of the problems. Here is one of my sources, melted down to the bare minimum:

#include <complex>
#include <iostream>
int main()
{
   {
      std::cout<<"Doing host side"<<std::endl;
      std::complex<double> *a=new std::complex<double> [4];
      std::cout<<"Done host side"<<std::endl;
   }
   
#pragma offload target(mic)
   {
      std::cout<<"Doing MIC side"<<std::endl;
      std::complex<double> *a=new std::complex<double> [4];
      std::cout<<"MIC side done"<<std::endl;
   }
   return 0;
}

When compiled with "icc -D__USE_XOPEN2K8 -offload-attribute-target=mic -z defs -openmp test.cpp" and run as a.out, I get the following:

./a.out
Doing host side
Done host side
On the sink, dlopen() returned NULL. The result of dlerror() is "/tmp/coi_procs/1/5665/load_lib/iccoutuiOYHe: undefined symbol: __$U1"
On the remote process, dlopen() failed. The error message sent back from the sink is /tmp/coi_procs/1/5665/load_lib/iccoutuiOYHe: undefined symbol: __$U1
offload error: cannot load library to the device 0 (error code 20)

Compling with -z defs gives this:

icc -D__USE_XOPEN2K8 -offload-attribute-target=mic -offload-option,mic,compiler,"-z defs -lm" -z defs -openmp test.cpp
/tmp/iccdEAKwl.o: In function `main':
test.cpp:(.text+0x16c): undefined reference to `__$U1'

The offending line is

 std::complex<double> *a=new std::complex<double> [4]; 
in the offload section. So what is going wrong here?

Georg

This is a possible defect. I forwarded to our C++ Front-end Developer for analysis/comment and will post when I learn more.

(Internal tracking id: DPD200241156)

(Resolution Update on 04/04/2013): This defect is fixed in the Intel C++ Composer XE 2013 Update 3 (2013.3.163 - Linux)

As I also noted in your Premier issue, the fix for this issue is available in the Composer XE 2013 Update 3 (2013.3.163) is now available from the Intel Registration Center.

登陆并发表评论。