# "Self referring" affectations

## "Self referring" affectations

Hi,

I am having problems with some code. I was able to reproduce what I think is a bug of the compiler on a simple example:
Program Strange

Implicit None

Type Link
Integer, Dimension(2) :: Next
End Type Link

Integer, Parameter :: N = 2
Integer :: i, j

Type(Link), Dimension(:,:), Pointer :: Perm
Integer, Dimension(2) :: Current

Allocate (Perm(N,N))

Print*, 'Spanned by indices'
Do i = 1, N**2
Perm(mod(i-1,N)+1, (i-1)/N+1)%Next = (/ Mod(i,N) + 1, Mod(i/N+1,N)+1/)
Write(*,100) mod(i-1,N)+1, (i-1)/N+1, Perm(mod(i-1,N)+1, (i-1)/N+1)%Next
End Do

Print*, 'Spanned as a cycle'
Current = (/1,1/)
Do i = 1, n**2
Write(*,100) Current, Perm(Current(1), Current(2))%Next
Current = Perm(Current(1), Current(2))%Next
End Do

100 Format( 2I3, '--->', 2I3)
DeAllocate (Perm)

End Program Strange

Here, Mat represent a permutation matrice. The output of the first loop is as follow:
Spanned by indices
1 1---> 2 2
2 1---> 1 1
1 2---> 2 1
2 2---> 1 2
Now, in the second loop, Map is spanned as a cycle. The expected output should then be:
1 1---> 2 2
2 2---> 1 2
1 2---> 2 1
2 1---> 1 1

However, Intel Fortran 7.0 returns
Spanned by indices
1 1---> 2 2
2 1---> 1 1
1 2---> 2 1
2 2---> 1 2

PGI returns the very same sequence, while an old version of the Fujitsu compiler (1.01), as well as sun 6.0 compiler return the correct answer:
Spanned by indices
1 1---> 2 2
2 1---> 1 1
1 2---> 2 1
2 2---> 1 2
Spanned as a cycle
1 1---> 2 2
2 2---> 1 2
1 2---> 2 1
2 1---> 1 1

I am misunderstanding the code I write, I am writing something illegal or are Intel and PGI compiler wrong?

Thanks,

Blaise

4 posts / 0 новое
Пожалуйста, обратитесь к странице Уведомление об оптимизации для более подробной информации относительно производительности и оптимизации в программных продуктах компании Intel.

I took a look at this - the Intel compiler is doing the assignment

Current = Perm(Current(1), Current(2))%Next

incorrectly. I suspect it is starting to update Current before fully evaluating the reference to Perm. The standard says that the right side of the assignment is to be fully evaluated before doing the assignment. Optimizing compilers need dependence analysis to determine whether or not a temporary copy needs to be made, or if it can do the assignment directly. My guess is that the Intel compiler is not getting the analysis right and by the time it goes to write Current(2), it has the wrong index.

Please report this through https://premier.intel.com/ and include my analysis.

Steve

Steve

You are absolutely right.

Indeed, the results displayed by the code I quoted are similar to that computed by the following modification in the last loop,
!!\$ Current = Perm(Current(1), Current(2))%Next
Current(1) = Perm(Current(1), Current(2))%Next(1)
Current(2) = Perm(Current(1), Current(2))%Next(2)
which is clearly different.

I don't have access to premier.intel.com yet.
I am actually purchasing the supported version of the compiler, mainly to report this bug, but it takes time...

Thanks,

Blaise

If you have the evaluation version, you do have access to Premier Support. Just register using the serial number sent to you.

Let me know if you have trouble doing this.

Steve

Steve