Discussion:
Fortran Users! Is there a better way to do this?
Ron Hudson
2010-05-15 20:20:26 UTC
Permalink
Hey fellow fortran users..

I have a program that produces a long list of numbers calculated one after
the other.
I want to print these numbers 5 wide to save 'paper'

What I am doing now:

an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...

Is there a better way?

Ron
Dave Wade
2010-05-15 20:59:19 UTC
Permalink
Rod,

From what I remember Fortran i/o is expensive so your solution is probably
more efficient than the alternative which would be to use the "+" format
control to allow multiple prints to occupy the same line.

Dave
G4UGM
Illegitimi Non Carborundum

-----Original Message-----
From: turnkey-mvs-***@public.gmane.org [mailto:turnkey-mvs-***@public.gmane.org] On
Behalf Of Ron Hudson
Sent: 15 May 2010 21:20
To: turnkey-mvs-***@public.gmane.org
Subject: [turnkey-mvs] Fortran Users! Is there a better way to do this?




Hey fellow fortran users..

I have a program that produces a long list of numbers calculated one after
the other.
I want to print these numbers 5 wide to save 'paper'

What I am doing now:

an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...

Is there a better way?

Ron
Ron Hudson
2010-05-15 21:27:45 UTC
Permalink
I had thoguht of that approach, but I would need six different writes and
six different format statements
and a counter to control which one to use right? (one to advance to the
next line and 5 to print each column)
Post by Dave Wade
Rod,
From what I remember Fortran i/o is expensive so your solution is probably
more efficient than the alternative which would be to use the "+" format
control to allow multiple prints to occupy the same line.
Dave
G4UGM
*Illegitimi Non Carborundum*
-----Original Message-----
Behalf Of *Ron Hudson
*Sent:* 15 May 2010 21:20
*Subject:* [turnkey-mvs] Fortran Users! Is there a better way to do this?
Hey fellow fortran users..
I have a program that produces a long list of numbers calculated one after
the other.
I want to print these numbers 5 wide to save 'paper'
an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...
Is there a better way?
Ron
Jeff Sumner
2010-05-16 01:55:40 UTC
Permalink
How about a simple output to dataset instead of "paper?" That's pretty easy to do for FortranG/H. You avoid the spooler... If that buys anything.

Remember that in TSO, the printed output is all thrown into the spool and isn't dumped until the job ends (typically).

J
Rod,
From what I remember Fortran i/o is expensive so your solution is probably more efficient than the alternative which would be to use the "+" format control to allow multiple prints to occupy the same line.
Dave
G4UGM
Illegitimi Non Carborundum
-----Original Message-----
Sent: 15 May 2010 21:20
Subject: [turnkey-mvs] Fortran Users! Is there a better way to do this?
Hey fellow fortran users..
I have a program that produces a long list of numbers calculated one after the other.
I want to print these numbers 5 wide to save 'paper'
an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...
Is there a better way?
Ron
Gerhard Postpischil
2010-05-15 21:25:58 UTC
Permalink
Post by Ron Hudson
an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...
Is there a better way?
About the only thing that would be (slightly) more efficient
would be to use a single array large enough for all values, then
use a single WRITE at the end. That supposes you have enough
storage available to keep all values. If not, use an
intermediate array size that's a multiple of 5.

Gerhard Postpischil
Bradford, VT
Ron Hudson
2010-05-15 21:32:29 UTC
Permalink
On Sat, May 15, 2010 at 2:25 PM, Gerhard Postpischil
Post by Gerhard Postpischil
Post by Ron Hudson
an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...
Is there a better way?
About the only thing that would be (slightly) more efficient
would be to use a single array large enough for all values, then
use a single WRITE at the end. That supposes you have enough
storage available to keep all values. If not, use an
intermediate array size that's a multiple of 5.
Like perhaps a pages worth?
Post by Gerhard Postpischil
Gerhard Postpischil
Bradford, VT
Gerhard Postpischil
2010-05-15 22:18:47 UTC
Permalink
Post by Ron Hudson
Like perhaps a pages worth?
There's nothing really special about a page when it comes to
performance. On a really large job, what could affect
performance is writing a block that just fits your JES2 buffer
size (your program writes to an unprotected buffer, and when
that's full, JES2 transfers it to a protected buffer and writes
to the spool); doing so slightly reduces your system overhead.

Gerhard Postpischil
Bradford, VT
Tuomo Stauffer
2010-05-16 02:20:19 UTC
Permalink
A long time since I used Fortran - besides which level you are using?

