2

In C I can use the standard function freopen with stdout to redirect the standard output of my program to a file. I would like to do the same with fortran, but after having googled I couldn't find a similar feature. Does it exist?

In case somebody wonder what my use case is, and why I cannot just redirect the output using the shell, I'm running an MPI program and need to redirect the output of each instance to a different file. I cannot do this from outside the program since the MPI implementation we have does not allow doing so.


EDIT: A related question is the following. Say that the fortran code calls a C function, and this C function calls freopen of stdout to a different file. What happens to the subsequent write(*,*), print * and write(6,*) in fortran? Is the output of these redirected to the file or not?

Spiros
  • 2,156
  • 2
  • 23
  • 42
  • 1
    As to the question you added -- what did you find out when you tried this ? – High Performance Mark Sep 23 '14 at 05:29
  • Well, what I found out is quite irrelevant, since I need portability and portability is ensured by the standards. I'd probably need to know how are file descriptors treated according the fortan standard, but I'm not sure what the implications could be. However, you deserve an answer... Yes, it worked. All subsequent output was redirected to the file as expected. – Spiros Sep 23 '14 at 07:58

1 Answers1

2

If you had the foresight to write all your write statements along the lines of

write(write_unit,*) stuff_to_write

it would be very simple, you could simply attach write_unit to a file instead of stdout. I guess you knew that already or you wouldn't be asking the question. If your write statements are of the form

write(*,*) 

or

print *

then you can probably redirect output with a little help from your compiler. Intel Fortran, for example, sends output directed to * to the console, unless the program finds itself executing in an environment with the variable FOR_PRINT set to the name of some file or other, in which case write(*,*) will write to that file. I expect other compilers have similar capability.

If your code uses

write(6,*)

on the expectation that unit 6 points at stdout you can open unit 6 on a file

open(unit = 6, file = 'stdout_redirect', status = 'new')

For any more you'd better tell us what your write statements look like and what compiler you're using.

EDIT

after OP's edit to question. This is more of a comment than an answer but I'm quite long-winded ...

Sadly, from the portability point of view, much of a Fortran program's interaction with the underlying computer system is not defined in the standards. Your question of where does output sent to unit * go is a case in point; the latest (2008) standard says that it must go to the same unit as identified by the named constant output_unit from the intrinsic module iso_fortran_env. But it does not say that it goes to stdout (there have been plenty of Fortran implementations on systems without a stdout) and it does not specify how to redirect that output, or even if it is possible to do so. Redirection of output is a matter for the platform, not Fortran. As we've discovered Intel Fortran can use an environment variable to redirect output, apparently Cray Fortran can't.

The latest standard is entirely silent on the topic of file descriptors, I'm not sure it's a concept known to Fortran.

Using * for i/o is essentially saying that it is up to the compiler / run-time system where input comes from and output goes to. If you want portability you have to take control and use specific unit identification. Personally I think you should take @george's advice in the comment below.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
  • 2
    If you did not have the foresight to use a variable for the unit number, bite the bullet and go back and fix it. Anything else is asking for trouble under mpi. – agentp Sep 22 '14 at 17:52
  • Well, quite @george. And thanks for making explicit something I'd not thought to make explicit. – High Performance Mark Sep 22 '14 at 17:54
  • Many thanks for your hints. The codebase I'm working with is quite big (in the order of 50k lines) and very heterogeneous in terms of style and practices. There is no general agreement on how to print things, mostly because only diagnostic messages are printed to stdout (and diagnostic messages are considered of little relevance). I see your solutions and think that none of them is really suitable for my case, the reason being that there is no standard way of doing this. The compilers I'm targeting are GCC and Cray. – Spiros Sep 22 '14 at 23:36
  • 1
    50 kloc is not THAT large. Roughly the size of my PhD project. When porting to MPI it took me just about 2 hours with search and replace to add sone if statements to every `write(*,` with some variations. Just roll roll your sleeves and use a good text editor. – Vladimir F Героям слава Sep 23 '14 at 05:49
  • Final comment before going too much out-of topic: can you share some resources about the fortran standards? I did not found much out there. The next question would be what happens if I try to use open with the unit ID output_unit. But I am most willing to find this out myself. – Spiros Sep 23 '14 at 12:28
  • The published standards are available, at a cost, from the ISO store (http://www.iso.org/iso/home/store.htm) or from a local agent in your country. If you are unwilling or unable to pay for the standards you might find drafts useful, these are freely available from NAG (http://www.nag.co.uk/sc22wg5/links.html). – High Performance Mark Sep 23 '14 at 12:52