Software Archive
Read-only legacy content
17061 Discussions

Offload code in MFC application

Gerco
Beginner
2,494 Views

Hi there!

I'm trying to offload some code to the Xeon Phi in my MFC application, however when I run the application and get to the offload command I get an 0xC0000005: Access violation reading location exception. The project is built with the Visual C++ compiler and I use the Intel C++ compiler for the file that has the offload code. If I do the exact same thing in a win32 console application everything works fine. 

I have also tried creating a static library with the Offload code in a separate project with the Intel C++ compiler and linking that to my MFC project, this gave the exact same result: also the access violation exception. The same issue with a DLL instead of the static library. 

I couldn't find any info if it is even possible to use the Xeon Phi in combination with MFC, does anyone know if and how this can be done?

The project properties are a standard MFC project with the following changes:

- C/C++>Language>Run Time Type Information> NO (/GR-)

- C/C++>General>Additional Include Directories> $(WindowsSDK_IncludePath)

If I run this application on the actual machine with the Xeon Phi it results in a BSOD with WHEA_UNCORRECTABLE_ERROR.

I have attached a very basic MFC project that gives me the exception too. It tries to call the following function and the exception occurs as soon as the offload target command is used. How ever if I use the same function in an win32 console project everything works fine.

#include "Offload.h"
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int GetNumProcs()
{
	int totalProcs = 0;
#pragma offload target(mic)
	{
		totalProcs = omp_get_num_procs();
	}
	printf("Num procs = %d", totalProcs);
	return totalProcs;
}

Any help is greatly appreciated!

Gerco

0 Kudos
17 Replies
SergeyKostrov
Valued Contributor II
2,494 Views
>>...I'm trying to offload some code to the Xeon Phi in my MFC application, however when I run the application and get to the offload >>command I get an 0xC0000005: Access violation reading location exception... More technical details are needed. Also, If you will be able to create a simple reproducer then it would help. I'm not sure that it could be related to your problem but do you have call to AFX_MANAGE_STATE( ... ) in your MFC application?
0 Kudos
Gerco
Beginner
2,494 Views

Hi Sergey,

Thanks for the quick response. I have attached a simple MFC project that calls a test function that uses the offload pragma. The GetNumProcs() function works fine if called from a win32 project but it gives the access violation exception in the MFC project.

I don't do any calls on AFX_MANAGE_STATE(...) but maybe one of the MFC classes does this?

If you need anymore details please let me know.

Gerco

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,494 Views

Dear (name withheld),

Would you please edit your profile to enable sharing your name. Note, if you wish, you can use an alias (pick one you can live with).

My KNC system is currently setup to run Linux, so I cannot test. When it was, the following would work for me on

C# (managed) -> C++ DLL (managed) -> Fortran DLL (unmanaged) -> offload -> Fortran .so on KNC (2)

What you may need to do is to take your Offload.cpp and place it into a new project that produces an unmanaged DLL.

Note, for debugging, there is (I found) a quirk and work around. The quirk was, after an edit session, the debugger could not directly place a breakpoint into the unmanaged code from the IDE until after I (you) stepped into the code. Only then would the debugger know the application was a mixture of managed and unmanaged code. I added a little "Here_I_am" function that did nothing but increment a static variable and return. I placed a call to this in the managed program at/near startup. Then for debugging the unmanaged code, place a break at the function call and then step into the locator. The first time you do this the debugger may ask if the code is unmanaged and where the source folder is located. You may also need to look at the properties of your managed code project in the Debug property pages. I seem to recall there is a check box to indicate if the debugger will be debugging managed/unmanaged code.

I hope this gets you going.

Jim Dempsey

0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views

Could you try this:

...
int GetNumProcs()
{
       AFX_MANAGE_STATE( _afxModuleAddrThis );

       int totalProcs = 0;
       #pragma offload target(mic)
       {
              totalProcs = omp_get_num_procs();
       }
       printf("Num procs = %d", totalProcs);
       return totalProcs;
}
...

Also, run Debug configuration step-by step and take a look in an Output Window for a last DLL loaded, any errors, or exceptions. I'd like to see a full output from the Output Window when the crash happens.

 

0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views
>>I don't do any calls on AFX_MANAGE_STATE(...) but maybe one of the MFC classes does this? No. It needs to be done explicitly by a developer. I'm still not sure it would fix the problem but since I have a significant experience with MFC programming an AFX state managing was a first thing to consider.
0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views
Consider to comment all these UI related calls, like: ... m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; ... ... // InitCommonControlsEx() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // Set this to include all the common control classes you want to use // in your application. InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); ... ... // Create the shell manager, in case the dialog contains // any shell tree view or shell list view controls. CShellManager *pShellManager = new CShellManager; // Activate "Windows Native" visual manager for enabling themes in MFC controls CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); ... ... // Delete the shell manager created above. if (pShellManager != NULL) { delete pShellManager; } ... These pieces I would comment during investigation. Also, did you try to press on a button when a call to GetNumProcs is commented out? Does the application work? Is there a crash?
0 Kudos
JWong19
Beginner
2,494 Views

Sorry that I don't have a MIC to reproduce your problem.

