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

Problem with reshape in bound procedure

jkrzz
Beginner
2,018 Views

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

0 Kudos
1 Solution
FortranFan
Honored Contributor II
1,924 Views
@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:

  1. Please do post a reproducer of your code either at Intel OSC or here, as suggested by @Barbara_P_Intel .
  2. 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.
  3.  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

 

View solution in original post

10 Replies
jimdempseyatthecove
Honored Contributor III
2,002 Views

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

0 Kudos
jkrzz
Beginner
1,996 Views

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. 

0 Kudos
FortranFan
Honored Contributor II
1,925 Views
@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:

  1. Please do post a reproducer of your code either at Intel OSC or here, as suggested by @Barbara_P_Intel .
  2. 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.
  3.  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

 

jkrzz
Beginner
1,906 Views

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.

0 Kudos
jkrzz
Beginner
1,991 Views

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. 

0 Kudos
Barbara_P_Intel
Employee
1,934 Views

Do you have a complete reproducer?  If you have paid support, submit the reproducer as a bug.  Otherwise, post that complete reproducer here.

 

0 Kudos
jkrzz
Beginner
1,904 Views

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.

0 Kudos
Barbara_P_Intel
Employee
1,852 Views

Thank you for the simple reproducer!  I filed a bug report, CMPLRIL0-34043.  I'll let you know its progress to a fix.

 

0 Kudos
IanH
Honored Contributor II
1,888 Views

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.
0 Kudos
Devorah_H_Intel
Moderator
1,414 Views

This was fixed and the fix will be available in the next release of the Intel Fortran Compiler 2021.7 

0 Kudos
Reply