- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider a function returning a parameterised derived type that depends on inputs to set its parameter length. Such a use seams the most logical way to use this feature. This example is part of some AD code I suspect many will attempt:
module Bar implicit none integer, parameter :: DP = 8 type Foo(n) integer, len :: n real(DP) :: v real(DP) :: d(n) end type contains function divide(a, b) result(c) type(Foo(*)), intent(in) :: a type(Foo(*)), intent(in) :: b type(Foo(a%n)) c c%v = a%v/b%v c%d = (a%d - a%v*b%d/b%v)/b%v end function subroutine divideSub(a, b, c) type(Foo(*)), intent(in) :: a type(Foo(*)), intent(in) :: b type(Foo(a%n)), intent(out) :: c c%v = a%v/b%v c%d = (a%d - a%v*b%d/b%v)/b%v end subroutine end module program test use Bar implicit none type (Foo(n=100)) :: x, y, z x%v = 1.0d0 x%v = 1.0d0 y%v = 2.0d0 y%d = 0.0d0 z = divide(x, y) call divideSub(x, y, z) end program
If gives:
1>------ Build started: Project: TestDerivedTypeCompilerCrash, Configuration: Debug Win32 ------
1>Compiling with Intel(R) Visual Fortran Compiler 16.0 [IA-32]...
1>Source1.f90
1>Bla\Bla\Source1.f90(42): error #6197: An assignment of different structure types is invalid.
1>Bla\Bla\Source1.f90(43): error #6633: The type of the actual argument differs from the type of the dummy argument.
1>compilation aborted for Bal\Bla\Source1.f90 (code 1)
1>
1>Build log written to "file://Bla\Bla\BuildLog.htm"
1>TestDerivedTypeCompilerCrash - 3 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The problem appears to arise because the return type of the function is not explicit and so can not be assumed to match the type of the local variable we assign it to. The same problem arises for a subroutine version with an intent(out) result.
The compiler must be intelligent enough to work through the function call to determine the implied result type but has not done so. With these severe limitations of the 16.0 compiler we have very little we can usefully do with parameterised derived types apart from declare a few just for fun. Will Intel attempt to fix this issue soon ?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may need a copy operator (principally to handle cases of different n values).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Andrew Smith wrote:
.. The compiler must be intelligent enough to work through the function call to determine the implied result type but has not done so. With these severe limitations of the 16.0 compiler we have very little we can usefully do with parameterised derived types apart from declare a few just for fun. Will Intel attempt to fix this issue soon ? ..
Welcome to the club in which you're a long-time member! I believe your case is similar to one or more of many issues involving PDTs that have already been reported to Intel for resolution. Hopefully Intel can fix all those issues soon to provide us with a most robust implementation of PDTs, for it is indeed a very valuable feature of the language.
In the meantime, a temporary workaround I suggest you try is assumed type dummy argument for c in the subroutine procedure; forget about the function procedure until the compiler becomes "intelligent enough":
subroutine divideSub(a, b, c) type(Foo(n=*)), intent(in) :: a type(Foo(n=*)), intent(in) :: b type(Foo(n=*)), intent(inout) :: c c%v = a%v/b%v c%d = (a%d - a%v*b%d/b%v)/b%v end subroutine
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
You may need a copy operator (principally to handle cases of different n values).
Jim Dempsey
I've not found it to help due to limitations in the current implementation of PDTs in Intel Fortran:
module Bar implicit none integer, parameter :: DP = 8 type Foo(n) integer, len :: n real(DP) :: v real(DP) :: d(n) end type interface assignment(=) module procedure assign_foo end interface contains function divide(a, b) result(c) type(Foo(*)), intent(in) :: a type(Foo(*)), intent(in) :: b type(Foo(n=a%n)) c c%v = a%v/b%v c%d = (a%d - a%v*b%d/b%v)/b%v end function subroutine divideSub(a, b, c) type(Foo(*)), intent(in) :: a type(Foo(*)), intent(in) :: b type(Foo(*)), intent(out) :: c !.. corrective action elided if length parameter of c is different c%v = a%v/b%v c%d = (a%d - a%v*b%d/b%v)/b%v end subroutine subroutine assign_foo( lhs, rhs ) type(Foo(*)), intent(out) :: lhs type(Foo(*)), intent(in) :: rhs !.. corrective action elided if length parameter of lhs is different lhs%v = rhs%v lhs%d = rhs%d end subroutine assign_foo end module
program test use Bar implicit none type (Foo(n=100)) :: x, y, z x%v = 1.0d0 x%v = 1.0d0 y%v = 2.0d0 y%d = 0.0d0 z = divide(x, y) call divideSub(x, y, z) end program
Compiling with Intel(R) Visual Fortran Compiler 16.0 [Intel(R) 64]... p.f90 p.f90(11): error #6197: An assignment of different structure types is invalid. compilation aborted for p.f90 (code 1)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will report this case to Development shortly and inquire about a general status/update on PDT related defects.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page