Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
66 Views

Mixed Fortran and C++ allocation

Hello,

 

I would like to have a main program in c++ that calls a Fortran subroutine, and in that subroutine data is allocated and sent back to the c++ program.

This I do by allocating a pointer array and then returning C_LOC(pointer_array).

This works great. 

My c++ program does some operations on the passed array and then when I no longer need it, I want it to be freed. My question is, how do I then deallocate the data? Do I do this in the c++ code or do I do this inside the Fortran code?

I looked at the thread:

https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/807005

but that method doesn't seem to scale nicely if I want to call this subroutine many times to receive many different arrays. Is there some generic way to deallocate the data?

 

Thank you,

 

Elad

0 Kudos
7 Replies
Highlighted
66 Views

Perform the deallocations in the language where the allocations occur.

Fortran uses descriptors for array allocations for both pointer and non-pointer arrays. Should you allocate an array in Fortran and then attempt to deallocate in C, you will likely corrupt the heap .AND. where the descriptor itself was allocated, that memory would be leaked. .AND. you have these two additional potential issues:

1) should your Fortran code, after allocation of non-pointer array, obtain the C_LOC(array), then exit the scope of the array descriptor, the array would have been auto-deleted (assuming array not in the global context of a module)

2) Should your Fortran code use pointer array (as you indicate), and you exit the function with C_LOC(pointer_array), then sometime later, reenter some Fortran routine to use the pointer for processing, you may/will have issues if you do not reconstruct the pointer (as to what happens, this will depend on how you declare your dummy for that array).

RE: scaling issues

The underlying allocation is performed by the C Runtime Library. The majority of any scaling issues will be related to the critical section performed in the CRTL and not in the additional code Fortran manages for the descriptors. You may need to address the scaling issue by using thread-private pool based allocators. This includes performing the allocations on the C++ side using the TBB scalable allocator .OR. you writing your own thread-private code for allocations in Fortran.

Jim Dempsey

0 Kudos
Highlighted
66 Views

Thanks for the reply.

So there is no way to avoid some global array? I can't pass a the pointer from fortran to c++, then pass that pointer from c++ back to fortran and have fortran deallocate it?

 

Elad

0 Kudos
Highlighted
Black Belt Retired Employee
66 Views

You don't need a global array, but the requirement to do the deallocate in the language that did the allocate is real. The Fortran language now provides a way for a C (or C++) program to request deallocation of a Fortran pointer or allocatable, but this requires the use of what Fortran calls "C descriptors" and is probably more than what you want to get into at this time.

A simple approach is to write a C++ routine to which Fortran passes the C pointrer and the C++ routine does the free.

0 Kudos
Highlighted
Honored Contributor I
66 Views

steinberg, elad wrote:

.. My c++ program does some operations on the passed array and then when I no longer need it, I want it to be freed. My question is, how do I then deallocate the data? Do I do this in the c++ code or do I do this inside the Fortran code? ..

I looked at the thread:

https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/807005

but that method doesn't seem to scale nicely if I want to call this subroutine many times to receive many different arrays. Is there some generic way to deallocate the data?

@Elad,

Have you referred to this thread?  https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/697150

In it, take a look at the fully worked example in Quote #12 where you will notice the subroutine in Fortran (and which is called from C++) has a dummy argument with the ALLOCATABLE attribute.  When it's time to "free" the memory, the call to CFI_deallocate (see ISO_Fortran_binding.h) is invoked to achieve it effectively from the C++ side

Can you consider using the enhanced interoperability features in standard Fortran in your code?  These features are now supported in Intel Fortran compiler.

 

0 Kudos
Highlighted
66 Views

That looks great and exactly what I wanted, but unfortunately I need my code to compile both with the Intel and GNU compilers.

0 Kudos
Highlighted
Black Belt Retired Employee
66 Views

My understanding is that the current gfortran also supports this feature.

0 Kudos
Highlighted
66 Views

You are right, I upgraded my GNU compiler to version 9 and they have it there, thank you!

0 Kudos