Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to flush stdout in mixed FORTRAN/C-code?

1,161 views
Skip to first unread message

Arjan

unread,
Jul 16, 2013, 8:50:03 AM7/16/13
to
Hi!

I am trying to decipher what is happening inside a program of which I recently got the sources. The main program code is essentially FORTRAN (77..., refactorization to F90 is in progress), but the optimization routine that is called (ASA) is written in C. That C-code in its turn calls a user-defined cost-function, which is written in FORTRAN. The beast seems to run. I re-directed stdout to a log-file. The printf-statements in the C-code seem to be out of phase with the write-statements in the FORTRAN bits: texts from the printf-statements end up somewhere in the far end of the run-log, way after the two write-statements around the call to C-routine ASA, messages which now appear as if nothing happens in between. How can I make printf and write wait for one-another to finish? I know that FLUSH(6) can do something on the FORTRAN-side, but what to do on the C-side? Do C and FORTRAN know about one another's stdout? Should I follow a different route? Which?

Thanks!


Arjan

Wolfgang Kilian

unread,
Jul 16, 2013, 9:09:52 AM7/16/13
to
You should be able to call fflush() on stdout, either from C, or from a
C wrapper, or directly from Fortran. In the latter case, you probably
need the filehandle of stdout as a C_PTR.

As I understand it, the I/O subsystems of the Fortran and C runtime
libraries are buffered independently. But that may not be true on all
systems.

-- Wolfgang

--
E-mail: firstnameini...@domain.de
Domain: yahoo

Arjan

unread,
Jul 16, 2013, 11:55:40 AM7/16/13
to
> You should be able to call fflush() on stdout, either from C, or from a
> C wrapper, or directly from Fortran. In the latter case, you probably
> need the filehandle of stdout as a C_PTR.

Thanks for the suggestions!

My FORTRAN is fair, but my C is quite rusty... Therefore, I still have some questions. Flushing the C stdout from within FORTRAN seems preferable, since this will allow me to place that functionality on a location where I still know what happens ;-). Also: I would not have to tamper with the external-party C-code of ASA. I presume that in the FORTRAN subroutine that calls ASA, I would have to do insert the following statement before the call:

CALL FLUSH(6)

and after the call to the C-subroutine:

CALL FLUSH(MyCPointer)

That subroutine (or the module containing it) will probably need to have to

USE ISO_C_BINDING

Now how do I declare stdout of the C routines as a C_PTR in my FORTRAN subroutine? In the C code stdout is accessed via printf(), which does not specify any file-handle.


Arjan

Arjan

unread,
Jul 16, 2013, 12:24:41 PM7/16/13
to
Hi!

I composed some bits in an attempt to call fflush from within FORTRAN, see below. To have a multi-track process, I hereby fork 1 thread to you ;-))
Does the following bit make sense? Will it allow my to do:

CALL MyCFlushRoutine(CStdOutHandle)

and have that do the trick? I'm going to try that out now in my code. Comments/suggestions welcome in the mean time.

Arjan




MODULE LibFlushC
USE ISO_C_BINDING
IMPLICIT NONE
PRIVATE
PUBLIC :: MyCFlushRoutine,CStdOutHandle
TYPE(C_PTR) :: CStdOutHandle BIND(C,NAME='stdout')
!
INTERFACE

FUNCTION MyCFlushRoutine(MyFileHandle) BIND(C,NAME='fflush')
USE ISO_C_BINDING
IMPLICIT NONE
TYPE(C_PTR) :: MyCFlushRoutine,MyFileHandle
END FUNCTION MyCFlushRoutine

END INTERFACE
!
END MODULE LibFlushC

Richard Maine

unread,
Jul 16, 2013, 12:33:04 PM7/16/13
to
Arjan <arjan.v...@rivm.nl> wrote:

> ... How can I make printf and write
> wait for one-another to finish? I know that FLUSH(6) can do something on
> the FORTRAN-side, but what to do on the C-side? Do C and FORTRAN know
> about one another's stdout? Should I follow a different route? Which?

I generally prefer to avoid that kind of problem by doing all the output
for a single file from a single language or the other (usually Fortran
in most of my cases) instead of fighting with trying to coordinate
possibly separate buffers.

I have a small Fortran wrapper routine which does nothing other than
take a character argument and write that argument to the Fortran output
unit (almost always 6, but I do isolate that dependency elsewhere). I
have the C code call that wrapper routine whenever I want it to print
something. I was going to trot out a sample, but I failed to find it in
a quick glance at the first place I thought I should have one saved.

