Using PGI for compiling Matlab Executables (MEX) from C++.

Background:
I have some Matlab functions that I have implemented in C++ for my Master Thesis, and I want to try using the PGI 14.1 compiler with OpenACC to GPU-accelerate an extensive for-loop in the C++ MEX function. During the last week I have bin doing several attempts to make the unsuportet (by Matlab at least) link between PGI and MATLAB work. I have tried on Windows 7 (32bit), MAC OS X 10.9 (x86_64) and Scientific Linux 6 (x86_64). Using MATLAB 2013b for Unix, and 2013a on Windows.

All my functions is compiling fine with GCC 4.8 and 4.9 (the ones I have used earlier).

To make Matlab call PGI, a lot of tweeking has to be done in the mexopts file, and I have been doing some of this for all tree arcitectures (here is a nice guide for win64: Walking Randomly » Using the Portland PGI Compiler for MATLAB mex files in Windows #1 ). The Unix mexopts.sh file that I have adapted can be found here: http://folk.ntnu.no/seljasen/Arbeider/PGI_mexopts.sh . The most simple C++ MEX function I have been using is a C++ implementation of Matlabs normalized sinc() function for which the source code can be seen here: http://folk.ntnu.no/seljasen/Arbeider/MEX_sinc.cpp . This MEX function features OpenMP, but it compiles fine using GCC both with or without the GCC -fopenmp flag (i know this is -mp for the PGI compiler, but I am new with the whole PGI compiler bundle).

Problem:
Om both Windows and Linux the problem seems to boil down to the linking with system libraries that reqires the entry point “main” which in a MEX-function is renamed: “mexFunction”. This gives a vaiaty of different “missing entry point” errors. I have been googling for days, and it does not seem to bee very common to try and make PGI and MATLAB become friends. On some forums there is stated that I need the GCC switch “-bundle” on Unix, but this switch is not recogniced by PGI. Does there exist an equvivalent? In Windows the same gcc switch seems to be “-Mmakedll=export_all”, which also is ignored on my PGI compiler.

I do not need to compile the file on all tree platforms, but I need it on one of them to work. Preferably Linux or Windows. The object file is made without errors or warnings so this seem to be a linking problem.

Does anyone have any clue?
Tell me if you want more details.


A typical windows and Linux error msg is:

LINK : fatal error LNK1561: entry point must be defined

On MAC i suspect there are som apple issues as well, or immaturity in my adaptet mexopts function because there I get the following error:

Undefined symbols for architecture x86_64:
  "__div__Q2_3std16complex__tm__2_dSFRCdN31RdT5", referenced from:
      _mexFunction in openMP_sinc_source.o
      ___CPR79____dv__tm__2_d__3stdFRCQ2_3std18complex__tm__4_Z1ZT1_Q2_3stdJ29J in openMP_sinc_source.o
  "_main", referenced from:
      __start in crt1.o
  "_sin__3stdFRCQ2_3std16complex__tm__2_d", referenced from:
      _mexFunction in openMP_sinc_source.o
ld: symbol(s) not found for inferred architecture x86_64

    mex: link of ' "openMP_sinc_source.mexmaci64"' failed.

But it is not my focus to get this working on MAC, as the computational servers I am working on uses Linux or Windows.

Thank you in advance!

Haakon,

I’m sorry to hear you are having this issue. Our resident Matlab expert is out of the office this week, but I will do my best to try and help you.

From reading some of Mat’s previous responses, it looks like -Mmakedll=export_all is unsupported with PGI:

Mat advises users in this post to decorate symbols using the “dllexport” keyword instead. Perhaps you could try this?

From research elsewhere, -bundle seems to be an option limited to only Apple’s builds of GCC for Darwin/OS X - not sure that it is a standard GCC flag.

If these do not help, please let us know the link line you are using, and we will see if we can investigate further.

Best regards,

+chris

Thank you for your advices!

I have now tried editing the mex header file and declaring the mexFunction with __declspec(dllexport) and I also made a simpler MEX test function helloMEX.cpp to use in the set-up phase. This gave sort of the same error:

#include"mex.h"
#include"matrix.h"
#include <stdio.h>
#include <stdlib.h>


__declspec(dllexport) void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    /*The C++ MEX function "newSinc(x)" takes a matrix as input argument and computes the sinc(x)
     *value of any input element sinc(x.). */
//Validation of inputs:
    if (nlhs!=0){
        mexErrMsgIdAndTxt("Toolbox:complexSinc:nlhs","no output is allowed");
    };
    if (nrhs!=0){
        mexErrMsgIdAndTxt("Toolbox:complexSinc:nrhs","no input matrix is allowed");
    };

  mexPrintf("MEX Hello world\n");

}

