Resizing a polymorphic array

Resizing a polymorphic array

Bild des Benutzers dougf

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.

9 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Bild des Benutzers Steve Lionel (Intel)

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:

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
Steve
Bild des Benutzers dougf

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

Bild des Benutzers Steve Lionel (Intel)

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.

Steve
Bild des Benutzers Steve Lionel (Intel)

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.

Steve
Bild des Benutzers dougf

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

Bild des Benutzers dougf

Can you tell me where I can get a status of this issue (DPD200175268)?

Bild des Benutzers Steve Lionel (Intel)

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.

Steve
Bild des Benutzers Steve Lionel (Intel)

This is now fixed for a release later this year.

Steve

Melden Sie sich an, um einen Kommentar zu hinterlassen.