Yes, it does require making changes in the C code, but I don't end up
doing it a lot (apparently little enough to make it slightly hard for me
to find an example in my code readily at hand). If I recall correctly, I
tended to use something like sprintf in C to write to a string to be
passed to my wrapper routine.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

FX

unread,
Jul 16, 2013, 12:43:34 PM7/16/13
to
> Should I follow a different route? Which?

Either on the C or on the Fortran side (whichever is easier), just
redirect the output to a file. It's much easier to deal with, really.

--
FX

dpb

unread,
Jul 16, 2013, 1:04:33 PM7/16/13
to
At the top level but it loses the intent of having the code output
serialized to aid in determining what's going on inside...plus it may
well be there's other reasons it needs must be in sequence for anyone to
be able to make any sense out of it (at least in a reasonable amount of
effort to splice the pieces together again).

--



fj

unread,
Jul 16, 2013, 1:21:10 PM7/16/13
to
Usually, I flush on both sides systematically : fflush(stdout) in each C routine printing out something and FLUSH(6) on the Fortran side.

This works well with GCC (cc+gfortran) or Intel (ifort+icc) for instance.

Louis Krupp

unread,
Jul 16, 2013, 2:08:39 PM7/16/13
to
You get stdout when you #include <stdio.h>. I don't believe your
Fortran code would need a pointer to it.

Louis

Arjan

unread,
Jul 16, 2013, 2:19:07 PM7/16/13
to
> Usually, I flush on both sides systematically : fflush(stdout) in each C
> routine printing out something and FLUSH(6) on the Fortran side.


This was the easiest to do and it works...

The main reason why I want to share stdout between fortran and C (as opposed to have any subroutine write to its own dedicated file) is (as suggested in one of the reactions) to get an idea of what happens in this unknown code and in which order. Long subroutines with lots of GOTO's... The bunch of print-statements that is supposed to help me on the way needs to be in time-forward order, otherwise I have (at least) 1 puzzle too many! Thanks for helping me out!

Arjan

Louis Krupp

unread,
Jul 16, 2013, 4:14:58 PM7/16/13
to
If all else fails, you could have each write and printf put a
timestamp in the same (sortable) format at the beginning of each
output line. When you're all done, sort the output file, and you'll
have everything in chronological order.

Louis

FX

unread,
Jul 16, 2013, 4:55:01 PM7/16/13
to
> At the top level but it loses the intent of having the code output
> serialized to aid in determining what's going on inside...

Yeah... you're right. I forget because my own debug code usually
timestaps every line of output, so there can be no confusion.

--
FX

Arjan

unread,
Jul 17, 2013, 6:09:46 AM7/17/13
to
> If all else fails, you could have each write and printf put a
> timestamp in the same (sortable) format at the beginning of each
> output line. When you're all done, sort the output file, and you'll
> have everything in chronological order.



That's a smart one! I'll remember this for a next time! Thanks!

Arjan

Louis Krupp

unread,
Jul 17, 2013, 7:18:35 AM7/17/13
to
You're welcome. You'll notice that FX replied with the same idea, and
it sounds like he's had more extensive -- and more recent --
experience.

Louis

dpb

unread,
Jul 17, 2013, 11:16:57 AM7/17/13
to
That works for new stuff and is certainly a good way to write debug
code. It runs into problems if there's a lot of existing code and/or
there's other routine output that would also be mixed in there in that
to implement may need a significant amount of effort in practice;
particularly w/ legacy code that may not be all that clean...

But, certainly is worth doing for added stuff and new work...

--

Iuri Segtovich

unread,
Apr 30, 2017, 3:25:45 PM4/30/17
to
Hi, i think you should change
TYPE(C_PTR) :: CStdOutHandle BIND(C,NAME='stdout')
for
USE mfstdout
where
MODULE mfstdout
USE iso_c_binding
implicit none
type(c_ptr), BIND(c,NAME='stdout') :: fstdout
END MODULE

note that for binding the variable, the bind(c) statement appears before the ::
and note that my compiler (gfortran) said i should put them in a module (or common block), not right on the main program declarations.

I know it's been some good years since this question was asked but i had the same problem now, had trouble finding an answer and wanted to show the answer it in this post that had high relevance in my today's google search
0 new messages