The linking and compile reports where then:

mex helloMEX.cpp -v
→ Default options filename found in C:\Users\Håkon Seljåsen\AppData\Roaming\MathWorks\MATLAB\R2013a


→ Options file = C:\Users\Håkon Seljåsen\AppData\Roaming\MathWorks\MATLAB\R2013a\mexopts.bat
MATLAB = C:\Program Files\MATLAB\R2013a
→ COMPILER = pgcpp
→ Compiler flags:
COMPFLAGS = -c -Minfo -fast -mp
OPTIMFLAGS = -O3
DEBUGFLAGS =
arguments =
Name switch =
→ Pre-linking commands =
→ LINKER = pgcpp
→ Link directives:
LINKFLAGS = -I"C:\Program Files\MATLAB\R2013a\extern\include" -L"C:\Program Files\MATLAB\R2013a\extern\lib\win32\microsoft" -lmx -lmex -lmat
LINKDEBUGFLAGS =
LINKFLAGSPOST =
Name directive = -o “helloMEX.mexw32”
File link directive =
Lib. link directive =
Rsp file indicator =
→ Resource Compiler =
→ Resource Linker =



→ pgcpp -c -Minfo -fast -mp -I"C:\Program Files\MATLAB\R2013a\extern\include" -I"C:\Program Files\MATLAB\R2013a\simulink\include" -O3 -DMX_COMPAT_32 helloMEX.cpp


→ pgcpp -o “helloMEX.mexw32” -I"C:\Program Files\MATLAB\R2013a\extern\include" -L"C:\Program Files\MATLAB\R2013a\extern\lib\win32\microsoft" -lmx -lmex -lmat helloMEX.obj

Creating library C:\Users\HKONSE~1\AppData\Local\Temp/pgcpp2aY4Dw7tcu7Z_.lib and object C:\Users\HKONSE~1\AppData\Local\Temp/pgcpp2aY4Dw7tcu7Z_.exp
libcmt.lib(crt0.obj) : error LNK2019: unresolved external symbol _main referenced in function __tmainCRTStartup
C:\Users\HKONSE~1\AppData\Local\Temp/pgcpp2aY4Dw7tcu7Z
.exe : fatal error LNK1120: 1 unresolved externals

C:\PROGRA~1\MATLAB\R2013A\BIN\MEX.PL: Error: Link of ‘helloMEX.mexw32’ failed.

Error using mex (line 206)
Unable to complete successfully.

I also tried using a -export:mexFunction flag to the linker (don’t know if it is recognized by pgi) adviced in a Matlab Newsreader post: http://www.mathworks.com/matlabcentral/newsreader/view_thread/145214

In case this is a sub-option to the Mmakedll switch, I tried 3 various versions of this switch obtaining the same sort of results,

-export:mexFunction,
-Mmakedll=export_mexFunction
and
–Mmakedll=export:mexFunction

This did not give any noticable results. The set-up and respons are quoted below

mex helloMEX.cpp -v
→ Default options filename found in C:\Users\Håkon Seljåsen\AppData\Roaming\MathWorks\MATLAB\R2013a


→ Options file = C:\Users\Håkon Seljåsen\AppData\Roaming\MathWorks\MATLAB\R2013a\mexopts.bat
MATLAB = C:\Program Files\MATLAB\R2013a
→ COMPILER = pgcpp
→ Compiler flags:
COMPFLAGS = -c -Minfo -fast -mp
OPTIMFLAGS = -O3
DEBUGFLAGS =
arguments =
Name switch =
→ Pre-linking commands =
→ LINKER = pgcpp
→ Link directives:
LINKFLAGS = -export:mexFunction –Mmakedll=export_all -I"C:\Program Files\MATLAB\R2013a\extern\include" -L"C:\Program Files\MATLAB\R2013a\extern\lib\win32\microsoft" -lmx -lmex -lmat
LINKDEBUGFLAGS =
LINKFLAGSPOST =
Name directive = -o “helloMEX.mexw32”
File link directive =
Lib. link directive =
Rsp file indicator =
→ Resource Compiler =
→ Resource Linker =



→ pgcpp -c -Minfo -fast -mp -I"C:\Program Files\MATLAB\R2013a\extern\include" -I"C:\Program Files\MATLAB\R2013a\simulink\include" -O3 -DMX_COMPAT_32 helloMEX.cpp


→ pgcpp -o “helloMEX.mexw32” -export:mexFunction –Mmakedll=export_all -I"C:\Program Files\MATLAB\R2013a\extern\include" -L"C:\Program Files\MATLAB\R2013a\extern\lib\win32\microsoft" -lmx -lmex -lmat helloMEX.obj