Anyway - why not put the whole thing in format clause? Let the compiler do
what it does best?

That was and still is one of the power of Fortran almost no other language
shares, maybe PL/I but that's it. A format clause is optimized and executed
as one - no real looping. Great especially in machines which had some vector
processing capability - C and ilk are still far, far behind that, the
libraries are getting better but..

Also, if used in "toy" MVS, I have no idea how the compiler behaves, how JES
buffers, etc - but in "real" MVS/JES I had an exit which buffered the output
so writing one element, a row or even a page at a time didn't make much
difference.

just some, probably bad, idea? have a nice day - tuomo
Post by Ron Hudson
Hey fellow fortran users..
I have a program that produces a long list of numbers calculated one after
the other.
I want to print these numbers 5 wide to save 'paper'
an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...
Is there a better way?
Ron
Gary Lee Phillips
2010-05-16 13:07:27 UTC
Permalink
Hi Ron. While it's true that formatted I/O in Fortran has a higher
processing cost than in some other languages, it's no worse than the
stream I/O native to languages like C and BASIC when they were brought
to the mainframe world.

Certainly when working with a Hercules environment, you probably don't
need to worry much about this, as the differences are very slight in
the overall picture. Even in a real mainframe, we normally used
Fortran for tasks that were compute intensive, with lots of math and
only a little output. Things like statistics or numerical integration
were done (and still are) in Fortran.

If you really want to dig into this issue, you can try running several
versions of your code with different I/O algorithms. Make sure you
have enough data so that the program doesn't just complete in a
fraction of a second. Then you can look at the step analytics that
print out in the job log after the JCL. Compare the different methods
and see what does best.

Your coding approach seems about as good as any to me. However, you
can try other choices. In the G and H compilers, you can use "grouped"
formats. These let you nest format specifications in parenthetical
groups that are repeated, to produce output that is formatted over
several lines or even pages with just one FORMAT statement. There are
restrictions on the depth of nesting, but I know you can get down to
at least two levels of parentheses, with various repeats on each
group.

If I remember correctly, the "cost" of formatted I/O is connected not
with the amount of data, but with the number of times you issue a
WRITE or READ. So grouping data and performing a single output for
multiple values is a good approach.

Another approach would be to use unformatted I/O, and write your
values out to a temporary file. Read that file back in with another
language that does more efficient I/O and do your printing at that
time. So Fortran does the calculations and writes the numbers to a
tape or temp file, which you pass to a second step written in COBOL or
PL/I that formats the report.

The description of grouped format statements is in the original IBM
OS/360 Fortran manuals, along with much detailed discussion of I/O
options and costs. Have a look here:

http://bitsavers.org/pdf/ibm/360/fortran/

I have some additional manuals from the era, but when I tried to
submit copies, they seemed to think it was "duplicate" data or
something. In general, start with the programmer's guides (PG) for
this sort of thing. If you're really after fine tuning, the H compiler
is capable of optimizing some elements for you. Note that neither G
nor H is anything like the current Fortran standards, though. Those
who use Fortran regularly on modern equipment are almost certainly
using compilers built to the Fortran-90 or Fortran-95 standards, which
are light years beyond the Fortran IV represented by the OS/360
software.

--Gary
John R. Macdonald
2010-05-16 17:39:20 UTC
Permalink
-----Original Message-----
From: turnkey-mvs-***@public.gmane.org [mailto:turnkey-mvs-***@public.gmane.org] On
Behalf Of Gary Lee Phillips
Sent: dimanche 16 mai 2010 15:07
To: turnkey-mvs-***@public.gmane.org
Subject: [turnkey-mvs] Re: Fortran Users! Is there a better way to do this?




Hi Ron.

------ snip ----

Another approach would be to use unformatted I/O, and write your
values out to a temporary file. Read that file back in with another
language that does more efficient I/O and do your printing at that
time. So Fortran does the calculations and writes the numbers to a
tape or temp file, which you pass to a second step written in COBOL or
PL/I that formats the report.

---- snip ----
--Gary



Many many moons ago (circa 1968-69 IIRC) I worked with a contractor who
vetted his input using assembler, did his computations with FORTAN
programs and printed the results with RPG.
His philosophy was 'use the most appropriate tool for the task at hand'.
But it is not always easy to convince TPTB that's the way to go.
John
yvette hirth
2010-05-16 17:54:36 UTC
Permalink
Post by Gary Lee Phillips
Another approach would be to use unformatted I/O, and write your
values out to a temporary file. Read that file back in with another
language that does more efficient I/O and do your printing at that
time. So Fortran does the calculations and writes the numbers to a
tape or temp file, which you pass to a second step written in COBOL or
PL/I that formats the report.
wouldn't the easiest and fastest approach be to write out all five
values per line with one format statement?

