PGI User Forum
 SearchSearch   MemberlistMemberlist     RegisterRegister   ProfileProfile    Log inLog in 

CUDA-x86.

Using PGI for compiling Matlab Executables (MEX) from C++.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    PGI User Forum Forum Index -> Programming and Compiling
View previous topic :: View next topic  
Author Message
Haakon



Joined: 18 Mar 2014
Posts: 10

PostPosted: Sun Mar 23, 2014 6:58 am    Post subject: Using PGI for compiling Matlab Executables (MEX) from C++. Reply with quote

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: http://www.walkingrandomly.com/?p=4064 ). 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:
Code:
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:
Code:

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!
Back to top
View user's profile
cparrott



Joined: 02 May 2011
Posts: 141

PostPosted: Mon Mar 24, 2014 12:02 pm    Post subject: Reply with quote

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:

http://www.pgroup.com/userforum/viewtopic.php?t=3261

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
Back to top
View user's profile
Haakon



Joined: 18 Mar 2014
Posts: 10

PostPosted: Tue Mar 25, 2014 7:40 am    Post subject: Reply with quote

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:

Code:

#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:
Quote:

>> 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,
Quote:

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


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

>> 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?
Back to top
View user's profile
cparrott



Joined: 02 May 2011
Posts: 141

PostPosted: Tue Mar 25, 2014 11:57 am    Post subject: Reply with quote

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
Back to top
View user's profile
Haakon



Joined: 18 Mar 2014
Posts: 10

PostPosted: Tue Mar 25, 2014 5:11 pm    Post subject: Reply with quote

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:
Code:

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:
Quote:

>> 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:
Code:

#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"?
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    PGI User Forum Forum Index -> Programming and Compiling All times are GMT - 7 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © phpBB Group