What's the purpose of array size inside subroutine arguments?

Never gotten a chance to use Silverfrost.

I got to use a Lahey compiler when I first started learning, and at the time it gave the better compilation errors compared to whatever else I had available at the time.

I was under the impression that g95 stopped being supported once gfortran got going.

Some blas procedure need incx argument,which means incontiguous index. so a(*) should be changed as a(1+(n-1)*incx)

2 Likes

You can check the dimensions of assumed-shape arrays concisely with FINDLOC, as I showed.

This mismatch,

call f(size(A)+1, A)

looks like something a static analyzer could catch. They have these in other languages:

GCC has a static analyzer for C - The state of static analysis in the GCC 12 compiler | Red Hat Developer

Are there any for Fortran? Bjarne Stroustrup believes that for safe code it’s best to use a “cocktail” of techniques, meaning both static analysis tools, and instrumentation/run-time checking.

Maybe Fortraners should get in the habit of declaring scalar variables that are not read or used as loop indices as allocatable. Then the first assignment of such variables allocates them, and if they are used without being allocated, that should trigger a run-time error. Their behavior would resemble that of variables in a language like Python.

@certik, when F90 introduced assumed shape arrays I believe there was some reluctance to use them instead of explicit shaped arrays because early implementations of assumed shape did not perform as well as explicit shape. I assume in the 30 or so years since F90 that the performance difference has been fixed. My question then is as a compiler developer do you see any performance advantage to using explicit shape vs assumed shape? Are there cases where the optimizer will generate more efficient code with explicit shape? Just curious.

One could revisit the example codes in

McCalpin, J. D. (1996). A Case Study of Some Issues in the Optimization of Fortran 90 Array Notation Scientific Programming

Abstract
Some issues in the relationship of coding style and compiler optimization are discussed with regard to Fortran 90 array notation. A review of several important Fortran 90 array constructs and their performance on vector and scalar hardware sets the stage for a more detailed example based on the kernel of a finite difference computational fluid dynamics model, specifically the nonlinear shallow water equations. Special attention is paid to the optimization of memory use and memory traffic. It is shown that the style of coding interacts with the rules of Fortran 90 and the current state of the art of Fortran 90 compilers to produce a fairly wide range of performance levels. Although performance degradations are typically small, a few cases of more serious loss of efficiency are identified and discussed.

Definitely. The explicit shape arrays do not need an array descriptor, so they can be represented by just a pointer to a contiguous memory. The assumed shape arrays in general can be strided and you will only know the dimensions and striding at runtime. So if you want to generate fast code compilers typically generate two versions of each function, one assuming contiguous memory and one for strided. You need to insert checks and handle array descriptors. In LFortran we have a pass that can optionally transform and assumed shape arrays to explicit shape. This causes a strided array to be converted to a contiguous one earlier in the function stack, which might or might not improve performance.

The general question is about strided arrays, which are typically slower to vectorize. If we assumed that all arrays are always contiguous, then I think assumed shape and explicit shape arrays could be implemented to have the same performance.

3 Likes

Yes you can. But I don’t recommend doing this as a user. Rather, the compiler should do this for you automatically and only in Debug mode, so that in Release mode things can run at maximum speed.

I always found it easier to set values as a NaN usually via a compiler option. Then turn on checks for floating point errors. That way when the value is used you trigger an error if you haven’t set it before use.

the ANY() and ALL() intrinsics are also useful for this. The expressions are clear to a human and easy for the compiler to optimize.

The programmer also has the option of including the checks in the source code, but surrounding them with either an if(.true.) block or a preprocessor directive #if 1. The compiler can then remove the dead code for the production builds, while giving the programmer easy access to the checking during the development/debug steps. Of course, parameters and macros can be used to activate/deactive multiple blocks.

1 Like

G95 is indeed no longer supported but I still use it. It’s pretty good on Fortran 95 with many Fortran 2003 features but it has some unfixed bugs and it never implemented all the quad precision intrinsics.

1 Like

Isn’t the contiguous attribute supposed to help, here?

2 Likes

passing-arrays-to-subroutines-in-fortran-assumed-shape-vs-explicit-shape](Passing arrays to subroutines in Fortran: Assumed shape vs explicit shape - Stack Overflow) This should help answer the question about passing fortran arrays sizes in subroutine calls.

4 Likes