can't you do:

do 20 (index = ...)
v1 = value(index)
v2 = value(index + 1)
v3 = value(index + 2)
v4 = value(index + 3)
v5 = value(index + 4)
WRITE (*,*) 'v1=',v1,', v2=',v2,', v3=',v3,', v4=',v4,', v5=',v5
index = index + 5
20 continue

?

yvette hirth
Ron Hudson
2010-05-16 18:06:21 UTC
Permalink
Post by yvette hirth
Post by Gary Lee Phillips
Another approach would be to use unformatted I/O, and write your
values out to a temporary file. Read that file back in with another
language that does more efficient I/O and do your printing at that
time. So Fortran does the calculations and writes the numbers to a
tape or temp file, which you pass to a second step written in COBOL or
PL/I that formats the report.
wouldn't the easiest and fastest approach be to write out all five
values per line with one format statement?
do 20 (index = ...)
v1 = value(index)
v2 = value(index + 1)
v3 = value(index + 2)
v4 = value(index + 3)
v5 = value(index + 4)
WRITE (*,*) 'v1=',v1,', v2=',v2,', v3=',v3,', v4=',v4,', v5=',v5
index = index + 5
20 continue
?
yvette hirth
Your suggesting close to what I am already doing...

Actually I am computing them - The function takes n

n = some positive integer

if (mod(n,2) .eq. 0) n = n / 2
if (mod(n,2) .ne. 0) n = 3 * n + 1

print n

repeat until n = 1


but I want to print them 5 wide to save virtual paper...

I am currently saving 5 of them in an array and then printing out the array.

The writing is easy:
write(6,100) (array(i), i = 1,5)
100 format (' ',5I12)

Then I empty the array and fill it again to print the next line. I was
hoping to do
it without the array and indexes and stuff.
Ron Hudson
2010-05-16 17:54:12 UTC
Permalink
Post by Dave Wade
-----Original Message-----
Behalf Of *Gary Lee Phillips
*Sent:* dimanche 16 mai 2010 15:07
*Subject:* [turnkey-mvs] Re: Fortran Users! Is there a better way to do
this?
Hi Ron.
------ snip ----
Another approach would be to use unformatted I/O, and write your
values out to a temporary file. Read that file back in with another
language that does more efficient I/O and do your printing at that
time. So Fortran does the calculations and writes the numbers to a
tape or temp file, which you pass to a second step written in COBOL or
PL/I that formats the report.
---- snip ----
--Gary
Many many moons ago (circa 1968-69 IIRC) I worked with a contractor who
vetted his input using assembler, did his computations with FORTAN
programs and printed the results with RPG.
His philosophy was 'use the most appropriate tool for the task at hand'.
But it is not always easy to convince TPTB that's the way to go.
John
Another interesting take.
: ^ )
Rick Fochtman
2010-05-16 18:48:50 UTC
Permalink
------------------------------<snip>-------------------------------------
Post by Ron Hudson
Hey fellow fortran users..
I have a program that produces a long list of numbers calculated one
after the other.
I want to print these numbers 5 wide to save 'paper'
an array(5)
a pointer = 0
loop
increment pointer
fill array(pointer) with next calculated result)
if pointer = 5
print array on a line of the page
zero pointer
until done calculating
if (pointer .ge. 1) print array(1 - pointer)
...
Is there a better way?
Ron
-------------------------------------------<unsnip>------------------------------------
Looks fine to me. That's how I'd do it as well.
Gary Lee Phillips
2010-05-17 10:11:46 UTC
Permalink
Post by Ron Hudson
write(6,100) (array(i), i = 1,5)
100 format (' ',5I12)
Then I empty the array and fill it again to print the next line. I was
hoping to do it without the array and indexes and stuff.
I think you need the array if you're worried about I/O efficiency. If
you want to write a whole page at once with just one I/O, you can.
Just make the array bigger. Say you want 50 lines of 5 values each,
dimension the array(250) and try this:

WRITE(6,100) (ARRAY(I), I = 1, 250)
100 FORMAT ('1 ', 50(/1X,5I12))

Obviously, if there aren't going to be 250 values, you need to adjust
somehow for that. In general, though, one I/O per line just isn't that
big a deal these days, so what you are already doing is pretty
acceptable.

--Gary

Loading...