Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

How to add openmp pragma in macro definitions? error LNK2019: unresolved external symbol _Pragma

mikeitexpert
New Contributor II
1,882 Views

Hello All,

I have macro definition in which I need add "pragam omp parallel" so I followed gcc function/macro _Pragma("omp parallel") as below .... 

#include <omp.h>
#include <stdio.h>
#include <math.h>
#include "mest_cmat.h"
#include "cmat_utils.h"

#ifdef COMPILER_INTEL64
#define SIMCOL  ;
#else
#define SIMCOL
#endif

#ifdef USE_OPENMP
#define OMP_PARALLEL	_Pragma("omp parallel ") SIMCOL
#define OMP_FOR    _Pragma("omp for ") SIMCOL
#else
#define OMP_PARALLEL
#define OMP_FOR
#endif


// wraplatitude
#define mac_wraplatitude_loop(V) 										\
int wraplatitude_loop_##V(cmatrix_##V lat, float pideg){				\
    OMP_PARALLEL                                                        \
    {                                                                   \
    /*printf("\n\n*** Max Thread No. : %d, Thread no: %d *** \n\n", omp_get_max_threads(), omp_get_num_threads()); */ \
    OMP_FOR                                                             \
	for(int i = 0; i < lat.nrows; i++){									\
	    /* if (i % 157 == 0) {int tid = omp_get_thread_num(); putchar('0'+tid);} */     \
		if ( abs(CIJ0(lat, i, 0)) > pideg ){							\
			CIJ0(lat, i, 0) = mod_##V##_dt_single(CIJ0(lat, i, 0) + pideg, 2 * pideg) - pideg; 	\
		}																\
		if ( abs(CIJ0(lat, i, 0)) > (pideg / 2) ){						\
			CIJ0(lat, i, 0) = CIJ0(lat, i, 0) + pideg;					\
			CIJ0(lat, i, 0) = sign_##V( CIJ0(lat, i, 0) ) * (pideg/2-(abs(CIJ0(lat,i,0))-pideg/2));	\
		}																\
	}																	\
    }                                                                   \
	return 0;															\
}

mac_wraplatitude_loop(dt_single)
mac_wraplatitude_loop(dt_double)

 

The code compiles and runs just fine using QT_MinGW gcc on Windows 10; however if try icl and xilink, the code compiles fine but it doesn't link properly. The compile and link commands are as below:

 

# compile command
icl -DCOMPILER_GNUC -DCOMPILER_INTEL64   -Qdiag-error-limit:3 -O1 -DDISABLE_SSE -DVL_DISABLE_SSE2  -DDISABLE_AVX -DVL_DISABLE_AVX  -openmp -DUSE_OPENMP -DOMP_NUM_THREADS=5 -DUSE_INTERP2_FAST -DUSE_IMTRANS_FAST -DPRJ_ROOT_DIR="" -Fo:../../Debug/obj/flat2lla_imp.obj -c flat2lla_imp.c

# link command

xilink /nodefaultlib:vcomp libiomp5md.lib -LIBPATH:Debug\lib   -out:Debug/target.exe DEBUG/obj/main_object_file.obj libsome.lib 
xilink: executing 'link'
Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/nodefaultlib:vcomp 
libiomp5md.lib 
-LIBPATH:Debug\lib 
-out:Debug/target.exe 
DEBUG/obj/main_object_file.obj 
libsome.lib(flat2lla_imp.obj) : error LNK2019: unresolved external symbol _Pragma referenced in function wraplatitude_loop_dt_single
Debug\target.exe : fatal error LNK1120: 1 unresolved externals

 

Any comments is much appreciate it.

 

Regards

0 Kudos
1 Solution
mikeitexpert
New Contributor II
1,818 Views

SUCCESS ... thanks to you I tried different permutations. It turns out I should use __pragma instead of _Pragma (as used by gcc) and ICC doesn't need the omp construct to be quoted ... so the correct syntax for ICC (icl.exe) must be like below:

#define OMP_PARALLEL __pragma(omp parallel)
#define OMP_FOR __pragma(omp for)

 

as opposed to below define which is applicable to gcc based compilers (including MinGW, Texas Instrument C6X compiler)

#define OMP_PARALLEL _Pragma("omp parallel")
#define OMP_FOR _Pragma("omp for")

 

 

View solution in original post

