Most elegant way to read to allocatable array?  
Author Message
James Giles





PostPosted: 2007-1-22 10:50:36 Top

fortran, Most elegant way to read to allocatable array? Gary Scott wrote:
...
> My assumption was that once you query it, it is a reserved (negative
> or whatever) number that can't be used anywhere else regardless of
> whether it actuall gets connected or not. If a second inquire
> occurs, it must return a different number.

Most implementations have a limited number of different unit
numbers that are legal. A program that opens a lot of files
must usually reuse some of the numbers. You can't simultaneously
open more than a certain number on most operating systems
snyway.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


 
James Giles





PostPosted: 2007-1-22 10:50:00 Top

fortran >> Most elegant way to read to allocatable array? Gary Scott wrote:
...
> My assumption was that once you query it, it is a reserved (negative
> or whatever) number that can't be used anywhere else regardless of
> whether it actuall gets connected or not. If a second inquire
> occurs, it must return a different number.

Most implementations have a limited number of different unit
numbers that are legal. A program that opens a lot of files
must usually reuse some of the numbers. You can't simultaneously
open more than a certain number on most operating systems
snyway.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


 
James Giles





PostPosted: 2007-1-22 10:56:00 Top

fortran >> Most elegant way to read to allocatable array? email***@***.com wrote:
...
> No, the problem is that it is numeric. The numeric value has to be
> translated into a reference to the real data structure that contains
> the necessary data. That requires using a global table to map
> numbers to the corresponding data structures. In threaded code,
> that means using locks. I have seen real world programs that
> spend 30+% of their execution time in the locking routines for I/O.
> Yes, they are doing things like reading a direct-access file one
> character at a time, but codes like that do exist.

Locks are required anyway to ensure distinct threads don't try
doing I/O "simultaneously" on the same file. Sure, without the
unit number lookup there's one less lock. Actually that only
needs to be locked when it's being modified (during OPEN
statement processing). Such table locks are not that expensive.
I guess it depends on how you implement locks in general
though. Been there, done that.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


 
 
Gary Scott





PostPosted: 2007-1-22 21:55:00 Top

fortran >> Most elegant way to read to allocatable array? James Giles wrote:
> Gary Scott wrote:
> ...
>
>>My assumption was that once you query it, it is a reserved (negative
>>or whatever) number that can't be used anywhere else regardless of
>>whether it actuall gets connected or not. If a second inquire
>>occurs, it must return a different number.
>
>
> Most implementations have a limited number of different unit
> numbers that are legal. A program that opens a lot of files
> must usually reuse some of the numbers. You can't simultaneously
> open more than a certain number on most operating systems
> snyway.
>
Most implementations that I've used allow any positive value allowed in
a default integer. There are typically limits on the number of
simultaneously assigned files.

--

Gary Scott
mailto:garylscott@sbcglobal dot net

***** 5 Jan: Back from 7 days in Cozumel! *****

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
 
 
pa





PostPosted: 2007-1-22 23:00:00 Top

fortran >> Most elegant way to read to allocatable array? Gary Scott <email***@***.com> wrote:
> Pierre Asselin wrote:
> >
> > [ ... ]
> > The minimal change to Fortran could be a new key in the OPEN
> > statement, for example OPEN(NEWUNIT=ivar, FILE=...).

> I personally don't consider that to be any better than an
> INQUIRE(FREEUNIT=ivar) method followed by a normal OPEN(UNIT...).

Which is what I do, but you have to loop over ivar until you find
a free unit (or cut bait). I ended up with 15 lines of boilerplate
that I would rather not have written.

Also, the scheme is vulnerable to conflicts with old code, as
Richard points out.

call get_me_an_unused_unit(ivar)
open(unit=ivar, file='important')
call DUSTYDECK(in,out)
write(ivar,*) out

There is no telling what units are hard-coded in DUSTYDECK.

> I consider INQUIRE to be more natural, otherwise, you're having OPEN
> perform an implicit inquire with the NEWUNIT specifier. It also allows
> you to INQUIRE a free unit without immediately opening/assigning to
> something.

There is no reason to deprecate INQUIRE. As to what feels natural,
I think this is just habit, pure and simple. I had to get used to
C's way of doing things when I learned C; comparing after many
years, processor-chosen handles are better than user-chosen handles.
I couldn't have told you that ahead of time.

