現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
Why OpenMP does not work in a CUDA code compiled in Matlab (as a MEX)?
13 ビュー (過去 30 日間)
古いコメントを表示
Moein Mozaffarzadeh
2021 年 9 月 20 日
Hi, I'm trying to use OpenMP in my CUDA code, compile and use it in Matlab. However, it does not work. Here is a simple example:
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <stdio.h>
#include "cuda.h"
#include "mex.h"
#include "omp.h"
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[])
{
#pragma omp parallel
{
int ID = omp_get_thread_num();
printf("Hello(%d)", ID);
printf("World(%d) \n", ID);
}
}
I use
mexcuda OpenMPTest.cu
to compile this code in Matlab. When i run this in Matlab, all I get is "Hello(0)World(0) ". So, something is wrong. Maybe the probem is with the way that I compile?!!! Please help.
Moein.
20 件のコメント
Walter Roberson
2021 年 9 月 20 日
Moein Mozaffarzadeh
2021 年 9 月 20 日
編集済み: Walter Roberson
2021 年 9 月 20 日
Hi Walter,
I have already seen that post. It does not provide any compiling solution.
could you please let me know how i can add liomp5 to my build line?
Searching through the web, i got this one so far, but no changes! The code gets compiled well, but ThreadID is always zero.
mexcuda C:\ProgramData\MATLAB\SupportPackages\R2021a\3P.instrset\mingw_w64.instrset\lib\gcc\x86_64-w64-mingw32\6.3.0\libgomp.a -v CFLAGS="$CFLAGS -fopenmp" -LDFLAGS="$LDFLAGS -fopenmp" Xcompiler="-fopenmp" OpenMPTest.cu
Walter Roberson
2021 年 9 月 20 日
-liomp5 is probably the flag needed; you might also need a -L flag to point to the directory the library is in.
The -l part is a flag, and iomp5 is its argument, but by convention the linker will automatically try prefixing it with l and lib to search for it. You can also give a specific name and extension
I did not realize that OpenMP could be used with CUDA, so this is not something I have experience with myself.
Joss Knight
2021 年 9 月 20 日
Sorry, I'm not an OpenMP expert. Are you sure you've specified that more than one thread should be created? Don't you have to compile with -fopenmp, which you might need to add to the CXXFLAGS variables when invoked using MEX?
Walter Roberson
2021 年 9 月 20 日
Ah, add the -fopenmp to the CXXFLAGs instead of the current CFLAGS location ?
Moein Mozaffarzadeh
2021 年 9 月 20 日
I added -fopenmp to the CXXFLAGs instead of the current CFLAGS, but still the threadID is zero.
I cannot find iomp5 anywhere. Any idea at what directory this could be found?
Moein Mozaffarzadeh
2021 年 9 月 20 日
I just tried the following .cpp code to see if the problem is with my OMP or the cuda compiler is the problem.
#include <stdio.h>
#include "mex.h"
#include "omp.h"
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[])
{
omp_set_num_threads(4);
#pragma omp parallel
{
printf("Hello(%d), ", omp_get_thread_num());
printf("World(%d) \n", omp_get_thread_num());
}
}
I used the following code
mex C:\ProgramData\MATLAB\SupportPackages\R2021a\3P.instrset\mingw_w64.instrset\lib\gcc\x86_64-w64-mingw32\6.3.0\libgomp.a -v ...
CXXFLAGS="$CXXFLAGS -fopenmp" LDFLAGS="$LDFLAGS -fopenmp" Xcompiler="-fopenmp" OpenMPTest.cpp
to compile. Unfortunately, it does not even compile. I get the following error:
... OpenMPTest.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in
Any idea what is the problem now?
Bruno Luong
2021 年 9 月 20 日
編集済み: Bruno Luong
2021 年 9 月 20 日
cc = cc(loc);
if contains(cc.ShortName,'MSVC')
opmopt = {'COMPFLAGS="$COMPFLAGS /openmp"'};
elseif contains(cc.ShortName,'INTEL')
opmopt = {'COMPFLAGS="$COMPFLAGS /MD /Qopenmp"'};
elseif contains(cc.ShortName,{'gcc' 'mingw64'}) % not tested
opmopt = {'CFLAGS="$CFLAGS -fopenmp"'
'LDFLAGS="$LDFLAGS -fopenmp"'};
else
fprintf('Error: Not known compiler\n')
fprintf('You might want to edit %s if you know how to setup openmp options\n', me)
return
end
No idea how to compile (or compatible) with CUDA.
Note that the MSVS OpenMP has some limitation.
Moein Mozaffarzadeh
2021 年 9 月 20 日
I have just tried to compile outside of Matlab environment to see if the problem is with the compiler or Matlab. I used
g++ OpenMPTest.c -o OpenMPTest.exe -fopenmp
in the windows command bar, and compiled the following code.
#include <stdio.h>
//#include "mex.h"
#include "omp.h"
#include <unistd.h>
//void mexFunction(int nlhs, mxArray* plhs[],
// int nrhs, const mxArray* prhs[])
int main ()
{
#pragma omp parallel
{
printf("Hello(%d), ", omp_get_thread_num());
printf("World(%d) \n", omp_get_thread_num());
}
system("pause");
return 0;
}
It works well. So, there is nothing wrong with the compiler installation in my Laptop.
I changed the code back to the version the output will be a MEX file as follows:
#include <stdio.h>
#include "mex.h"
#include "omp.h"
#include <unistd.h>
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[])
//int main ()
{
#pragma omp parallel
{
printf("Hello(%d), ", omp_get_thread_num());
printf("World(%d) \n", omp_get_thread_num());
}
system("pause");
// return 0;
}
and now using the following to compile, following your suggestion:
mex -v CFLAGS="$CFLAGS -fopenmp" LDFLAGS="$LDFLAGS -fopenmp" OpenMPTest.c
the code compiles, but my Matlab crashes once i run the .mex file. Please let me know what is it that I'm missing.
Moein.
Bruno Luong
2021 年 9 月 20 日
I never use "printf" in mex, rather mexPrintf(), but such function are not suitable for parallel calling (notr reentrance).
You must test with something simple.
Joss Knight
2021 年 9 月 21 日
It certainly could be a problem that you're using printf, which MEX overrides with mexPrintf in order to output to the command window; thus you may be attempting to call into MATLAB from two different threads, which won't be supported.
Try using fprintf(stderr, ...) or just put #undef printf at the top of your file.
I'm guessing attempting a system call in a mexFunction may be inadvisable too, not sure though.
Joss Knight
2021 年 9 月 21 日
By the way if you were already adding -fopenmp to CFLAGS then that's fine, it won't make any difference adding it to CXXFLAGS. All that really matters is the compiler command you see in the verbose output ( -v ) . As long as the right compiler switches appear in that line (or those lines) you know the right thing is happening. MEX is basically just a MAKE system which helps you invoke your compiler with the right commands and with the correct environment variables set on the system. With a bit of clever interpretation you can reproduce its behaviour using system calls (but getting all the library and include paths right is hard).
Moein Mozaffarzadeh
2021 年 9 月 21 日
thank you @Joss Knight and @Bruno Luong for your help. you were rigth about printf. So, i changed the code as follows:
#include <stdio.h>
#include "mex.h"
#include "omp.h"
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[])
//int main ()
{
int* Output;
plhs[0] = mxCreateNumericMatrix(1, 6, mxINT32_CLASS, mxREAL);
Output = (int*)mxGetData(plhs[0]);
omp_set_num_threads(6);
#pragma omp parallel
{
int ID = omp_get_thread_num();
Output[ID] = ID+10;
}
}
So, as you have noticed. this is a C code. So, I compiled it with the following command in Matlab and it works fine:
mex CFLAGS="$CFLAGS -fopenmp" LDFLAGS="$LDFLAGS -fopenmp" OpenMPTest.c
Now, here is the same code, but in .cu format:
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <stdio.h>
#include "cuda.h"
#include "mex.h"
#include "omp.h"
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[])
{
int* Output;
plhs[0] = mxCreateNumericMatrix(1, 6, mxINT32_CLASS, mxREAL);
Output = (int*)mxGetData(plhs[0]);
omp_set_num_threads(6);
#pragma omp parallel
{
int ID = omp_get_thread_num();
Output[ID] = ID + 10;
}
}
Following your comments, I compiled this code with:
mexcuda -v CFLAGS="$CFLAGS -fopenmp" LDFLAGS="$LDFLAGS -fopenmp" OpenMPTest.cu
When i run this, the output should be "10 11 12 13 14 15" (or something like this in different orders), but I get 10 0 0 0 0 0. So, OpenMP is not working.
Following page 25 of this LINK (says: add "-Xcompiler -fopenmp" flag and -lgomp flag ), I see that I need to use (it mi)
mexcuda -v CFLAGS="$CFLAGS -Xcompiler -fopenmp" LDFLAGS="$LDFLAGS -Xcompiler -fopenmp" -lgomp OpenMPTest.cu
However, I get error for the -lgomp. Matlab cannot find it. I also looked into the Matlab/Mingw base folder, but could not something with such a name.
Could you please let me know what is it that I'm missing here? is the compile command wrong?
Moein.
Joss Knight
2021 年 9 月 21 日
I can't comment on exactly why nvcc might have trouble building host-side code with OpenMP syntax. You may be better off keeping your host-side code in a .c or .cpp file and putting your device-side code in a separate .cu file. That way, MEXCUDA will invoke gcc for the host code instead of nvcc.
回答 (1 件)
俊凯 王
2021 年 9 月 24 日
編集済み: 俊凯 王
2021 年 9 月 24 日
til now i can't find the corroect compile cmd to create a cu project with omp activited
but there are some other ways can handle this trouble,like me i just use omp to create binary tree in cpu,and i want to make this tree root(struct in C) accessible to cu project in matlab
in fact,use intptr_t which cast pointer into int, matlab can accept this int parameter ,next step,we use this int as a input for a matlab cu input parameter
all in all,pointer can be casted into a int parameter for matlab ,and matlab transfer this parameter to cu project , all the variable in CPP/C can sited as a pointer ,this method maybe useful
.cpp(mex64) pointer->int matlab int -> .cu(project) int->pointer
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
アジア太平洋地域
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)