- 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