--
pa at panix dot com
 
 
pa





PostPosted: 2007-1-22 23:06:00 Top

fortran >> Most elegant way to read to allocatable array? Richard Maine <email***@***.com> wrote:

> [ ... ] Having OPEN return a negative unit number,
> which can't conflict with an open of a valid user-assigned unit number,
> avoids that problem.

It also breaks some of my code, in subroutines that take a unit
number for optional output and use iunit<0 to mean "don't write
anything", which is legal by today's standard. If we reserve -1
to mean "impossible unit" and specify that OPEN(NEWUNIT_or_whatever=)
returns a negative number other than -1, I can fix my code by a
trivial change to the test. Otherwise, I have to add an extra
logical argument or use F90+ features such as optional arguments.

Reserving -1 seems like a simple thing to do.

--
pa at panix dot com
 
 
nospam





PostPosted: 2007-1-23 0:47:00 Top

fortran >> Most elegant way to read to allocatable array? Pierre Asselin <email***@***.com> wrote:

> Richard Maine <email***@***.com> wrote:
>
> > [ ... ] Having OPEN return a negative unit number,
> > which can't conflict with an open of a valid user-assigned unit number,
> > avoids that problem.
>
> It also breaks some of my code, in subroutines that take a unit
> number for optional output and use iunit<0 to mean "don't write
> anything", which is legal by today's standard. If we reserve -1
> to mean "impossible unit" and specify that OPEN(NEWUNIT_or_whatever=)
> returns a negative number other than -1, I can fix my code by a
> trivial change to the test. Otherwise, I have to add an extra
> logical argument or use F90+ features such as optional arguments.
>
> Reserving -1 seems like a simple thing to do.

Makes sense to me. In fact, checking f2003, I see that INPUT_UNIT,
OUTPUT_UNIT, and ERROR_UNIT are specifically prohibitted from being -1.
I don't recall that level of detail of the OPEN(NEWUNIT_or_whatever=)
proposal, but it would certainly seem that the idea in f2003 is to
reserve -1, which would be sort of pointless if it wasn't done
consistently.

Hmm. The one other place in f2003 where a negative unit number is
alllowed is in DTIO. I don't off-hand see a restriction against -1
there. I might possibly have missed it. Seems to me like one belongs
there. And Note 9.44 will need some attention if the NEWUNIT= feature is
added.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
 
 
nospam





PostPosted: 2007-1-23 1:03:00 Top

fortran >> Most elegant way to read to allocatable array? Gary Scott <email***@***.com> wrote:
[about unit numbers]
> Most implementations that I've used allow any positive value allowed in
> a default integer.

That seems typical of the more recent implementations. However, I would
have said that smaller limits than that were common earlier. I've seen
limits of 63, 99, and 255. My personal portability guideline is to stop
at 99. (The 63 limit was unusual, and I think a later version of that
compiler upped it).

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
 
 
glen herrmannsfeldt





PostPosted: 2007-1-23 2:02:00 Top

fortran >> Most elegant way to read to allocatable array? Gary Scott <email***@***.com> wrote:
(snip on UNIT numbers)

> Most implementations that I've used allow any positive value allowed in
> a default integer. There are typically limits on the number of
> simultaneously assigned files.

It is easy enough to use a hash table to accept any valid postive
integer. I am pretty sure that many Fortran 66 implementations
didn't do that, instead using a fixed size table and directly
indexing it.

For OS/360 and successors the unit number maps directly to the
DDname, allowing for only two digits. I believe the actual
maximum is a sysgen option.

-- glen
 
 
Dan Nagle





PostPosted: 2007-1-23 2:25:00 Top

fortran >> Most elegant way to read to allocatable array? Hello,

-1 is off limits because inquire returns -1
to mean no such unit.

