experchange > fortran

FortranFan (02-05-19, 06:08 PM)
On Monday, February 4, 2019 at 9:58:48 PM UTC-5, Ron Shepard wrote:

[..]
> change the legacy code to
> A(:,:) = B(:,:)
> ..


@Ron Shepard,

So to reiterate, you are bringing up these scenarios but which point to code that may be nonconforming to begin with and then you are jumping to your approach to "correcting" such code in view of the resultant problems with the highly questionable array approach such as "A(:,:) = B(:,:)" when other, possibly better refactoring options can be considered.

Given the alarms you raise and which are likely false, you really need to put in the effort to illustrate your scenarios.

Separately, you write "The main reason is because of the false positive warning messages by compilers warning the programmer that possible reallocation of the array may occur" - you need to explain this too, what "false positive warning messages by compilers", where?!

Toward the points I am making, I can easily show a minimal working example as follows: note the code example has all manner of array operations *without* any of the array section non-sense:

--- begin code ---
module m
integer, allocatable, save :: x(:) ! Module "data"
logical, save :: Data_Are_Setup = .false.
contains
subroutine Setup_Data( n )
! Example state management
integer, intent(in) :: n
if ( Data_Are_Setup ) then
if ( size(x) /= n ) then
! handling elided: is stop an option?
stop "Data setup with different shape"
end if
else
allocate( x(n) )
Data_Are_Setup = .true.
end if
end subroutine
subroutine DataOps( y )
integer, intent(in) :: y(:)
call Setup_Data( size(y) )
! Some operations on module data
x = y
print *, "DataOps: size(x) = ", size(x), "x = ", x
end subroutine
subroutine Clean_Data()
if ( Data_Are_Setup ) then
deallocate(x)
Data_Are_Setup = .false.
end if
end subroutine
end module
program p
use m
integer, parameter :: n = 3 ! Specification of "data"
integer, parameter :: nn = n-1
integer, allocatable :: a(:)
integer :: i
allocate( a(n) ) ! Allocation of "data"
a = 0 ! Initialization of "data"
print *, "main: size(a) = ", size(a), "a = ", a
a = (/ (i, i=1,n) /) ! Definition of "data"
print *, "main: size(a) = ", size(a), "a = ", a
call Setup_Data(nn) ! or Setup_Data(n)
call DataOps( a ) ! Operation on "data"
call Clean_Data()
if ( allocated(a) ) deallocate(a) ! Finalization of "data"
stop
end program
--- end code ---

And here are console outputs with 3 different compilers: 1) gfortran with -std=f95 to enforce Fortran 95 standard compliance, 2) with Compaq Visual Fortran dated 2003 and 3) with current Intel Fortran. You will see no compiler "false" warnings. In terms of run-time, the results are consistent with all the 3 compilers and as expected.

--- gfortran with -std=f95 ---
C:\Temp>gfortran -Wall -Wextra -pedantic -fcheck=all -std=f95 p.f90 -o p.exe

C:\Temp>p.exe
main: size(a) = 3 a = 0 0 0
main: size(a) = 3 a = 1 2 3
STOP Data setup with different shape

C:\Temp>
--- end gfortran ---

--- Compaq Visual Fortran v6.6C ---
C:\Temp>df /warn:all /check:all p.f90
Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update C)
Copyright 2003 Compaq Computer Corp. All rights reserved.

p.f90
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/subsystem:console
/entry:mainCRTStartup
/debugtype:cv
/pdb:none
obj3F9B.tmp
dfor.lib
libc.lib
dfconsol.lib
dfport.lib
kernel32.lib
/out:p.exe

C:\Temp>p.exe
main: size(a) = 3 a = 0 0 0
main: size(a) = 3 a = 1 2 3
Data setup with different shape

C:\Temp>
--- end Compaq Fortran ---

--- Intel Fortran ---
C:\Temp>ifort /standard-semantics /warn:all /check:all /stand p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.1.144 Build 20181018
Copyright (C) 1985-2018 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 14.16.27026.1
Copyright (C) Microsoft Corporation. All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe
main: size(a) = 3 a = 0 0 0
main: size(a) = 3 a = 1 2 3
Data setup with different shape