Creating library C:\Users\HKONSE~1\AppData\Local\Temp/pgcpp2aC8Kbuc7KLVxs.lib and object C:\Users\HKONSE~1\AppData\Local\Temp/pgcpp2aC8Kbuc7KLVxs.exp
libcmt.lib(crt0.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
C:\Users\HKONSE~1\AppData\Local\Temp/pgcpp2aC8Kbuc7KLVxs.exe : fatal error LNK1120: 1 unresolved externals

C:\PROGRA~1\MATLAB\R2013A\BIN\MEX.PL: Error: Link of ‘helloMEX.mexw32’ failed.

Error using mex (line 206)
Unable to complete successfully.

.
I could go ahead and install a 64 bit version of Windows if this could help me, but I suspect the same problem would re-appear anyway.

Does these two logs also include the link line information you requested?

Haakon,

It looks like you do need a -Mmakedll option to tell the linker to link the code as a DLL and not a standalone binary. The error you are getting is due to the fact that the linker thinks you are trying to make a standalone program, and you have not defined a main() function. It probably does not hurt to append the export_all flag to -Mmakedll, even though it is not officially supported by PGI and may not work in all cases (hence the dllexport decorations).

I took a look at the Walking Randomly page you mentioned, and in the pgi.bat file, the author sets these linker flags:

set LINKFLAGS=-Mmakedll=export_all -implib “%LIB_NAME%.x” -L"%LIBLOC%" libmx.lib libmex.lib libmat.lib

It’s not clear from the batch file where %LIB_NAME% gets defined, though - perhaps this comes from MEX?

Hopefully this helps.

Best regards,

+chris

I adjusted the mexopts file so it corresponds with the file in the post. %LIB_NAME% is automaticaly defined in MEX. My current mexopts file is:

rem Version 1
rem Original version, by Mike Croucher (www.walkingrandomly.com)
rem win32 tweeks by Håkon Seljåsen

@echo off

set MATLAB=%MATLAB%

set PGINSTALLDIR=C:\Program Files\PGI\win32\14.3\bin


set COMPILER=pgcpp


set PATH=%PGINSTALLDIR%;%MATLAB_BIN%;%PATH%

set LIB=%MATLAB%\extern\lib\win32;%LIB%

set INCLUDE=%INCLUDE%

set MW_TARGET_ARCH=win32

set COMPFLAGS=-c -Minfo -fast -mp
set LINKER=pgcpp
pp
set OPTIMFLAGS=-O3  
set LIBLOC=%MATLAB%\extern\lib\win32\microsoft
set INCLUDE_MEX=%MATLAB%\extern\include
set LINKFLAGS=  -Mmakedll=export_all  -implib "%LIB_NAME%.x" -L"%LIBLOC%" libmx.lib libmex.lib libmat.lib
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"

The Matlab-translated version is the first part of the compile report:

mex helloMEX.cpp -v
→ Default options filename found in C:\Users\Håkon Seljåsen\AppData\Roaming\MathWorks\MATLAB\R2013a


→ Options file = C:\Users\Håkon Seljåsen\AppData\Roaming\MathWorks\MATLAB\R2013a\mexopts.bat
MATLAB = C:\Program Files\MATLAB\R2013a
→ COMPILER = pgcpp
→ Compiler flags:
COMPFLAGS = -c -Minfo -fast -mp
OPTIMFLAGS = -O3
DEBUGFLAGS =
arguments =
Name switch =
→ Pre-linking commands =
→ LINKER = pgcpp
→ Link directives:
LINKFLAGS = -Mmakedll=export_all -implib “C:\Users\HKONSE~1\AppData\Local\Temp\mex_5FK3G4\templib.x” -L"C:\Program Files\MATLAB\R2013a\extern\lib\win32\microsoft" libmx.lib libmex.lib libmat.lib
LINKDEBUGFLAGS =
LINKFLAGSPOST =
Name directive = -o “helloMEX.mexw32”
File link directive =
Lib. link directive =
Rsp file indicator =
→ Resource Compiler =
→ Resource Linker =



→ pgcpp -c -Minfo -fast -mp -I"C:\Program Files\MATLAB\R2013a\extern\include" -I"C:\Program Files\MATLAB\R2013a\simulink\include" -O3 -DMX_COMPAT_32 helloMEX.cpp


→ pgcpp -o “helloMEX.mexw32” -Mmakedll=export_all -implib “C:\Users\HKONSE~1\AppData\Local\Temp\mex_5FK3G4\templib.x” -L"C:\Program Files\MATLAB\R2013a\extern\lib\win32\microsoft" libmx.lib libmex.lib libmat.lib helloMEX.obj

Creating library C:\Users\HKONSE~1\AppData\Local\Temp\mex_5FK3G4\templib.x and object C:\Users\HKONSE~1\AppData\Local\Temp\mex_5FK3G4\templib.exp
LINK : fatal error LNK1561: entry point must be defined

C:\PROGRA~1\MATLAB\R2013A\BIN\MEX.PL: Error: Link of ‘helloMEX.mexw32’ failed.

Error using mex (line 206)
Unable to complete successfully.

As you see, i still have the same problems…
My dllexport helloMEX.cpp looks like this:

#include"mex.h"
#include"matrix.h"
#include <stdio.h>
#include <stdlib.h>

void __declspec(dllexport) mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
//Declaration of mexFunction is also edited in the mex.h header file....
//Error tests:
    if (nlhs!=0){
        mexErrMsgIdAndTxt("Toolbox:complexSinc:nlhs","no output is allowed");
    };
    if (nrhs!=0){
        mexErrMsgIdAndTxt("Toolbox:complexSinc:nrhs","no input matrix is allowed");
    };
  mexPrintf("MEX Hello world\n");
};

