이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
Why OpenMP does not work in a CUDA code compiled in Matlab (as a MEX)?
조회 수: 6 (최근 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!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 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 (한국어)