View previous topic :: View next topic |
Author |
Message |
cluosh
Joined: 15 Mar 2013 Posts: 20
|
Posted: Fri Mar 15, 2013 11:10 pm Post subject: Memory problems while executing function from C++ DLL |
|
|
Good evening,
I noticed a problem occuring when executing a function from a C++ DLL. Using the function from the DLL works perfectly with FTN95. The function loads a 3D model from a STL-File and does several modification to this model, which means a lot of memory is needed when the 3D models get larger.
When the stack size of the Fortran program is exceeded, the program throws an exception and stops executing. When I set the stack size higher, it can compute bigger 3D models, but this is not an option for the final program.
My question is: Is there any way to call a C++ Function without getting all variables saved into the stack, or is there a possibility to make the stack bigger dynamically? |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sat Mar 16, 2013 12:03 am Post subject: |
|
|
Its not clear what you mean here.
You can save stack space in your Fortran program by adding the
SAVE declaration to each of your programs and subroutines. This cause local variables to be put in static memory.
Like this:
Code: |
subroutine xxxx
integer a, b, c
real x, y, z
save
! Do something
end subrouint
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Sat Mar 16, 2013 10:00 am Post subject: |
|
|
How do you set the stack size higher (a SLINK command?) and why is this not an option for release? |
|
Back to top |
|
 |
cluosh
Joined: 15 Mar 2013 Posts: 20
|
Posted: Sat Mar 16, 2013 2:47 pm Post subject: |
|
|
I'm not sure how to describe what I mean, lets just say the function I import from a DLL uses the whole stack memory. I set the stack memory higher with "STACK 104857600" for 100 MB, which is still too small. If I set it any higher the program won't execute because of lacking RAM(according to the program). It's not an option for release, cause all the RAM would be reserved when starting the program, means if there is not enough RAM left according to the program, it won't execute.
A 3D model file with 1 MB needs more than 100 MB stack size during processing and if the stack is too small the program stops executing, but if I call the same DLL function from a C++ program it works fine. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Sun Mar 17, 2013 7:08 am Post subject: |
|
|
My recommendation is that you should consider a programming alternative that does not use 100mb of stack. The use of the stack for such large amounts is always going to cause problems.
You could move temporary local variables from the stack by using ALLOCATE. This should be a more robust approach.
If the variables are not temporary or local, why are they on the stack ?
John |
|
Back to top |
|
 |
cluosh
Joined: 15 Mar 2013 Posts: 20
|
Posted: Sun Mar 17, 2013 5:22 pm Post subject: Re: |
|
|
JohnCampbell wrote: | If the variables are not temporary or local, why are they on the stack ?
John |
That's what I'm asking myself. Obviously all variables used in the C++ function from the DLL are considered temporary and therefore end up on the stack. Is there any way to tell FTN95 to not put variables of an external DLL function on the stack? |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Mon Mar 18, 2013 7:09 am Post subject: |
|
|
Do you know what is going onto the stack ?
I would have assumed they were temproary variables being created in the routine being called.
Another possibility is they could also be array sections being genetated by the calling routine.
You need to identify what is being put onto the stack and consider an alternative.
John |
|
Back to top |
|
 |
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Mon Mar 18, 2013 10:14 am Post subject: Re: Memory problems while executing function from C++ DLL |
|
|
cluosh wrote: | When I set the stack size higher, it can compute bigger 3D models, but this is not an option for the final program. |
Is the DLL routine recursive, or is it doing something as exotic as using alloca() to reserve space on stack?
If STL-file is in binary format, then you know the exact size of a model and could simply use malloc() to allocate a buffer for it. |
|
Back to top |
|
 |
cluosh
Joined: 15 Mar 2013 Posts: 20
|
Posted: Tue Mar 19, 2013 12:22 am Post subject: |
|
|
The DLL uses C++(new) instead of C(malloc) methods for reserving memory. Obviously variable memory reserved with "new" ends up on the stack when calling the function through Fortran. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Tue Mar 19, 2013 12:37 am Post subject: |
|
|
I'm not sure of your knowledge in this area, when you say "obviously". Is that definately the case or are you saying in must be ?
I would recommend that you identify what is the source of the 100mb.
C-Malloc and fortran-ALLOCATE do not use the stack, so if you can control this use you may be able to avoid the problem. I can confirm how to achieve this in Fortran, but I am not familiar with controlling this in C.
Is there any recursion involved ?
It should be a problem that can be solved.
John |
|
Back to top |
|
 |
