LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Shared memory between Fortran & C++ applications (https://www.linuxquestions.org/questions/programming-9/shared-memory-between-fortran-and-c-applications-806541/)

mbrose1994 05-07-2010 02:11 PM

Shared memory between Fortran & C++ applications
 
I have to figure out how to pass data between a Fortran application and a C++ application. The memory has to be locked/unlocked to prevent data corruption. I know very little about Fortran. I have done mutex lock/unlock stuff in Linux apps, multi-threaded, using mutex locks before.

Digging around on the Web, I do not find any info on a Fortran app including linux headers, library calls such as those in ipc.h, shm.h and sem.h.

What is an approach to this problem?

-thanks, Michael

SaintDanBert 05-07-2010 04:44 PM

Can you provide some more information? Are both programs running at the same time in cooperation, or do they run sequentially?

In the latter case, simply use STDOUT and STDIN.
Code:

myCprog | myFprog
Whatever myCprog writes to STDOUT, is available as input to myFprog on STDIN.

If both programs run at the same time, consider using a named pipe. There are library routines to create and destroy the pipe. You then use fopen() fwrite() fread() and fclose() -- and their fortran equivalents OPEN( ), WRITE( ), READ( ) and CLOSE( ) -- to move the data.

Cheers,
~~~ 0;-Dan

SaintDanBert 05-07-2010 05:55 PM

Take a look at this

http://www.cct.lsu.edu/~kosar/csc430...munication.pdf

Fortran can make calls to C or C++ library routines, but there is a dance required because the two languages use different calling conventions. It has been some time since I've done Fortran on linux
so I bet the usual suspect routines are available as fortran variants by now.

In a previous life (circa 1995) I built an industrial instrument using linux as a real-time-OS doing xray florescence. Most of the information processing was industry standard fortran code so we had all sorts of C and C++ talking with Fortran in all sorts of ways.
We had a work flow that was a series of steps so we could use traditional command line pipes with STDOUT and STDIN. We could then use simple redirection to write then read a temporary file for intermediate results and debugging. We could also tee to send the data multiple places. I'll help where I can, but my Fortran is very rusty (grinning).


Good luck,
~~~ 0;-Dan

~~~ 0;-Dan

jiml8 05-08-2010 04:35 AM

If you use a BLOCK DATA statement in Fortran, then reference the block data with an extern statement from C, you should be able to pick up the same piece of memory that represents the BLOCK DATA.

For example, in Fortran you would say:

BLOCK DATA FOO
COMMON /MYDATA/X,Y,Z
DATA X, Y, Z/ 1., 2., 3./
END

Then in C you would specify:

extern FOO

and the linker *should* pick it up.

You might also take advantage of the differences in calling conventions between Fortran and C functions.

By default, Fortran passes arguments by reference, while C passes by value.

So you might, for instance do this in fortran:

CHAR*1 MYDATA(256)
CALL MYFUNC(MYDATA)

then in C:

void MYFUNC(char *mydata) {

}

And to go the other way:

C:
char mydata[256];
MYFORFUNC(&mydata)

Fortran:
FUNCTION MYFORFUNC(MYDATA)
END

or

SUBROUTINE MYFORFUNC(MYDATA)
END

Of course, with any fortran since F77, you can use lowercase without any trouble. In fact, if you use F90 or later, you can use pointers explicitly.

If your apps are indeed separate and you are using IPC mechanisms, then you can conveniently get to the IPC interfaces in Linux by writing C subroutines that are called from Fortran as I show here, and use those C subroutines to handle the IPC. This has a minimal impact on your fortran app, but enables the functionality you need without the circumlocutions you'd encounter if you try to set up all the IPC stuff (and all the data structures) in fortran, though you certainly COULD do that.

I would use C rather than C++ for linking with Fortran because the conventions of C are simpler and you'll have a lot less trouble debugging your linking. I think that if I wanted to link C++ with Fortran, I would go through C stubs to do that.

mbrose1994 05-10-2010 12:41 PM

Thank you SaintDanBert and jiml8 for your replies.

Yes to running 2 separate apps concurrently on the linux OS (2.6.18, RED HAT Enterprise 5). I have timing requirements such that STDIN, STDOUT, file open and closes can't be utilized.

Basically, I have to accomplish what two separate C/C++ apps could do, namely access shared memory using mutex locks/unlocks to keep data handling clean. The Fortran app is necessary as it does the heavy number crunching. The C/C++ program handles other IO to the outside world.

From your replies, looks like I only need a C program. C++ is not offering any real benefits in this implementation.

Instead of figuring out how to add mutex locks, I have a decent timer loop running now that provides good enough millisecond slices. So I could maybe divide and conquer memory independent reads/writes using the timer.

Sound reasonable or feasible?

SaintDanBert 05-10-2010 01:26 PM

Quote:

Originally Posted by mbrose1994 (Post 3963559)
Thank you SaintDanBert and jiml8 for your replies.
...
Instead of figuring out how to add mutex locks, I have a decent timer loop running now that provides good enough millisecond slices. So I could maybe divide and conquer memory independent reads/writes using the timer.

If you have two completely independent processes with read-write access to the same set of variables, you need some sort of locking mechanism. I've done them in C and C++ and Fortran several times.
My experience is dusty and rusty so others might have stronger ideas.
There are several descriptions of how to do this implementation online. There are even features built-in with linux but they might be overkill.

One word of caution. Make arrangements for dealing with a "deadly embrace" dead lock ... one where both processes are waiting for the other and neither can act. In the past, I've had a third process serve as watch dog and application notifier.
If it sees that lock set for two long, it complains. That way you know something is happening.

Cheers,
~~~ 0;-Dan

SaintDanBert 05-10-2010 01:33 PM

Quote:

Originally Posted by mbrose1994 (Post 3963559)
Thank you SaintDanBert and jiml8 for your replies.
...
Basically, I have to accomplish what two separate C/C++ apps could do, namely access shared memory using mutex locks/unlocks to keep data handling clean. The Fortran app is necessary as it does the heavy number crunching. The C/C++ program handles other IO to the outside world.
...

When I did this for industrial instruments, I chose a "work order" model. The front-end collected data and parameters and details then
prepared a work-order data packet (a struct in C) with a unique task-ID and the data and details. We wrote this data packet to a queue of things to do. The back-end (fortran) had access to the queue. When a task became available, the back-end would turn its crank
and update the work order packet.

Sounds like fun,
~~~ 0;-Dan

jiml8 05-10-2010 04:03 PM

Timing loops are usually a bad idea. They make far too many assumptions about the environment, and things break quickly when any of those assumptions are violated.

If you want to share memory, and state is at all important, you HAVE to use mutexes.

mbrose1994 05-10-2010 05:42 PM

Quote:

Originally Posted by jiml8 (Post 3963795)
Timing loops are usually a bad idea. They make far too many assumptions about the environment, and things break quickly when any of those assumptions are violated.

If you want to share memory, and state is at all important, you HAVE to use mutexes.

Well, yes, I am starting to see that pretty clearly now. Digging around on the web, looks like I should design this so that the Fortran app uses all C app function calls for mutex locking, unlocking, shared memory reads and writes.

What I have not confirmed is that the Fortran app can "include" a C style header file (file.h) to define the shared memory structure(s). I have seen a Fortran <==> C variables mapping chart so I can define the shared memory so Fortran is happy.

Any gotcha's or over-looks jumping out in the design just described?

jiml8 05-10-2010 10:23 PM

You can include files in fortran. They are not the .h file format, though, because that format is C format. You would have to build your own fortran includes.

I'm not quite sure how g77 will handle the includes; there are substantial differences between compilers. Might be the includes have to be in the same directory as the executable.

Valery Reznic 05-11-2010 03:10 AM

Quote:

Originally Posted by mbrose1994 (Post 3963895)
Well, yes, I am starting to see that pretty clearly now. Digging around on the web, looks like I should design this so that the Fortran app uses all C app function calls for mutex locking, unlocking, shared memory reads and writes.

If you have to call C functions from Fortran, then why do you need separate C program, with all those looking and shared memory issues ?

Can't you call from Fortran C functions that will do what your second program now supposed to do ?

SaintDanBert 05-11-2010 10:55 AM

Quote:

Originally Posted by Valery Reznic (Post 3964349)
If you have to call C functions from Fortran, then why do you need separate C program, with all those looking and shared memory issues ?

Can't you call from Fortran C functions that will do what your second program now supposed to do ?

One can always create a larger and larger program. But then maintenance and effectiveness typically suffer. I salute the desire to have one process that is really good at gathering and packaging data and a second process that is really good a processing that data.

I've done it [years ago] so I know that there is a way. Once can share Fortran common blocks -- either blank or named -- with C programs. As I recall, named common just lined up as a C struct.
The wrinkles happened due to the different ways that fortran packages data (especially character data) into variables.

I do have a request from the OP and this thread. If someone knows of a reasonable mutex library suitable to drop into applications like this, please post a web link to this thread.

Cheers,
~~~ 0;-Dan

Valery Reznic 05-11-2010 02:13 PM

Quote:

Originally Posted by SaintDanBert (Post 3964657)
One can always create a larger and larger program. But then maintenance and effectiveness typically suffer. I salute the desire to have one process that is really good at gathering and packaging data and a second process that is really good a processing that data.

I've done it [years ago] so I know that there is a way. Once can share Fortran common blocks -- either blank or named -- with C programs. As I recall, named common just lined up as a C struct.
The wrinkles happened due to the different ways that fortran packages data (especially character data) into variables.

I do have a request from the OP and this thread. If someone knows of a reasonable mutex library suitable to drop into applications like this, please post a web link to this thread.

Cheers,
~~~ 0;-Dan

Let's take another direction - each program can be split. And each of resulting programs can be split too... Decision to make separate programs or combine their functionality into one depends on many factors (including personal taste). I have no information about problem at hand to recommend one way or another. I just pointed out that "combine" way exist too.

Another note - Fortran's common blocks can't be shared with C program.
Those common block CAN BE shared with C functions inside same fortran + C program, but not with external C program. Tod this you need usual Operation systems IPC

jiml8 05-11-2010 02:40 PM

Correct. Common can't be shared between processes (though I do believe it could be shared among threads).

mbrose1994 05-12-2010 11:06 AM

Quote:

Originally Posted by Valery Reznic (Post 3964349)
If you have to call C functions from Fortran, then why do you need separate C program, with all those looking and shared memory issues ?

Can't you call from Fortran C functions that will do what your second program now supposed to do ?

A good question and the answer is:

The C program's job, or C++ if I can do that, is handling IP IO. It is a client that gets/reads (recv()) command data and must write this data into a memory structure the Fortran app can read from. After the Fortran app processes the data, a response must be sent back. So the Fortran app must then write to a memory structure. To complete the data cycle the C/C++ app then must read the response data and send the response data out.

I believe it is a better design to keep the Fortran app focused on data processing and the C/C++ app on the IP socket IO processing. I am assuming, but need to confirm, that it is efficient and clean for the C/C++ app to provide mutex functions, memory reads and memory writes to the Fortran app.

Maybe that means the Fortran app does not need any direct access to the memory? As in no shared memory at all? I could have the memory exist exclusively in my C++ app and simply provide read/write access via functions to the Fortran app?

But is that laying expensive/in-efficient overhead into the Fortran app?

Thinking out loud now, your replies are much appreciated.


All times are GMT -5. The time now is 11:45 PM.