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

Bug Report: Incorrect application of elemental function on user defined type

Aidan_H_
Beginner
1,075 Views

 

 

I have an error with Intel Fortran incorrectly applying an elemental function to a user defined type.

module quart

  implicit none
  type quaternion
     ! q(4) = (w, x, y, z) where w is the scalar part
     real :: q(4)
     ! Flags to tell us if we want to keep the quaternion unitised, and
     ! also if the quaternion represents an improper rotation (rotation + inversion)
     logical :: unit
     logical :: improper
  end type quaternion
contains

  elemental subroutine pnormalise_quaternion(q)

    ! Normalise the quaternion by dividing the quaternion by it's
    ! 'reduced norm'

    type (quaternion), intent(inout) :: q

    q%q = q%q / (pnormq(q))

  end subroutine pnormalise_quaternion

  elemental subroutine enormalise_quaternion(q)

    ! Normalise the quaternion by dividing the quaternion by it's
    ! 'reduced norm'

    type (quaternion), intent(inout) :: q

    q%q = q%q / (enormq(q))

  end subroutine enormalise_quaternion

  pure real function pnormq(q)

    ! The 'reduced norm' of a quaternion is just the square root of the
    ! arithmetic sum of the squares of it's elements

    real :: normq
    type (quaternion), intent(in) :: q

    pnormq = sqrt(sum(q%q**2))

  end function pnormq

  elemental real function enormq(q)

    ! The 'reduced norm' of a quaternion is just the square root of the
    ! arithmetic sum of the squares of it's elements

    real :: normq
    type (quaternion), intent(in) :: q

    enormq = sqrt(sum(q%q**2))

  end function enormq
end module quart

program test
    use quart

    type(quaternion) :: q(2)

    q(1)%q = [1,2,2,4]
    q(2)%q = [1,0,0,0]

    call pnormalise_quaternion(q)

    write(*,*) q(1)%q
    write(*,*) q(2)%q

    q(1)%q = [1,2,2,4]
    q(2)%q = [1,0,0,0]

    call enormalise_quaternion(q)

    write(*,*) q(1)%q
    write(*,*) q(2)%q


end program

Compiled and run like so:

fort -o quaternion quaternion.f90​

./quaternion 
  0.2000000      0.4000000      0.4000000      0.8000000     

 1.000000      0.0000000E+00  0.0000000E+00  0.0000000E+00

  0.2000000      0.4079085      0.4449238      0.9875987     

 1.000000      0.0000000E+00  0.0000000E+00  0.0000000E+00

The top two lines are correct (from the pure routine), and the third line is erroneous.

Stepping through the code with gdb it seems that enormq is being 4 times for each quaternion q, once for each element of q%q.

 

0 Kudos
3 Replies
Aidan_H_
Beginner
1,075 Views

I meant to add, the same result was obtained with the following compilers

ifort -V
Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.1.2.183 Build 20130514
Copyright (C) 1985-2013 Intel Corporation.  All rights reserved.

and

ifort -V
Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0.0.090 Build 20140723
Copyright (C) 1985-2014 Intel Corporation.  All rights reserved.

but correct results were obtained with gfortran 5.2.0

 

0 Kudos
FortranFan
Honored Contributor III
1,075 Views

The latest version of Intel Fortran compiler - 16, update 1 - seems to give results as expected.

0 Kudos
Aidan_H_
Beginner
1,075 Views

 

FortranFan wrote:

The latest version of Intel Fortran compiler - 16, update 1 - seems to give results as expected.

Great. Thanks for the feedback.

0 Kudos
Reply