Richard E Maine wrote:
> Pierre Asselin <email***@***.com> wrote:
>
>> Richard Maine <email***@***.com> wrote:
>>
>>> [ ... ] Having OPEN return a negative unit number,
>>> which can't conflict with an open of a valid user-assigned unit number,
>>> avoids that problem.
>> It also breaks some of my code, in subroutines that take a unit
>> number for optional output and use iunit<0 to mean "don't write
>> anything", which is legal by today's standard. If we reserve -1
>> to mean "impossible unit" and specify that OPEN(NEWUNIT_or_whatever=)
>> returns a negative number other than -1, I can fix my code by a
>> trivial change to the test. Otherwise, I have to add an extra
>> logical argument or use F90+ features such as optional arguments.
>>
>> Reserving -1 seems like a simple thing to do.
>
> Makes sense to me. In fact, checking f2003, I see that INPUT_UNIT,
> OUTPUT_UNIT, and ERROR_UNIT are specifically prohibitted from being -1.
> I don't recall that level of detail of the OPEN(NEWUNIT_or_whatever=)
> proposal, but it would certainly seem that the idea in f2003 is to
> reserve -1, which would be sort of pointless if it wasn't done
> consistently.
>
> Hmm. The one other place in f2003 where a negative unit number is
> alllowed is in DTIO. I don't off-hand see a restriction against -1
> there. I might possibly have missed it. Seems to me like one belongs
> there. And Note 9.44 will need some attention if the NEWUNIT= feature is
> added.
>


--
Cheers!

Dan Nagle
Purple Sage Computing Solutions, Inc.
 
 
nospam





PostPosted: 2007-1-23 2:37:00 Top