I see some places that dllimport also is used, is this something i have to think about?

How would a similar linker call look in linux?

The mystical thing is that the MEX file is a semi standalone program, including a modifyed entry point called mexFunction. Maybe there is some way to make an alias list, that tricks the linker to think mexFunction means “main”?

I have now made a setup on linux with the following mex-options and linking line.
Maybe it is easier to figure out how to do this on Linux. I run PGI 14.1 and Matlab 2013a on my Ubuntu 12.

Still the linking with the absence of main() is the problem.

→ mexopts.sh sourced from directory (DIR = .)
FILE = /home/haakon/Dropbox/NTNU/Masteroppgave/Propose_MAC_test/Sinc_test/mexopts.sh

→ MATLAB = /usr/local/MATLAB/R2013a
→ CC = /opt/pgi/linux86-64/14.3/bin/pgcc
→ CC flags:
CFLAGS = -ansi -D_GNU_SOURCE -fpic -Mframe -mp
CDEBUGFLAGS = -g
COPTIMFLAGS = -O3
CLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lstdc++
arguments = -DMX_COMPAT_32
→ CXX = /opt/pgi/linux86-64/14.3/bin/pgcpp
→ CXX flags:
CXXFLAGS = -Mframe -mp
CXXDEBUGFLAGS = -g
CXXOPTIMFLAGS = -O3 -DNDEBUG
CXXLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat
arguments = -DMX_COMPAT_32
→ FC = gfortran
→ FC flags:
FFLAGS = -fbackslash -fpic -Mframe
FDEBUGFLAGS = -g
FOPTIMFLAGS = -O3
FLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat
arguments = -DMX_COMPAT_32
→ LD = /opt/pgi/linux86-64/14.3/bin/pgcpp
→ Link flags:
LDFLAGS = -Bdynamic -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined
LDDEBUGFLAGS = -g
LDOPTIMFLAGS = -O
LDEXTENSION = .mexa64
arguments =
→ LDCXX =
→ Link flags:
LDCXXFLAGS =
LDCXXDEBUGFLAGS =
LDCXXOPTIMFLAGS =
LDCXXEXTENSION =
arguments =

/usr/local/MATLAB/R2013a/bin/mex: 305: /usr/local/MATLAB/R2013a/bin/mex: /opt/pgi/linux86-64/14.3/bin/pgcc: not found

Warning: You are using gcc version “”. The version
currently supported with MEX is “4.4.x”.
For a list of currently supported compilers see:
Compatible Windows Compilers - MATLAB & Simulink

→ /opt/pgi/linux86-64/14.3/bin/pgcpp -c -I/usr/local/MATLAB/R2013a/extern/include -I/usr/local/MATLAB/R2013a/simulink/include -DMATLAB_MEX_FILE -Mframe -mp -DMX_COMPAT_32 -O3 -DNDEBUG “helloMEX.cpp”

→ /opt/pgi/linux86-64/14.3/bin/pgcpp -O -Bdynamic -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined -o “helloMEX.mexa64” helloMEX.o -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat

/usr/lib/x86_64-linux-gnu/crt1.o: In function _start': (.text+0x20): undefined reference to main’

mex: link of ’ “helloMEX.mexa64”’ failed.

Error using mex (line 206)
Unable to complete successfully.

I don’t know the reason for all the various linking flags, as they are set using the gcc version of the mexopts.sh file as a basis. From this default gcc setup i had to remove the following CXXFLAGS:

pgcpp-Error-Unknown switch: -fno-omit-frame-pointer
pgcpp-Error-Unknown switch: -pthread

This made the compiler run, and give the error msg. above. I suspect that I may need a PGI equivalent to theese two switches or something similar. Hope someone has a clue, as it would be wery interesting to compare OpenACC to OpenMP in my thesis.

Is there any Linux equivalent to the “__declspec(dllexport)” suggested earlier in this threas (using windows).

Haakon,

The equivalent PGI option to -fomit-frame-pointer is -Mnoframe.

THe -pthread flag in GCC is just a convenience flag that automatically pulls in the header files and libraries for POSIX threads. For PGI, I believe you can get away with just adding -lpthread to the list of libraries to link. You might even be able to get away with omitting this altogether, unless the code you are compiling uses POSIX threads.

As for the main() problem (pardon the pun!) - you need to pass the -shared flag to pgcc. pgcc, in turn, will pass this flag to ld (the GNU linker). This tells ld to link the objects as a shared library, and not a standalone executable. I believe this is what Matlab is expecting.

Hope this helps,

+chris

Thank you.

The -Mnoframe switch moved me forward a bit. A new error concerning the libstdc++ appears and including the -shared switch still gives the same error.

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -O3 -shared -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined -o “helloMEX.mexa64” helloMEX.o -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm

/usr/bin/ld: cannot find -lstdc++

When i tride to include the PGI path -L/opt/pgi/linux86-64/14.3/lib (to tell the compiler where to look for libstdc++), an additional error that propts for the -fpic switch appears (which is already turned on but apparently is beeing ignored). This error only appears when both the PGI lib path is included, and -shared is turned on:

/usr/bin/ld: /opt/pgi/linux86-64/14.3/lib/libpgmp.a(preinit2.o): relocation R_X86_64_32S against `.bss’ can not be used when making a shared object; recompile with -fPIC
/opt/pgi/linux86-64/14.3/lib/libpgmp.a: could not read symbols: Bad value

Full recipts are included below, first without the -shared switch but with -L/opt/pgi/linux86-64/14.3/lib included (this path seem to make no difference) :

→ mexopts.sh sourced from directory (DIR = .)
FILE = /home/haakon/Dropbox/NTNU/Masteroppgave/Propose_MAC_test/Sinc_test/mexopts.sh

→ MATLAB = /usr/local/MATLAB/R2013a
→ CC = /opt/pgi/linux86-64/14.3/bin/pgcc
→ CC flags:
CFLAGS = -ansi -D_GNU_SOURCE -fpic -Mnoframe -mp
CDEBUGFLAGS = -g
COPTIMFLAGS = -O3
CLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat
arguments = -DMX_COMPAT_32
→ CXX = /opt/pgi/linux86-64/14.3/bin/pgc++
→ CXX flags:
CXXFLAGS = -Mnoframe -fPIC -largeArrayDims
CXXDEBUGFLAGS = -g
CXXOPTIMFLAGS = -O3 -DNDEBUG
CXXLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm -L/opt/pgi/linux86-64/14.3/lib
arguments = -DMX_COMPAT_32
→ FC = gfortran
→ FC flags:
FFLAGS = -fbackslash -fpic -Mnoframe -pthread
FDEBUGFLAGS = -g
FOPTIMFLAGS = -O3
FLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm
arguments = -DMX_COMPAT_32
→ LD = /opt/pgi/linux86-64/14.3/bin/pgc++
→ Link flags:
LDFLAGS = -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined
LDDEBUGFLAGS = -g
LDOPTIMFLAGS = -O3
LDEXTENSION = .mexa64
arguments =
→ LDCXX =
→ Link flags:
LDCXXFLAGS =
LDCXXDEBUGFLAGS =
LDCXXOPTIMFLAGS =
LDCXXEXTENSION =
arguments =

/usr/local/MATLAB/R2013a/bin/mex: 305: /usr/local/MATLAB/R2013a/bin/mex: /opt/pgi/linux86-64/14.3/bin/pgcc: not found

Warning: You are using gcc version “”. The version
currently supported with MEX is “4.4.x”.
For a list of currently supported compilers see:
Compatible Windows Compilers - MATLAB & Simulink

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -c -I/usr/local/MATLAB/R2013a/extern/include -I/usr/local/MATLAB/R2013a/simulink/include -DMATLAB_MEX_FILE -Mnoframe -fPIC -largeArrayDims -DMX_COMPAT_32 -O3 -DNDEBUG “helloMEX.cpp”

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -O3 -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined -o “helloMEX.mexa64” helloMEX.o -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm -L/opt/pgi/linux86-64/14.3/lib

/usr/bin/ld: cannot find -lstdc++

mex: link of ’ “helloMEX.mexa64”’ failed.

Including the -shared switch gives me additional errors:

→ mexopts.sh sourced from directory (DIR = .)
FILE = /home/haakon/Dropbox/NTNU/Masteroppgave/Propose_MAC_test/Sinc_test/mexopts.sh

→ MATLAB = /usr/local/MATLAB/R2013a
→ CC = /opt/pgi/linux86-64/14.3/bin/pgcc
→ CC flags:
CFLAGS = -ansi -D_GNU_SOURCE -fpic -Mnoframe -mp
CDEBUGFLAGS = -g
COPTIMFLAGS = -O3
CLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat
arguments = -DMX_COMPAT_32
→ CXX = /opt/pgi/linux86-64/14.3/bin/pgc++
→ CXX flags:
CXXFLAGS = -Mnoframe -fPIC -largeArrayDims
CXXDEBUGFLAGS = -g
CXXOPTIMFLAGS = -O3 -DNDEBUG
CXXLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm -L/opt/pgi/linux86-64/14.3/lib
arguments = -DMX_COMPAT_32
→ FC = gfortran
→ FC flags:
FFLAGS = -fbackslash -fpic -Mnoframe -pthread
FDEBUGFLAGS = -g
FOPTIMFLAGS = -O3
FLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm
arguments = -DMX_COMPAT_32
→ LD = /opt/pgi/linux86-64/14.3/bin/pgc++
→ Link flags:
LDFLAGS = -shared -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined
LDDEBUGFLAGS = -g
LDOPTIMFLAGS = -O3
LDEXTENSION = .mexa64
arguments =
→ LDCXX =
→ Link flags:
LDCXXFLAGS =
LDCXXDEBUGFLAGS =
LDCXXOPTIMFLAGS =
LDCXXEXTENSION =
arguments =

/usr/local/MATLAB/R2013a/bin/mex: 305: /usr/local/MATLAB/R2013a/bin/mex: /opt/pgi/linux86-64/14.3/bin/pgcc: not found

Warning: You are using gcc version “”. The version
currently supported with MEX is “4.4.x”.
For a list of currently supported compilers see:
Compatible Windows Compilers - MATLAB & Simulink

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -c -I/usr/local/MATLAB/R2013a/extern/include -I/usr/local/MATLAB/R2013a/simulink/include -DMATLAB_MEX_FILE -Mnoframe -fPIC -largeArrayDims -DMX_COMPAT_32 -O3 -DNDEBUG “helloMEX.cpp”

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -O3 -shared -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined -o “helloMEX.mexa64” helloMEX.o -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm -L/opt/pgi/linux86-64/14.3/lib

/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: /opt/pgi/linux86-64/14.3/lib/libpgmp.a(preinit2.o): relocation R_X86_64_32S against `.bss’ can not be used when making a shared object; recompile with -fPIC
/opt/pgi/linux86-64/14.3/lib/libpgmp.a: could not read symbols: Bad value

mex: link of ’ “helloMEX.mexa64”’ failed.

Error using mex (line 206)
Unable to complete successfully.

Running without giving the PGI lib path, and leaving the -shared switch on gives the same error as the first test (with path + Mnoframe, but no -shared switch):

→ mexopts.sh sourced from directory (DIR = .)
FILE = /home/haakon/Dropbox/NTNU/Masteroppgave/Propose_MAC_test/Sinc_test/mexopts.sh

→ MATLAB = /usr/local/MATLAB/R2013a
→ CC = /opt/pgi/linux86-64/14.3/bin/pgcc
→ CC flags:
CFLAGS = -ansi -D_GNU_SOURCE -fpic -Mnoframe -mp
CDEBUGFLAGS = -g
COPTIMFLAGS = -O3
CLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat
arguments = -DMX_COMPAT_32
→ CXX = /opt/pgi/linux86-64/14.3/bin/pgc++
→ CXX flags:
CXXFLAGS = -Mnoframe -fPIC -largeArrayDims
CXXDEBUGFLAGS = -g
CXXOPTIMFLAGS = -O3 -DNDEBUG
CXXLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm
arguments = -DMX_COMPAT_32
→ FC = gfortran
→ FC flags:
FFLAGS = -fbackslash -fpic -Mnoframe -pthread
FDEBUGFLAGS = -g
FOPTIMFLAGS = -O3
FLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm
arguments = -DMX_COMPAT_32
→ LD = /opt/pgi/linux86-64/14.3/bin/pgc++
→ Link flags:
LDFLAGS = -shared -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined
LDDEBUGFLAGS = -g
LDOPTIMFLAGS = -O3
LDEXTENSION = .mexa64
arguments =
→ LDCXX =
→ Link flags:
LDCXXFLAGS =
LDCXXDEBUGFLAGS =
LDCXXOPTIMFLAGS =
LDCXXEXTENSION =
arguments =

