7

私は次の形式のプログラムを作成しました。

#include "stuff_I_need.h"

int main(){

construct_array(); // uses OpenMP pragma's
print_array();

return(0);


}

これは、次のコマンドで正しくコンパイル、リンク、および実行されます。

`gcc44 -I/home/matteson/sundials/include/ main.c -lm -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial -fopenmp -o /home/matteson/MPI_test/CVODE_test/main_test`

「gcc44」は単にgccバージョン4.4であり、gccのいくつかのバージョンを維持するクラスター上でコンパイルされているため、このように名前が付けられています。ライブラリsundials_cvodeおよびsundials_nvecserialは、配列の構築中にいくつかの微分方程式を解く際に使用されます。

ここで、Matlabに転送して、次の形式のmexファイルをコンパイルしようとすると次のようになります。

#include "stuff_I_need.h"

void mexFunction(int nlhs,mxArray* plhs[], int nrhs, const mxArray* prhs[]){

construct_array(); // uses OpenMP pragma's
print_array();

}

Matlabで次のコマンドを使用してコンパイルしてみてください。

>> mex -v CC="gcc44" CFLAGS="\$CFLAGS -I/home/matteson/sundials/include/ -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial" mex_cvode.c

次のメッセージが表示され、リンクエラーが発生します。

    -> mexopts.sh sourced from directory (DIR = $HOME/.matlab/$REL_VERSION)
   FILE = /home/matteson/.matlab/R2010b/mexopts.sh
----------------------------------------------------------------
->    MATLAB                = /misc/linux/64/opt/pkg/matlab/R2010b
->    CC                    = gcc44
->    CC flags:
         CFLAGS             = -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -L/home/matteson/sundials/lib -lsundials_nvecserial
         CDEBUGFLAGS        = -g
         COPTIMFLAGS        = -O -DNDEBUG
         CLIBS              = -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++
         arguments          =  -DMX_COMPAT_32
->    CXX                   = g++
->    CXX flags:
         CXXFLAGS           = -ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread
         CXXDEBUGFLAGS      = -g
         CXXOPTIMFLAGS      = -O -DNDEBUG
         CXXLIBS            = -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          =  -DMX_COMPAT_32
->    FC                    = g95
->    FC flags:
         FFLAGS             = -fexceptions -fPIC -fno-omit-frame-pointer
         FDEBUGFLAGS        = -g
         FOPTIMFLAGS        = -O
         FLIBS              = -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          =  -DMX_COMPAT_32
->    LD                    = gcc44
->    Link flags:
         LDFLAGS            = -pthread -shared -Wl,--version-script,/misc/linux/64/opt/pkg/matlab/R2010b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -fopenmpofopenmp
         LDDEBUGFLAGS       = -g
         LDOPTIMFLAGS       = -O
         LDEXTENSION        = .mexa64
         arguments          = 
->    LDCXX                 = 
->    Link flags:
         LDCXXFLAGS         = 
         LDCXXDEBUGFLAGS    = 
         LDCXXOPTIMFLAGS    = 
         LDCXXEXTENSION     = 
         arguments          = 
----------------------------------------------------------------


Warning: You are using gcc version "4.4.4".  The version
         currently supported with MEX is "4.3.4".
         For a list of currently supported compilers see: 
         http://www.mathworks.com/support/compilers/current_release/

-> gcc44 -c  -I/misc/linux/64/opt/pkg/matlab/R2010b/extern/include -I/misc/linux/64/opt/pkg/matlab/R2010b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -L/home/matteson/sundials/lib -lsundials_nvecserial  -DMX_COMPAT_32 -O -DNDEBUG  "mex_cvode.c"

-> gcc44 -O -pthread -shared -Wl,--version-script,/misc/linux/64/opt/pkg/matlab/R2010b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -fopenmpofopenmp -o  "mex_cvode.mexa64"  mex_cvode.o  -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++