fortran >> Most elegant way to read to allocatable array? (I've re-arranged the top-posting for clarity)

> Richard E Maine wrote:
> > Pierre Asselin <email***@***.com> wrote:

> >> Reserving -1 seems like a simple thing to do.
> > Makes sense to me....
> > Hmm. The one other place in f2003 where a negative unit number is
> > alllowed is in DTIO. I don't off-hand see a restriction against -1
> > there. I might possibly have missed it. Seems to me like one belongs
> > there. And Note 9.44 will need some attention if the NEWUNIT= feature is
> > added.
> >

Dan Nagle <email***@***.com> replied:

> -1 is off limits because inquire returns -1
> to mean no such unit.

That would be part of why it would make sense to keep -1 off limits, but
I don't see that it follows that the standard disallows DTIO from using
-1. I see that it would be a poor choice for a compiler to make, but
that's not the same thing as being disallowed. I would think that the
standard should explicitly disallow -1 as a DTIO unit number, just like
it explicitly disallows it for INPUT_UNIT, OUTPUT_UNIT, and ERROR_UNIT.
After all, the disallowance is explicit in those 3 cases, which one
could apply the sam eargument to.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
 
 
pa





PostPosted: 2007-1-23 22:58:00 Top

fortran >> Most elegant way to read to allocatable array? email***@***.com wrote:

> Pierre Asselin wrote:

> > The problem here is not that the handle is numeric, but that the
> > the responsibility for its value is forced on the user.

> No, the problem is that it is numeric. The numeric value has to be
> translated into a reference to the real data structure that contains
> the necessary data. That requires using a global table to map
> numbers to the corresponding data structures. In threaded code,
> that means using locks. I have seen real world programs that
> spend 30+% of their execution time in the locking routines for I/O.
> Yes, they are doing things like reading a direct-access file one
> character at a time, but codes like that do exist.

Is the lock required on all I/O operations or just on OPEN/CLOSE
? It seems to me that two threads could do simultaneous I/O on
different units without any locking overhead if the run-time library
is implemented right --but I've never written one so I may be
completely wrong about that.

If you mean concurrent I/O on the same unit, that's a much bigger
beast. There was a long thread in c.l.c++.moderated on how
underspecified that language is for multi-threaded programming.
If anything, Fortran is even more underspecified. Presumably
the Fortran support for parallel processing will come in at a
higher level, e.g. co-arrays in F08.


> Never add a feature to a language that requires global state. It
> will cause trouble in a multi-threaded environment, and that is
> where computing is headed.

Except that the feature is already in, and has been since the
earliest days of Fortran. My proposal, if you want to call it
that, is orthogonal to threading nightmares.


--
pa at panix dot com
 
 
Janne Blomqvist





PostPosted: 2007-1-24 7:24:00 Top

fortran >> Most elegant way to read to allocatable array? In article <ep57qh$rbq$email***@***.com>, Pierre Asselin wrote:
> email***@***.com wrote:
>
>> Pierre Asselin wrote:
>
>> > The problem here is not that the handle is numeric, but that the
>> > the responsibility for its value is forced on the user.
>
>> No, the problem is that it is numeric. The numeric value has to be
>> translated into a reference to the real data structure that contains
>> the necessary data. That requires using a global table to map
>> numbers to the corresponding data structures. In threaded code,
>> that means using locks. I have seen real world programs that
>> spend 30+% of their execution time in the locking routines for I/O.
>> Yes, they are doing things like reading a direct-access file one
>> character at a time, but codes like that do exist.
>
> Is the lock required on all I/O operations or just on OPEN/CLOSE
> ?

I suspect it's needed, e.g. you need to make sure that one thread
doesn't close the unit while another is doing i/o in it, no?

> It seems to me that two threads could do simultaneous I/O on
> different units without any locking overhead if the run-time library
> is implemented right --but I've never written one so I may be
> completely wrong about that.

You can find a brief description of how gfortran does it at
http://gcc.gnu.org/viewcvs/*checkout*/trunk/libgfortran/io/unit.c
(gfortran supports openmp, so the library needs to be thread safe).

Basically there is one lock which protects the tree which holds the
data structures that the library keeps for each open unit, and then
there is one lock per unit.

> If you mean concurrent I/O on the same unit, that's a much bigger
> beast. There was a long thread in c.l.c++.moderated on how
> underspecified that language is for multi-threaded programming.
> If anything, Fortran is even more underspecified. Presumably
> the Fortran support for parallel processing will come in at a
> higher level, e.g. co-arrays in F08.

Should be doable at least for direct access. Could work for reading
sequential and stream as well if you take the view that the file
position is per-thread instead of a global property, though it should
be noted that co-array Fortran apparently forbids opening a sequential
file with action=read on multiple images. See
ftp://ftp.nag.co.uk/sc22wg5/N1601-N1650/N1639.txt

--
Janne Blomqvist
 
 
Gary Scott





PostPosted: 2007-1-24 7:37:00 Top

fortran >> Most elegant way to read to allocatable array? Janne Blomqvist wrote:

> In article <ep57qh$rbq$email***@***.com>, Pierre Asselin wrote:
>
>>email***@***.com wrote:
>>
>>
>>>Pierre Asselin wrote:
>>
>>>>The problem here is not that the handle is numeric, but that the
>>>>the responsibility for its value is forced on the user.
>>
>>>No, the problem is that it is numeric. The numeric value has to be
>>>translated into a reference to the real data structure that contains
>>>the necessary data. That requires using a global table to map
>>>numbers to the corresponding data structures. In threaded code,
>>>that means using locks. I have seen real world programs that
>>>spend 30+% of their execution time in the locking routines for I/O.
>>>Yes, they are doing things like reading a direct-access file one
>>>character at a time, but codes like that do exist.
>>
>>Is the lock required on all I/O operations or just on OPEN/CLOSE
>>?
>
>
> I suspect it's needed, e.g. you need to make sure that one thread
> doesn't close the unit while another is doing i/o in it, no?

Not necessarily. I would say that that is an application decision to
communicate between the threads (e.g. master/slave) and ensure that only
the thread that knows it is safe to do so does so. It isn't uncommon
for a multithreaded application to funnel all I/O activity through a
dedicated IO thread or separate IO process. I use a small file mapping
area (I once tried pipes for cross network synchronization and it seemed
to work really well) to communicate across threads and processes with a
fairly simple handshaking instruction/status interface. Some of this
becomes straightforwarded once you have basic thread/process facilities
within the language...maybe by my 90th birthday.

>
>
>>It seems to me that two threads could do simultaneous I/O on
>>different units without any locking overhead if the run-time library
>>is implemented right --but I've never written one so I may be
>>completely wrong about that.
>
>
> You can find a brief description of how gfortran does it at
> http://gcc.gnu.org/viewcvs/*checkout*/trunk/libgfortran/io/unit.c
> (gfortran supports openmp, so the library needs to be thread safe).
>
> Basically there is one lock which protects the tree which holds the
> data structures that the library keeps for each open unit, and then
> there is one lock per unit.
>
>
>>If you mean concurrent I/O on the same unit, that's a much bigger
>>beast. There was a long thread in c.l.c++.moderated on how
>>underspecified that language is for multi-threaded programming.
>>If anything, Fortran is even more underspecified. Presumably
>>the Fortran support for parallel processing will come in at a
>>higher level, e.g. co-arrays in F08.
>
>
> Should be doable at least for direct access. Could work for reading
> sequential and stream as well if you take the view that the file
> position is per-thread instead of a global property, though it should
> be noted that co-array Fortran apparently forbids opening a sequential
> file with action=read on multiple images. See
> ftp://ftp.nag.co.uk/sc22wg5/N1601-N1650/N1639.txt
>


--

Gary Scott
mailto:garylscott@sbcglobal dot net

***** 5 Jan: Back from 7 days in Cozumel! *****

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
 
 
kargl





PostPosted: 2007-1-24 7:59:00 Top

fortran >> Most elegant way to read to allocatable array? In article <r%wth.22446$email***@***.com>,
Gary Scott <email***@***.com> writes:
> Janne Blomqvist wrote:
>
>> In article <ep57qh$rbq$email***@***.com>, Pierre Asselin wrote:
>>
>>>email***@***.com wrote:
>>>
>>>
>>>>Pierre Asselin wrote:
>>>
>>>>>The problem here is not that the handle is numeric, but that the
>>>>>the responsibility for its value is forced on the user.
>>>
>>>>No, the problem is that it is numeric. The numeric value has to be
>>>>translated into a reference to the real data structure that contains
>>>>the necessary data. That requires using a global table to map
>>>>numbers to the corresponding data structures. In threaded code,
>>>>that means using locks. I have seen real world programs that
>>>>spend 30+% of their execution time in the locking routines for I/O.
>>>>Yes, they are doing things like reading a direct-access file one
>>>>character at a time, but codes like that do exist.
>>>
>>>Is the lock required on all I/O operations or just on OPEN/CLOSE
>>>?
>>
>>
>> I suspect it's needed, e.g. you need to make sure that one thread
>> doesn't close the unit while another is doing i/o in it, no?
>
> Not necessarily. I would say that that is an application decision to
> communicate between the threads (e.g. master/slave) and ensure that only
> the thread that knows it is safe to do so does so. It isn't uncommon
> for a multithreaded application to funnel all I/O activity through a
> dedicated IO thread or separate IO process. I use a small file mapping
> area (I once tried pipes for cross network synchronization and it seemed
> to work really well) to communicate across threads and processes with a
> fairly simple handshaking instruction/status interface. Some of this
> becomes straightforwarded once you have basic thread/process facilities
> within the language...maybe by my 90th birthday.
>

As the writer of the application, you can indeed funnel all I/O
through a dedicated thread to try to economize locking. From the
gfortran perspective, its runtime library can't assume everyone
knows how to properly lock the I/O channels, so it takes a defensive
position with tracking/applying locking to IO units.

--
Steve
http://troutmask.apl.washington.edu/~kargl/
 
 
James Giles





PostPosted: 2007-1-24 8:35:00 Top

fortran >> Most elegant way to read to allocatable array? Janne Blomqvist wrote:
> In article <ep57qh$rbq$email***@***.com>, Pierre Asselin wrote:
...
>> Is the lock required on all I/O operations or just on OPEN/CLOSE
>> ?
>
> I suspect it's needed, e.g. you need to make sure that one thread
> doesn't close the unit while another is doing i/o in it, no?

That would be a lock that's needed whether the I/O used unit numbers
or handles. The lock on the I/O unit table is unlocked as soon as
you've looked up the corresponding handle. Since it's only a
table lookup it's fast and no thread spends much time in that
critical section. So, unit numbers don't really contributte much
to the overhead of handling threads. (Yes, the table has to be
locked longer during OPEN and CLOSE since you're modifying
it. And yes, things that don't modify the table could be let into
the critical section several at a time.)

>> If you mean concurrent I/O on the same unit, that's a much bigger
>> beast. There was a long thread in c.l.c++.moderated on how
>> underspecified that language is for multi-threaded programming.
>> If anything, Fortran is even more underspecified. Presumably
>> the Fortran support for parallel processing will come in at a
>> higher level, e.g. co-arrays in F08.

I've done concurrent I/O on the same unit with Fortran 77 before.
The rule was the any number of threads could simultaneously read
the file but only one could write and only when no reads or other
writes were in progress. You have to address several issues.
But it can be made to work.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


 
 
Janne Blomqvist





PostPosted: 2007-1-24 15:27:00 Top

fortran >> Most elegant way to read to allocatable array? James Giles wrote:
> Janne Blomqvist wrote:
>> In article <ep57qh$rbq$email***@***.com>, Pierre Asselin wrote:
> ...
>>> Is the lock required on all I/O operations or just on OPEN/CLOSE
>>> ?
>>
>> I suspect it's needed, e.g. you need to make sure that one thread
>> doesn't close the unit while another is doing i/o in it, no?
>
> That would be a lock that's needed whether the I/O used unit numbers
> or handles.

I don't know what I meant above (?), but anyway, AFAICS gfortran needs
to acquire this global lock for every read or write to do the unit
number -> pointer to the unit structure mapping. So if Fortran used
opaque handles instead of unit numbers, then the handle could contain
the pointer directly and the global lock would not be needed (since
the lock for the unit itself naturally resides in the unit
structure). OPEN/CLOSE would still need the global lock, but they
aren't that performance critical.

Other compilers may do it differently, I suppose.

> The lock on the I/O unit table is unlocked as soon as
> you've looked up the corresponding handle. Since it's only a
> table lookup it's fast and no thread spends much time in that
> critical section. So, unit numbers don't really contributte much
> to the overhead of handling threads.

Yes, though presumably you could, as usual, design some pathological
examples where it would be significant. E.g. as explained by Robert
Corbett.


--
Janne Blomqvist
 
 
James Giles





PostPosted: 2007-1-24 16:07:00 Top

fortran >> Most elegant way to read to allocatable array? Janne Blomqvist wrote:
> James Giles wrote:
>> Janne Blomqvist wrote:
...
>>> I suspect it's needed, e.g. you need to make sure that one thread
>>> doesn't close the unit while another is doing i/o in it, no?
>>
>> That would be a lock that's needed whether the I/O used unit numbers
>> or handles.
>
> I don't know what I meant above (?), but anyway, AFAICS gfortran needs
> to acquire this global lock for every read or write to do the unit
> number -> pointer to the unit structure mapping. [...]

Yes, but that particular table only needs to be locked while you look
up that one piece of data. That's then unlocked. But, then you must
lock the table entry for the specific file you're actually working on.
That second lock must be set even if you were to eliminate unit
numbers from the language and began to use "handles" or some
such feature.

Since the unit number table look-up is rather fast, the time lost waiting
on that first lock is trivial unless the locking mechanism you use has
lots of overhead itself. It's unlikely that the unit number look-up
table will be locked when a process gets there. Even in a program
with lots of threads which each do lots of I/O, the odds of a clash
are small.

> Yes, though presumably you could, as usual, design some pathological
> examples where it would be significant. E.g. as explained by Robert
> Corbett.

That's why you prove correctness and specify exactly what
assumptions went into the proof. Most pathological examples
are resolved by detecting them and issuing a message. Things
like the above: suppose you try to close from one thread while
still trying to do I/O on the same file from another thread. If the
one doing I/O gets there first all's well. If the close gets there
first you simply issue the usual message that the program is
attempting I/O on a unit that's not open. Too bad, but it's the
programmer's fault for creating such a race condition in his
(her) program in the first place. The latter case is no different
than if the file were closed before an I/O attempt in a single
threaded code.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


 
 
glen herrmannsfeldt





PostPosted: 2007-1-24 19:00:00 Top

fortran >> Most elegant way to read to allocatable array? Pierre Asselin wrote:
(snip regarding unit numbers)

> The problem here is not that the handle is numeric, but that the
> the responsibility for its value is forced on the user. In
> retrospect, that was a bad idea. It causes no end of trouble when
> integrating codes from different authors. To make matters worse,
> there are no guidelines for choosing a value, as Richard reminds
> us above.

If it was alphanumeric and chosen by the user, then the probability
of accidentally choosing one already used is much smaller.

I did always like the MVS DDname better than the small integers
of unix file descriptors. Though some are against the whole
idea of DDnames connecting to data sets.

(snip)
> let's not forget that under stdio is a low-level file handle provided
> by the operating system. Under Posix, this handle is an integer;
(snip)

> The temptation to use arithmetic on handle variables or to otherwise
> clobber them must not be that strong, because users just don't do
> that. The big difference with Fortran is that the numerical value
> is chosen by the open() call instead of the user.

Unix users like to do that all the time.

The way to redirect stdin is to open a new file, close(0)
and dup(newfile). dup() duplicates an open descriptor on the
lowest available, which will then be zero. If that isn't
good enough, there is dup2() to duplicate it on any
available fd. I think after the dup, then the other one
is closed, so there won't be two open fd's for the same
file.

-- glen

 
 
Dick Hendrickson





PostPosted: 2007-1-25 6:06:00 Top

fortran >> Most elegant way to read to allocatable array? Richard Maine wrote:
> Michael Prager <email***@***.com> wrote:
>
>> Richard Maine <email***@***.com> wrote:
>>
>>> Sort of related - I didn't mention it at the time, but I second
>>> Beliavsky's advice to avoid opening units 5 and 6 (or any unit numbers
>>> less than 10, but 5 and 6 are the "worst"). Those are exactly the unit
>>> numbers *MOST* likely to have problems. They are often special-cased in
>>> several ways.
>
> (Oh. I missed the "/" part of the "/=", as Glen noted).
>
>> Would it be unthinkable for the next Fortran standard to make
>> obsolescent the use of unit numbers < 10 for disk I/O? This
>> issue comes up again and again and again, and since it's not in
>> the standard, new users seem to learn about it only by being
>> burnt.
>
> I have pushed much more for the whole concept of unit numbers to be
> phased out. I think it is one of Fortran's unfortunate hostorical
> features, which made sense in days long ago, but is just a hindrance
> today. Patching up little bits of it here and there won't fix it.
>
> I've seen two proposals that I like.
>
> 1. The more drastic one, but I think the best in the long run. Introduce
> a new non-numeric file "handle". Allow open to return it, and allow it
> to be specified in the other I/O statements. Basically, you'd have the
> option of using either unit numbers or file handles. That should provide
> a transitional capability. Basically the way that most more recent
> languages do such things.
>
> 2. The best "hack" I've seen is to have a system function to provide an
> unused unit number. In order to avoid conflicts with hard-wired unit
> numbers in other code, it would have to be a negative number. We already
> (in f2003) have the concept of negative unit numbers as something that
> the system can assign, but that user's can't otherwise use.
>
> Note that this pretty much has to be a compiler function in order to
> avoid all possible conflicts.