C:\Temp>
--- end Intel Fortran ---

So you will see ample evidence above this example code is standard-conforming including with Fortran 95 revision, it deliberately involves a scenario of a shape mismatch which is handled, and yet all the array operations are achieved with Fortran whole-array syntax which is a true strength of the language.

If you are writing code as you indicate with your notions of "conditional checks", "false positive compiler warnings", array sections, etc. and such code is disseminated in your domain to others, you are likely doing Fortran a great disservice.
FortranFan (02-05-19, 06:38 PM)
On Tuesday, February 5, 2019 at 11:04:46 AM UTC-5, Ron Shepard wrote:

> .. generate array bounds mismatch errors when
> they erroneously occur. A=<expression> would do that with f90 semantics, ..


Again, why don't you go through the Fortran 90 standard as well as your choice of "Fortran 90 compilers" and check what "array bounds mismatch errors" got generated by such compilers when "array bounds mismatch" "erroneously occur"ed?

You seem to presume "f90 semantics" did something useful for you to "generate array bounds mismatch errors" and that is where you are wrong.

> As for your other point, yes you can place the appropriate debug code
> into the program to test for SIZE() along all of the dimensions of all
> the arrays and do this testing manually. That has never been the issue.


Indeed that is not the issue. The issue really is your "advertising" of your array section approach e.g., "A(:) = B(:)"
Ian Harvey (02-06-19, 11:07 AM)
On 2019-02-05 01:29, spectrum wrote:
[..]
> I've never measured the performance difference for it.
> My another question is how this automatic reallocation of LHS syntax has been
> introduced or what motivated its introduction. Maybe Matlab-inspired...?


Have you tried writing code without it?

Consider cases such as:

! Expressions with unknown length parameters.
CHARACTER(*), INTENT(IN) :: first_name, last_name
CHARACTER(:), ALLOCATABLE :: full_name
lhs = first_name // ' ' // last_name

! Array expressions of unknown size.
FUNCTION unknown_size(...) RESULT(r)
INTEGER, ALLOCATABLE :: r(:)
...
ALLOCATE(r(xx))
...
END FUNCTION unknown_size

INTEGER, ALLOCATABLE :: lhs
lhs = unknown_size(...)

! Expressions of unknown type.
FUNCTION unknown_type(...) RESULT(r)
CLASS(t), ALLOCATABLE :: r
...
END FUNCTION

CLASS(t), ALLOCATABLE :: lhs
lhs = unknown_type(...)

There are workarounds for some of these things with "F95 style" code
(given other F95/F2003 feature gaps), but they are rather verbose and
clunky.

I find the angst against this F2003 feature rather odd.
dpb (02-06-19, 04:37 PM)
On 2/6/2019 3:07 AM, Ian Harvey wrote:
....

[..]
> (given other F95/F2003 feature gaps), but they are rather verbose and
> clunky.
> I find the angst against this F2003 feature rather odd.


As one who for the consulting gig relied on MATLAB heavily owing to its
fully-packaged environment, I was intrigued by the intro of array syntax
in F95 and tried moving some of the ML code I found useful for more than
single client over...indeed, at that time it was essentially useless for
emulating the way in which one writes MATLAB code--of course, generally
one isn't working with such large data sizes or problem types that are
as compute-intensive such that what performance overhead the
behind-the-scenes dynamic reallocation causes was critical.

But, in essence, the kind of problem Ron alludes to above can and does
happen on occasion in MATLAB, too--an inadvertent orientation of a
vector or matrix and a multiply operation on RHS and all of a sudden one
may have either a LHS that is suddenly an array instead of a value or an
inconsistent dimensions on assignment later on not apparently related to
the specific line of code at the point at which it occurred.

So, the "handiness" comes at a potential cost...but, overall, in the end
for my purposes I essentially dropped Fortran excepting for embedding
some very deep calculations as .mex files.

Similar Threads