/usr/local/MATLAB/R2013a/bin/mex: 305: /usr/local/MATLAB/R2013a/bin/mex: /opt/pgi/linux86-64/14.3/bin/pgcc: not found

Warning: You are using gcc version “”. The version
currently supported with MEX is “4.4.x”.
For a list of currently supported compilers see:
Compatible Windows Compilers - MATLAB & Simulink

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -c -I/usr/local/MATLAB/R2013a/extern/include -I/usr/local/MATLAB/R2013a/simulink/include -DMATLAB_MEX_FILE -Mnoframe -fPIC -largeArrayDims -DMX_COMPAT_32 -O3 -DNDEBUG “helloMEX.cpp”

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -O3 -shared -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined -o “helloMEX.mexa64” helloMEX.o -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm

/usr/bin/ld: cannot find -lstdc++

mex: link of ’ “helloMEX.mexa64”’ failed.

Error using mex (line 206)
Unable to complete successfully.

I am still kind of lost. Sorry if some of this might be noob-issues. I am running Linux.

Haakon,

I’m a bit perplexed by this message:

/opt/pgi/linux86-64/14.3/bin/pgcc: not found

Any idea why pgcc is missing from this directory, but pgc++ is found? Strange.

libstdc++ is the standard GNU C++ library. Most systems have it installed in /usr/lib or /usr/lib64:

cparrott ~ $ ls -l /usr/lib/libstdc++*
lrwxrwxrwx 1 root root 19 Sep 6 2012 /usr/lib/libstdc++.so.6 → libstdc++.so.6.0.13
-rwxr-xr-x 1 root root 930192 Aug 24 2011 /usr/lib/libstdc++.so.6.0.13
cparrott ~ $

Hope this helps,

+chris
[/quote]

Thank you a whole lot!

I think you hit the right spot here. For some reason the pgcc file was absent in the /opt/pgi/linux86-64/14.3/bin/ folder. However there was a file called “pgCC (Case Conflict)” in addition to the pgCC file, maybe this first one has been named uncorrect for some reason.

Now I am able to compile the HelloMEX function on Linux x86-64 using the following mexopts.sh file (I only quote the Linux 64 bit part of the file):

#(…)
#—Line 96:
glnxa64)
#----------------------------------------------------------------------------
RPATH=“-Wl,-rpath-link,$TMW_ROOT/bin/$Arch”

StorageVersion: 1.0

CkeyName: PGI C

CkeyManufacturer: PGI

CkeyLanguage: C

CkeyVersion: 14.3

CC=‘/opt/pgi/linux86-64/14.3/bin/pgCC’
CFLAGS=‘-ansi -D_GNU_SOURCE’
CFLAGS=“$CFLAGS "
CFLAGS=”$CFLAGS -fpic -Mnoframe -mp"
CLIBS=“$RPATH $MLIBS”
COPTIMFLAGS=‘-O3 ’ #-DNDEBUG
CDEBUGFLAGS=‘-g’
CLIBS="$CLIBS "

C++keyName: PGI C++

C++keyManufacturer: PGI

C++keyLanguage: C++

C++keyVersion: 14.3

CXX=‘/opt/pgi/linux86-64/14.3/bin/pgc++’

CXXFLAGS=‘-ansi -D_GNU_SOURCE’

CXXFLAGS="$CXXFLAGS -Mnoframe -fPIC -largeArrayDims "

CXXLIBS=“$RPATH $MLIBS -lm -L”/usr/lib/x86_64-linux-gnu" "
CXXOPTIMFLAGS=‘-O3 -DNDEBUG’
CXXDEBUGFLAGS=‘-g’

FortrankeyName: gfortran

FortrankeyManufacturer: GNU

FortrankeyLanguage: Fortran

FortrankeyVersion:

FC=‘gfortran’
FFLAGS=’ -fbackslash’
FFLAGS=“$FFLAGS -fpic -Mnoframe -pthread”
FLIBS=“$RPATH $MLIBS -lm”
FOPTIMFLAGS=‘-O3’
FDEBUGFLAGS=‘-g’

LD=‘/opt/pgi/linux86-64/14.3/bin/pgCC’ #“$COMPILER”
LDEXTENSION=‘.mexa64’
LDFLAGS=“-shared -Wl,–version-script,$TMW_ROOT/extern/lib/$Arch/$MAPFILE -Wl,–no-undefined”
LDOPTIMFLAGS=‘-O3’
LDDEBUGFLAGS=‘-g’

