Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28454 Discussions

Unhelpful MINLOC/MAXLOC documentation

DavidWhite
Valued Contributor II
1,205 Views

In the documentation for MINLOC and MAXLOC is the statement

"If array has size zero, or every element of mask has the value .FALSE., the value of the result is controlled by compiler option assume [no]old_maxminloc, which can set the result to either 1 or 0."

In this case, it is unclear to me when to expect a value of 1 or 0, and there are no examples given for this situation.

Am I correct in interpreting this that default compiler option is assume old_maxminloc, and the result is then 1, but with assume noold_maxminloc the result will be zero?

Thanks,

David

0 Kudos
9 Replies
Kevin_D_Intel
Employee
1,205 Views

Yes David, your interpretation should be correct. I will look into having some additional clarification added in the documentation.

To cite from an earlier case (DPD200111859) - Title: the MINLOC and MAXLOC do not properly work with empty arrays (closed as not a defect).

They noted in the case the Fortran 2003 standard says:

13.7.78 MINLOC
[...]
Result Value.

Case (i): [...]
If ARRAY has size zero, all elements of the result are zero.

Similarly for MAXLOC.

It included the following example which prints ones instead of zeros.

program ifc11_minloc_bug
implicit none
integer :: m(0)
print *, minloc (m), maxloc (m) ! Correct result: 0 0
end program ifc11_minloc_bug
$ ifort -V
Intel(R) Fortran Intel(R) 64 Compiler Professional for applications running on Intel(R) 64, Version 11.0    Build 20081105 Package ID: l_cprof_p_11.0.074
Copyright (C) 1985-2008 Intel Corporation.  All rights reserved.

$ ifort -O0 Q532928.f90
$ ./a.out
           1           1

Development explained this was not a defect but intended behavior writing:

The compiler provides the option for the F2003 max/minloc behavior with the switch "-assume noold_maxminloc".

Previous versions of the Fortran standard (e.g. F95) allowed for a MAXLOC or MINLOC returning 1 for zero-sized arrays, and this was the behavior of the compiler until late 2007.  At that time, we added the new, F2003-defined behavior for this case, but under the switch "-assume noold_maxminloc".  We kept the default to be the old behavior for compatibility with previous versions and because the new behavior results in code that will not execute as quickly as the old behavior (not necessarily with the given example, but with other, more complicated examples).

So, to get the F2003 behavior for this intrinsic, use the "-assume noold_maxminloc" switch, with the understanding that this is a change from previous versions of the compiler, and the resulting code may execute somewhat slower.

0 Kudos
TimP
Honored Contributor III
1,205 Views

Am I correct in observing that 15.0 compiler doesn't necessarily require old_maxminloc for optimization?

the point is that prior to f2003 the result for 0 length array was undefined, and Ifort requires noold_maxminloc to get f2003 compliance. One might think the combination -stand -assume:old_maxminloc should throw a warning when 0 length is possible.

0 Kudos
Kevin_D_Intel
Employee
1,205 Views

I believe your observation is correct. This change dates back to the 11.0 release and I cannot find anything specific beyond the details relating to optimization/performance noted in the Developer’s quote.

0 Kudos
Steven_L_Intel1
Employee
1,205 Views

-stand would not warn about such things - it warns you for non-standard syntax, not run-time semantics.

I don't think the optimization issues have changed any.

0 Kudos
TimP
Honored Contributor III
1,205 Views

16.0.2 appears to have corrected the situation to where either old_maxminloc or noold_maxminloc can be used safely and produce optimized code.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,205 Views

IMHO, due to the fact that an array can be declared as A(-12:34), i.e. have a valid index of 0, I would have preferred that the returned value for a null array would be an improbable value, say -0 (0x80000000). Same for LBOUND and UBOUND.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
1,205 Views

Jim, the returned value is an integer. Since Intel Fortran doesn't run on CDC 6600 systems, there is no -0 available. Note that the case in question includes both a null array and one where the MASK is all .FALSE.. In most cases, zero is a reasonable choice and it is consistent with other intrinsics in similar situations (for example, INDEX).

0 Kudos
JVanB
Valued Contributor II
1,205 Views

@jimdempseyatthecove: You seem to be forgetting about how Fortran assumed-shape arrays work. The callee has no way of knowing LBOUND information so before the change was made to the standard the smallest index that could be returned for a nonempty set was 1. Returning 0 for an empty set thus is unambiguous, unlike returning garbage, which was the previous behavior. When this was pointed out the committee adopted the new behavior quickly.

module M
   implicit none
   contains
      subroutine S(X)
         integer X(:)
         write(*,'(*(g0))') 'LBOUND(X) = ',lbound(X)
      end subroutine S
end module M

program P
   use M
   implicit none
   integer X(-1:1)
   X = [1,2,3]
   write(*,'(*(g0))') 'MINLOC(X) = ',minloc(X)
   call S(X)
end program P
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,205 Views

-0 is a matter of interpretation. In Fortran 0x8... is indeed the largest negative integer (... extended to precision of type).

However, if this number were stored in X, you then have the perplexing situation where

(X .ne. 0 .and. X .eq. -X) is .true.

RO, you are right about pre-assumed shape. I didn't forget about this. Back in the early days of FORTRAN, negative indexes were just as invalid as an index of 0. Therefore 0 or any negative value could have been specified. Unfortunately, the committees were too short sighted to not envision passing negative bounds. Had they been, then 0x8... would have been the best candidate to use.

Jim Dempsey

0 Kudos
Reply