[snip]
this comment is a little late, but I've been out of town.

F2008 has a NEWUNIT=scalar-integer-variable specifier on the OPEN
statement. Its job is to assign a value to the scalar integer
variable that is guaranteed to be an unused unit number. They
have to be negative and not equal to any of the special negative
values. It's sort of a compromise between a handle and a hack.

Dick Hendrickson
 
 
Janne Blomqvist





PostPosted: 2007-1-25 6:14:00 Top

fortran >> Most elegant way to read to allocatable array? James Giles wrote:
> Janne Blomqvist wrote:
>> I don't know what I meant above (?), but anyway, AFAICS gfortran needs
>> to acquire this global lock for every read or write to do the unit
>> number -> pointer to the unit structure mapping. [...]
>
> Yes, but that particular table only needs to be locked while you look
> up that one piece of data. That's then unlocked. But, then you must
> lock the table entry for the specific file you're actually working on.

Yes, obviously.

> That second lock must be set even if you were to eliminate unit
> numbers from the language and began to use "handles" or some
> such feature.

I'm not arguing against you, just pointing out that with handles one
can avoid the global lock; I don't think that is a particularly strong
argument for introducing I/O handles. Actually I kind of like the
OPEN(NEWUNIT=foo, ...) idea as being simpler and more like how Fortran
currently works.

>> Yes, though presumably you could, as usual, design some pathological
>> examples where it would be significant. E.g. as explained by Robert
>> Corbett.
>
> That's why you prove correctness and specify exactly what
> assumptions went into the proof.

I meant pathological as in R.C.:s example of a multithreaded program
spending a large amount of time waiting on the unit table lock.

> Most pathological examples
> are resolved by detecting them and issuing a message. Things
> like the above: suppose you try to close from one thread while
> still trying to do I/O on the same file from another thread. If the
> one doing I/O gets there first all's well. If the close gets there
> first you simply issue the usual message that the program is
> attempting I/O on a unit that's not open. Too bad, but it's the
> programmer's fault for creating such a race condition in his
> (her) program in the first place. The latter case is no different
> than if the file were closed before an I/O attempt in a single
> threaded code.

But this is a poor example for Fortran, since IIRC the standard
doesn't require you to explicitly OPEN units before using them, no?

--
Janne Blomqvist