Please show which instruction your program crashed at. I suppose that you are using Visual Studio because you write MFC codes. Configure your IDE (Debug --> Exception --> Win32 Exception --> tick the corresponding Thrown' check box) so that your program stops at the problem instruction.

Show the screen of disassembly including nearby instructions / source codes. In addition, show the call stack to locate which modules (right click the call stack window --> check to display module name) are involved.

0 Kudos
Gerco
Beginner
2,494 Views

I have been trying all of the suggestions but if I want to call AFX_MANAGE_STATE I have to include afx.h in Offload.cpp which gives me the following compilation error: Offload.cpp(7): error : *MIC* cannot open source file "afx.h"

I have attached the full build output.

I have also attached the full output window when the crash happens. The breakpoint is triggered in the CWinApp deconstructor. I have also attached a screenshot of the breakpoint and the top of the call stack at that moment.

And yes, if I comment out the call to GetNumProcs the application works fine. If I comment out just the line with the #pragma offload it also works. I tried the offload pragma with just empty brackets under it, that also produces the crash.

Gerco

0 Kudos
JWong19
Beginner
2,494 Views

From your call stack, your program crashed at the destructor of the CWinApp object. 'liboffload!doexit' was called by 'liboffload!__offload_target_acquire' which was called at line 14 of your GetNumProcs function.

Please check whether 'omp_get_num_procs()' had been called before call to the function '__offload_target_acquire'

My best guess is to use the OFFLOAD_INIT=on_start environment variable. Otherwise add your #pragma offload directive to the beginning of the WinMain function......

0 Kudos
Gerco
Beginner
2,494 Views

The crash also happens without the omp_get_num_procs() function call.

Also I don't think OFFLOAD_INIT=on_start is going to help because I'm currently not testing on a machine with the coprocessor. Because I get the exact same exception on my laptop I use to develop.

I can't add #pragma offload to the beginning of the program since that is MFC code that is being compiled with VC++.

0 Kudos
JWong19
Beginner
2,494 Views

Gerco N. wrote:

I can't add #pragma offload to the beginning of the program since that is MFC code that is being compiled with VC++.

Run with Debug build then copy the contents of 'WinMain' to your own source file...... Then set the entry function to your own 'WinMain'......

0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views
Jeremy, >>...Run with Debug build then copy the contents of 'WinMain' to your own source file This is an MFC application (!) and it doesn't have explicit call, or declaration, of WinMain! It is "buried" in MFC low level methods and Afx-functions. A break point on InitInstance needs to be set instead. Here is an example of how it is declared: ... class CTmplDlgApp : public CWinApp { public: CTmplDlgApp( RTvoid ); virtual ~CTmplDlgApp( RTvoid ); public: //{{AFX_VIRTUAL( CTmplDlgApp ) virtual RTBOOL InitInstance( RTvoid ); //}}AFX_VIRTUAL protected: //{{AFX_MSG( CTmplDlgApp ) //}}AFX_MSG DECLARE_MESSAGE_MAP(); public: }; ...
0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views
>>OutputWindow.PNG An exception was thrown from MFC110ud.DLL and I would suggest to add try-catch block(s) for CWinApp::~CWinApp and CWinApp::ExitInstance ( you need to add it ) methods. It could look like: ... ...CWinApp::ExitInstance( ... ) { try { ... ...all clean ups... ... } catch( ... ) { AfxMessage( "An exception is intercepted" ); // Needs to be commented out for Release configuration } } ...
0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views
Gerco, Consider these actions: - Try to review why there is a Memory Leak at strcore.cpp file( line 156 ) and a 98-byte memory block was not released. Set a break point on that line and then Re-start debugging session. - Try to add ExitInstance method and clear MIC resources ( if any... ) inside of it - I've uploaded a template for MFC Dialog based application created with a legacy Visual Studio 2005 and try to use it. Some little corrections could be needed. I could also create a very minimal MFC Dialog based project with Visual C++ 6.0 and it could help you to understand if this is an UI related problem ( recently introduced by Microsoft's new UI elements, classes, Afx-functions ) or if this is a bug with Intel runtime libraries. Note: A new zip file with a project uploaded. See newer posts.
0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views
>>...I could also create a very minimal MFC Dialog based project with Visual C++ 6.0 and it could help you to understand if this is an UI >>related problem... Here it is and try to use it. I've deleted a previously uploaded zip file because it would require too many modifications. A new one is a very clean without any modifications / updates after it was created by an MFC Wizard using Visual C++ 6.0
0 Kudos
SergeyKostrov
Valued Contributor II
2,494 Views
>>...If I do the exact same thing in a win32 console application everything works fine Gerco, Try to understand if this is an UI related problem recently introduced by Microsoft's new UI elements, classes, Afx-functions.
0 Kudos
JWong19
Beginner
2,494 Views

Gerco N. wrote:

The crash also happens without the omp_get_num_procs() function call.

Also I don't think OFFLOAD_INIT=on_start is going to help because I'm currently not testing on a machine with the coprocessor. Because I get the exact same exception on my laptop I use to develop.

I can't add #pragma offload to the beginning of the program since that is MFC code that is being compiled with VC++.

Any update of the problem?

To clarify uncertainty, you need to show where 'liboffload!__offload_target_acquire()' was called at line 14 of your 'GetNumProcs' file. When your IDE catch the access violation exception, double click the 'GetNumProcs' stack frame in the call stack window. Then you'll be at line 14 of the 'GetNumProcs' file. Right click on the source file window and choose 'disassembly' to open the disassembly window. You'll see where the '__offload_target_acquire()' function was called. Finally capture the screen and show it here.

0 Kudos
Reply