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

Resizing a polymorphic array

dougf
Beginner
1,070 Views
I would like to dynamically increase the size of a polymorphic array (say, from n to n+1) while retaining the lower n array values and making a copy of the nth value in the n+1 slot. I've discovered that I can't make a temporary clone of the array, deallocate and resize/reallocate the original array, and use intrinsic assignment to copy individual array components from the temporary array into the newly resized array (an error #8304 results).

Any ideas about how I might accomplish this?

I am using version 12.1.
0 Kudos
8 Replies
Steven_L_Intel1
Employee
1,070 Views
Error 8304 is "In an intrinsic assignment statement, variable shall not be polymorphic". This is a new feature in Fortran 2008 which we do not yet support.

The key to what you want is to use ALLOCATE with SOURCE= being a RESHAPE of the original array plus padding. Here's a contrived example:

[fortran]type base
integer i
end type base

type, extends(base) :: ext
real r
end type ext

class(base), allocatable :: arr(:), tmp(:)

allocate (ext::arr(3))
select type (arr)
type is (ext)
do i=1,3
arr(i)%i = i
arr(i)%r = real(i)
end do
end select

allocate(tmp(4),source=reshape(arr,[4],pad=[arr(3)]))


call move_alloc (from=tmp, to=arr)

do i=1,4
print *, arr(i)%i
end do
end
[/fortran]
0 Kudos
dougf
Beginner
1,070 Views
Steve,
Thanks. I tried this out and thought I had success, but then discovered what looks like a secondary problem. Following is some test code. The value of i prints as 1 before move_alloc and something resembling an uninitialized value after. Apparently the value of i is lost in the move.


type :: t_1
integer :: i
end type

type :: t
type(t_1), allocatable :: t_1_v
end type

type(t), dimension(:), allocatable :: x
type(t), dimension(:), allocatable :: y

allocate(y(1))

allocate(y(1)%t_1_v)

y(1)%t_1_v%i = 1

allocate(x(2), source=reshape(y,[2],pad=[y(1)]))

print *, y(1)%t_1_v%i
call move_alloc(x, y)
print *, y(1)%t_1_v%i


0 Kudos
Steven_L_Intel1
Employee
1,070 Views
Ah, that's a somewhat different thing. I can see the bug but am not sure yet if it is in the ALLOCATE(SOURCE=) or the MOVE_ALLOC. Let me play with this some more. The basic issue is that the t_1_v subcomponents are getting deallocated when they shouldn't be, or the ALLOCATE is failing to copy them properly.
0 Kudos
Steven_L_Intel1
Employee
1,070 Views
The actual problem is that the RESHAPE is not allocating new storage for the value it gets from Y(1) and is simply reusing the existing storage for Y(1)%t_1_V. Later, when the MOVE_ALLOC is done, the old Y is deallocated and the value goes along with it. I have escalated this as issue DPD200175268, but I suspect it is actually the same issue as a previously reported problem in a different context. Even if you rewrite it as this:

allocate(x(2))
x = reshape(y,[2],pad=[t(t_1(2))])

the same problem occurs.
0 Kudos
dougf
Beginner
1,070 Views
Steve,
Thanks for digging into this. Unfortunately, it's going to cause us some trouble until it's fixed, so I'll keep an eye out for resolution of the issue.
Doug
0 Kudos
dougf
Beginner
1,070 Views
Can you tell me where I can get a status of this issue (DPD200175268)?
0 Kudos
Steven_L_Intel1
Employee
1,070 Views
You would get it here. I have asked the developer, to whom this issue is assigned, for an update. I reran the test and see the issue is still not fixed.
0 Kudos
Steven_L_Intel1
Employee
1,070 Views

This is now fixed for a release later this year.

0 Kudos
Reply