mex_cvode.o: In function `mexFunction':
mex_cvode.c:(.text+0x2b2): undefined reference to `N_VNew_Serial'
mex_cvode.c:(.text+0x2db): undefined reference to `N_VNew_Serial'
mex_cvode.c:(.text+0x35b): undefined reference to `CVodeCreate'
mex_cvode.c:(.text+0x39c): undefined reference to `CVodeInit'
mex_cvode.c:(.text+0x3dd): undefined reference to `CVodeSVtolerances'
mex_cvode.c:(.text+0x412): undefined reference to `CVodeSetUserData'
mex_cvode.c:(.text+0x449): undefined reference to `CVDense'
mex_cvode.c:(.text+0x482): undefined reference to `CVDlsSetDenseJacFn'
mex_cvode.c:(.text+0x50c): undefined reference to `CVode'
mex_cvode.c:(.text+0x5b4): undefined reference to `N_VDestroy_Serial'
mex_cvode.c:(.text+0x5c0): undefined reference to `N_VDestroy_Serial'
mex_cvode.c:(.text+0x5cc): undefined reference to `CVodeFree'
collect2: ld returned 1 exit status

    mex: link of ' "mex_cvode.mexa64"' failed.

??? Error using ==> mex at 208
Unable to complete successfully.

どういうわけか、私は適切にリンクするための正しいフラグを与えていません。gcc44コマンドでリンクするコマンドを削除すると、同じ一連のエラー(およびさらにいくつかのエラー)が発生するため、コンパイラーにライブラリーを「認識」させていないことは間違いありません。

私の質問は:

  • エラーの分析が正しい場合、正常にリンクするには、mexコンパイルコマンドにどのフラグを渡す必要がありますか?
  • または、Matlab環境の外部でコンパイルおよびリンクして.mex64実行可能ファイルをコンパイルするためのgccフラグは何ですか?
  • 私の分析が間違っている場合、ここからどこに行くのですか?

gcc 4.4を使用してOpenMPプログラムで単純なmexをコンパイルできたので、サポートされていないコンパイラの警告を除外したと思いますが、これらは数学ライブラリ以外のものとリンクする必要はありませんでした。また、「-fopenmp」フラグの有無にかかわらず、バージョンgccバージョン4.1.2または4.3.4でコンパイルすると、同じエラーが発生します。

以前のバージョンには表示されなかった特定のOpenMPサポートのため、最終的にはバージョン4.4が必要です。

助けてくれてありがとう。

-アンドリュー

編集:(@ KWATFORD)

そのため、引用符の外側のステートメントを使用してコマンドを試したところ、エラーが発生しました。

-> gcc44 -c  -I/home/matteson/sundials/include/ -I/misc/linux/64/opt/pkg/matlab/R2010b/extern/include -I/misc/linux/64/opt/pkg/matlab/R2010b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread -fopenmp  -DMX_COMPAT_32 -O -DNDEBUG  "mex_cvode.c"

-> gcc44 -O -pthread -shared -Wl,--version-script,/misc/linux/64/opt/pkg/matlab/R2010b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -fopenmp -o  "mex_cvode.mexa64"  mex_cvode.o  -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial -Wl,-rpath-link,/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -L/misc/linux/64/opt/pkg/matlab/R2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++

/usr/bin/ld: /home/matteson/sundials/lib/libsundials_cvode.a(cvode.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/home/matteson/sundials/lib/libsundials_cvode.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

    mex: link of ' "mex_cvode.mexa64"' failed.

??? Error using ==> mex at 208
Unable to complete successfully.

「-fPIC」を使用して再コンパイルするという提案については少し混乱しています。gcc44コマンドを見ると、-fPICがオプションとして表示されているためです。

彼らは-fPICでライブラリを再コンパイルすると言っていますか?

ライブラリのソースがありません。ライブラリを再コンパイルすることが提案されている場合、回避策はありますか?

「ローカルオブジェクトに対する再配置」とはどういう意味ですか?

今後ともよろしくお願いいたします。

4

3 に答える 3

5

-lこれらの環境変数に、、、-Lまたは-I引数を入れないようにしてください。mex関数は、これらのタイプの引数を直接処理します。したがって、おそらく次のようなものです。

mex -v CC="gcc44" CFLAGS="\$CFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp" -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial mex_cvode.c
于 2011-02-07T19:20:31.897 に答える
4

Kwatfordは、2番目の質問で私を正しい方向に導いてくれました。共有ライブラリを使用して日時計ソルバーを再構築することで、mexコマンドを機能させることができました。具体的には、次のものを使用して構築しました。

% make distclean
% ./configure --prefix=/home/matteson/sundials --enable-shared
% make
% make install

また、次のように呼び出して元のファイルを修正してくれたkwatfordに感謝します。

mex -v CC="gcc44" CFLAGS="\$CFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp" -I/home/matteson/sundials/include/ -L/home/matteson/sundials/lib -lsundials_cvode -lsundials_nvecserial mex_cvode.c

mexは-Lと-Iの処理方法を知っているからです。

于 2011-02-08T07:18:16.897 に答える
0

Matlabは独自のlibstdcとlibstdc++を使用します。

ショートカットは、使用したいgcc44ライブラリへのそれらのライブラリへのsymbolinkを実行することです。

しかし、これは望ましい方法ではないかもしれません。matlabプロンプトの外部でコンパイルしてみて、それでも最初にコンパイルに失敗するかどうかを確認できます。

于 2011-02-07T18:57:07.217 に答える