0 Kudos
10 Replies
jimdempseyatthecove
Honored Contributor III
1,858 Views

You (may) need to specify option for std=c++11 or later.

Jim Dempsey

0 Kudos
mikeitexpert
New Contributor II
1,850 Views

std=c++11 is a compile flag not a link one! Though I tried in case but no luck.

Anyway thanks for the comment!

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,846 Views

>>std=c++11 is a compile flag not a link one!

#pragma / _Pragma are compile time directives.

Jim Dempsey

Because you see a Linker error of undefined symbol _Pragma, this indicates that the compiler did not "_Pragma" as a compiler pragma (directive), thus indicating the compiler saw _Pragma as an external function.

Note, some dialects use double _ (__Pragma), as well as lowcase (__pragma). I suggest you experiment with permutations

_Pragma   not working
__Pragma
_pragma
__pragma

Jim Dempsey

0 Kudos
mikeitexpert
New Contributor II
1,832 Views

Thanks for comments .... I did try

-qstd=c++0x 

-qstd=c99

 

but the compiler ignores them ...  (warning #10006: ignoring unknown option '/qstd=c99')

 

I search for omp headers in the icc include folder (C:/Program Files (x86)/IntelSWTools/sw_dev_tools/compilers_and_libraries_2020.2.254/windows/compiler/include)

I get to see three omp related files : omp.h, omp_lib.h, omp-tools.h and I search them for word "pragma" but interestingly nothing found there. 

so, I started following your suggestion and tried to different permutations. If I try __pragma it seems like compiler is doing its job sort halfway because I get to see the warning "warning #161: unrecognized #pragma" so I guess the compiler was able to to inject the #pragma omp stuff but yet cannot understand the pragma directives ... 

So I guess my best bet is to try and find pragma omp syntax that sits well with icl. It is weird because I adhere to OpenMP 3.0 spec and the code compiles file on two other compilers (QtMinGW and Texas Instrument C6X compilers )

I will keep updating this thread until I found a resolution. Anyway! Let me know if you have other valuable comments.

Regards

 

 

0 Kudos
mikeitexpert
New Contributor II
1,830 Views

The other thing I can't figure out is that I CANNOT compile the code using /qopenmp as suggested by ICC Reference and Guide (the compiler prints a warning and complains it is unrecognized option), however icl.exe doesn't warn if I use -openmp which is really weird and NOT inline with the reference.

Same happens if I try [/-]qstd=c99 or [/-]std=c++0x, however this time icl still complains if I use -std intead of -qstd. Maybe I use the wrong compiler, though I am pretty sure I am using the one provided by "Intel System Studio" under C:\Program Files (x86)\IntelSWTools\sw_dev_tools\compilers_and_libraries_2020.2.254\windows\compiler.

 

I would appreciate if you share your thought on this too.

Regards

0 Kudos
mikeitexpert
New Contributor II
1,819 Views

SUCCESS ... thanks to you I tried different permutations. It turns out I should use __pragma instead of _Pragma (as used by gcc) and ICC doesn't need the omp construct to be quoted ... so the correct syntax for ICC (icl.exe) must be like below:

#define OMP_PARALLEL __pragma(omp parallel)
#define OMP_FOR __pragma(omp for)

 

as opposed to below define which is applicable to gcc based compilers (including MinGW, Texas Instrument C6X compiler)

#define OMP_PARALLEL _Pragma("omp parallel")
#define OMP_FOR _Pragma("omp for")

 

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,816 Views

Glad to hear you got it working.

I assume you figured out to use

 /Qopenmp

as opposed to

/qopenmp

By the way

  __pragma

is a compiler keyword. IOW you will not find a declaration for it in any header file. You potentially find a use, but the likelihood is small as #pragma is more compatible across vendors.

Jim Dempsey

PrasanthD_intel
Moderator
1,779 Views

Hi Mike,


Looks like your issue got resolved. If you don't have any other issues can we close this thread?

Regards

Prasanth


0 Kudos
mikeitexpert
New Contributor II
1,774 Views

Fully answered, Feel free to close the thread.

Regards

0 Kudos
PrasanthD_intel
Moderator
1,759 Views

Hi Mike,


Thanks for the confirmation. We are closing this issue, please raise a new thread for any further issue.

Any further interaction in this thread will be considered community only.


Regards

Prasanth


0 Kudos
Reply