POSTLINK_CMDS=‘:’
#----------------------------------------------------------------------------
;;
sol64)
#-----line 146
#(…)

Your question gave me a clue about pgcc beeing the correct linker to use also if the file compiled is C++. So I changed the mexopts.sh file specifying the linker:

LD=‘/opt/pgi/linux86-64/14.3/bin/pgCC’ #“$COMPILER”

Maybe this was the problem, that MEX tried to give the linking call to pgcpp?
Note also here that i specified pgCC to avoid the whole mystical pgcc thing.

I also found my libstdc++ file (Ubuntu 12) in the folder

/usr/lib/x86_64-linux-gnu/

Compiling and running helloMEX now goes:

#include"mex.h"
#include"matrix.h"
#include <stdio.h>
#include <stdlib.h>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
//Error tests:
    if (nlhs!=0){
        mexErrMsgIdAndTxt("Toolbox:complexSinc:nlhs","no output is allowed");
    };
    if (nrhs!=0){
        mexErrMsgIdAndTxt("Toolbox:complexSinc:nrhs","no input matrix is allowed");
    };

  mexPrintf("MEX Hello world\n");

};



mex helloMEX.cpp -v


Warning: Neither -compatibleArrayDims nor -largeArrayDims is selected.
Using -compatibleArrayDims. In the future, MATLAB will require
the use of -largeArrayDims and remove the -compatibleArrayDims
option. For more information, see:
Upgrade MEX Files to Use 64-Bit API - MATLAB & Simulink


→ mexopts.sh sourced from directory (DIR = .)
FILE = /home/haakon/Dropbox/NTNU/Masteroppgave/Propose_MAC_test/Sinc_test/mexopts.sh

→ MATLAB = /usr/local/MATLAB/R2013a
→ CC = /opt/pgi/linux86-64/14.3/bin/pgCC
→ CC flags:
CFLAGS = -ansi -D_GNU_SOURCE -fpic -Mnoframe -mp
CDEBUGFLAGS = -g
COPTIMFLAGS = -O3
CLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat
arguments = -DMX_COMPAT_32
→ CXX = /opt/pgi/linux86-64/14.3/bin/pgc++
→ CXX flags:
CXXFLAGS = -Mnoframe -fPIC -largeArrayDims
CXXDEBUGFLAGS = -g
CXXOPTIMFLAGS = -O3 -DNDEBUG
CXXLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm -L/usr/lib/x86_64-linux-gnu
arguments = -DMX_COMPAT_32
→ FC = gfortran
→ FC flags:
FFLAGS = -fbackslash -fpic -Mnoframe -pthread
FDEBUGFLAGS = -g
FOPTIMFLAGS = -O3
FLIBS = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm
arguments = -DMX_COMPAT_32
→ LD = /opt/pgi/linux86-64/14.3/bin/pgCC
→ Link flags:
LDFLAGS = -shared -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined
LDDEBUGFLAGS = -g
LDOPTIMFLAGS = -O3
LDEXTENSION = .mexa64
arguments =
→ LDCXX =
→ Link flags:
LDCXXFLAGS =
LDCXXDEBUGFLAGS =
LDCXXOPTIMFLAGS =
LDCXXEXTENSION =
arguments =

→ /opt/pgi/linux86-64/14.3/bin/pgc++ -c -I/usr/local/MATLAB/R2013a/extern/include -I/usr/local/MATLAB/R2013a/simulink/include -DMATLAB_MEX_FILE -Mnoframe -fPIC -largeArrayDims -DMX_COMPAT_32 -O3 -DNDEBUG “helloMEX.cpp”

→ /opt/pgi/linux86-64/14.3/bin/pgCC -O3 -shared -Wl,–version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,–no-undefined -o “helloMEX.mexa64” helloMEX.o -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm -L/usr/lib/x86_64-linux-gnu

helloMEX
MEX Hello world

Now the compiling works and I am exited about trying out OpenACC.

Btw. I get a lot of warnings like:

“/opt/pgi/linux86-64/14.3/include/math.h”, line 282: warning: allowing all
exceptions is incompatible with previous function “pow” (declared at
line 155 of “/usr/include/x86_64-linux-gnu/bits/mathcalls.h”)
double pow(double,double);

when I compile the MEX version of sinc() that I mentioned in the first post. Is this something to worry about? Guess not…

Again thank you a whole lot for all help! I can post a final version of the working mexopts.sh file next week, after cleaning it up a bit.