- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Compiler: Compiling with Intel® Fortran Compiler Classic 2021.2.0 [Intel(R) 64], Visual Studio
I have following method (bound procedure) which assigns a constant array to a matrix:
subroutine copy_matrix2(me,a)
implicit none type(matrix(*,*)), intent(inout) :: me
real, dimension(:), intent(in) :: a
integer(int64) :: i
integer, dimension(1:2) ::s
if(me%r*me%c /= size(a)) then
stop 'dimension mismatch'
end if
! s=shape(me%x)
me%x=transpose(reshape(a,shape(me%x)))
end subroutine copy_matrix2
The assignment works correctly if I use the variable s, but it fails to work correctly if I use directy shape(me%x) in the reshape function. It takes only the first two element of a and fills the matrix.
If I use this same statement, me%x=transpose(reshape(a,shape(me%x))),outside the method it works correctly.
The matrix type is defined as follows:
! matrix
type matrix (r,c,k)
integer(int64),len::r,c=r
integer,kind:: k=real32
real(k), dimension(1:r,1:c)::x
contains
private
generic,public :: assignment(=) => copy_matrix1 ,copy_matrix2
procedure :: copy_matrix1
procedure :: copy_matrix2
end type matrix
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@jkrzz wrote:
I just wanted to create a matrix class, as you would do in C++. Declarations are shorter and operator overloading and methods can be bound to the type. I just was surprised about the unexpected behavior of the reshape function occurring in a procedure bound method. So I want to know what is causing this weird behavior.
@jkrzz ,
It's good to see you are trying out the parameterized derived type (PDT) facility introduced starting Fortran 2003 back in 2004. A few quick comments:
- Please do post a reproducer of your code either at Intel OSC or here, as suggested by @Barbara_P_Intel .
- If you intend to spend some time with Fortran, please take a look at https://fortran-lang.org/ and also the Discourse there for all matters generally related to Fortran: https://fortran-lang.discourse.group/. See also some recent discussions involving matrix computations and a PDT example toward a simple-minded exponential operation in this thread.
- Toward your copy_matrix2 assignment, another workaround you can consider in case your source "data" in 'a' is contiguous is to make use of rank transformation using a local pointer:
subroutine copy_matrix2(me,a)
type(matrix(r=*,c=*,k=..)), intent(inout) :: me
real, contiguous, intent(in), target :: a(:)
integer(int64) :: i
real, contiguous, pointer :: x(:,:)
if (me%r*me%c /= size(a)) then
stop 'dimension mismatch'
end if
x(1:me%r,1:me%c) => a
me%x = x
end subroutine copy_matrix2
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why are you using a user defined type "matrix" that abstracts an array descriptor when Fortran's arrays are implemented using an array descriptor? IOW you can use SIZE(me,DIM=1), SIZE(me,DIM=2), LBOUND and UBOUND to obtain the particulars of the array.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just wanted to create a matrix class, as you would do in C++. Declarations are shorter and operator overloading and methods can be bound to the type. I just was surprised about the unexpected behavior of the reshape function occurring in a procedure bound method. So I want to know what is causing this weird behavior.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@jkrzz wrote:
I just wanted to create a matrix class, as you would do in C++. Declarations are shorter and operator overloading and methods can be bound to the type. I just was surprised about the unexpected behavior of the reshape function occurring in a procedure bound method. So I want to know what is causing this weird behavior.
@jkrzz ,
It's good to see you are trying out the parameterized derived type (PDT) facility introduced starting Fortran 2003 back in 2004. A few quick comments:
- Please do post a reproducer of your code either at Intel OSC or here, as suggested by @Barbara_P_Intel .
- If you intend to spend some time with Fortran, please take a look at https://fortran-lang.org/ and also the Discourse there for all matters generally related to Fortran: https://fortran-lang.discourse.group/. See also some recent discussions involving matrix computations and a PDT example toward a simple-minded exponential operation in this thread.
- Toward your copy_matrix2 assignment, another workaround you can consider in case your source "data" in 'a' is contiguous is to make use of rank transformation using a local pointer:
subroutine copy_matrix2(me,a)
type(matrix(r=*,c=*,k=..)), intent(inout) :: me
real, contiguous, intent(in), target :: a(:)
integer(int64) :: i
real, contiguous, pointer :: x(:,:)
if (me%r*me%c /= size(a)) then
stop 'dimension mismatch'
end if
x(1:me%r,1:me%c) => a
me%x = x
end subroutine copy_matrix2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your comments. I didn't know that an assignment of a pointer to an array results in a copy. Is a much better solution than 3 function calls. In the argument declaration for matrix I leave k out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found that when I put shape(me%x) between () in the reshape function, reshape(a,(shape(me%x))), it works correctly. This seems that the compiler has problems with interpreting the syntax without (), but only in a procedure bound function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you have a complete reproducer? If you have paid support, submit the reproducer as a bug. Otherwise, post that complete reproducer here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I attach two files main.f90 and lina2.f90. I main I assign 1,2,3,4 to a square matrix and the result printed is 1,2\n1,2. Putting shape between () in copy_matrix2 gives the correct result. In the answer of @FortranFan I found a better solution for assignment. But I am still curious to learn why shape behaves as it did in the bound procedure.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the simple reproducer! I filed a bug report, CMPLRIL0-34043. I'll let you know its progress to a fix.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Probably separate to the observed issue, note that:
- Type bound procedures of extensible types are required to have the passed argument be polymorphic. This requirement is a constraint in the standard - the compiler should have issued a diagnostic.
- The expression that specifies the default value for a type parameter of a type definition (the optional expression after the equals in a type-param-decl) is required to be a constant expression - again this is by constraint and a diagnostic should have been issued.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This was fixed and the fix will be available in the next release of the Intel Fortran Compiler 2021.7

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