Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29284 Discussions

Problem with reshape in bound procedure

jkrzz
Beginner
3,181 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 III
3,087 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
3,165 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
3,159 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 III
3,088 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
3,069 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
3,154 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
3,097 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
3,067 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
3,015 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 III
3,051 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
2,577 Views

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

0 Kudos
Reply