cluosh
Joined: 15 Mar 2013 Posts: 20
|
Posted: Tue Mar 19, 2013 12:55 am Post subject: |
|
|
Yes I mean "must be". I can't prove the C++ memory allocation is done on the stack, but if malloc works this must be the case. I can't tell if there is any recursion involved for sure, but there probably is. I'm wondering tho if there is another way to solve the problem without having to use malloc, cause the whole library is huge and using C++ memory allocation, and it be quite an effort to rewrite everything to malloc. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Tue Mar 19, 2013 6:02 am Post subject: |
|
|
My understanding is that malloc derived arrays is not the problem, as these do not use the stack. I say this as in Fortran, ALLOCATE does not use the stack and I understand ALLOCATE is based on malloc.
Do you have access to the Fortran or C++ code to be able to modify either ?
Have you been able to identify where the 100 mb is coming from? You have not yet indicated you have identified the source of this 100 mb.
If you have, I'd be trying to specifically shift some of these arrays from the stack. Your options in Fortran are:
Transfer the local array definitions to allocatable and allocate these arrays. ( large local arrays are the main source of stack usage)
Alternatively if these arrays are being supplied, can you control their allocation elsewhere, such as using ALLOCATE or declaring them to be in COMMON or a MODULE; or using malloc if in C++.
Rather than try to fix the whole library, is there a single routine call that is generating this specific problem? If so can you change the program performance at this location.
I don't think I can help much more unless there is more information available.
John |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Tue Mar 19, 2013 7:31 am Post subject: Re: |
|
|
cluosh wrote: | The DLL uses C++(new) instead of C(malloc) methods for reserving memory. Obviously variable memory reserved with "new" ends up on the stack when calling the function through Fortran. |
No this isn't correct. How could the function in the DLL "know" it is being called from Fortran. It can't. In C++ new allocates variables on the heap, not the stack.
If new (and malloc) used the stack, then then there wouldn't be any way of deleting variables, other than in reverse order of creation, and C++ allows variables to be created and deleted in any order.
My guess is that you problem is one of getting the interface to the call wrong in Fortran. This could cause corruption and filling up of the stack after multiple calls. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
cluosh
Joined: 15 Mar 2013 Posts: 20
|
Posted: Tue Mar 19, 2013 5:46 pm Post subject: Re: |
|
|
JohnCampbell wrote: |
Do you have access to the Fortran or C++ code to be able to modify either ?
Have you been able to identify where the 100 mb is coming from? You have not yet indicated you have identified the source of this 100 mb.
|
Yes I have access to the Fortran and the C++ Code, but it's hard to identify the source of the 100 mb. And there isn't a single C++ function containing all the code needed, a huge part of all functions of the library is used.
davidb wrote: |
My guess is that you problem is one of getting the interface to the call wrong in Fortran. This could cause corruption and filling up of the stack after multiple calls.
|
Definition of the function in C++:
Code: | DLL_HEADER void MESHSTLDEFAULT(const char* filename, const char* meshname, int fineness, bool additional_parameters) |
Importing the function in Fortran:
Code: | c_external MESHSTLDEFAULT (STRING,STRING,VAL,VAL) |
Compiling with:
Code: | ftn95 adds_meshing.f95 /ref nglib.dll |
Linking with adding:
Code: | lo adds_meshing
lo nglib.dll |
to the linker script.
I've also tried to avoid including the DLL into the Fortran program, but writing an external C++ program and calling it with
Code: | i=START_PROCESS@('mesher.exe','m '//trim(filename)//' '//trim(meshname)//' 5 0') |
The program executes perfectly, but the Fortran program crashes afterwards with a "Floating point stack fault"-Exception. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Tue Mar 19, 2013 5:50 pm Post subject: |
|
|
What does DLL_HEADER expand to? |
|
Back to top |
|
 |
|