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

Saving derived types to disk

hentall_maccuish__ja
New Contributor II
1,659 Views

Hello,

Is it possible to save a multi-layered derived type to disk as binary and read it back again and if so what should the file specifications be? I am getting what I can only interpret as undefined behaviour (e.g. sometime work and sometimes not) which is what lead me to this question. I have tried with and without ACCESS=’stream’. The derived type I want to save looks is in the example program below.

Thanks,

Jamie

    program scratch

    implicit none

    type sparseCOOType

        integer :: col

        integer :: row

        real :: val

    end type sparseCOOType

 

    type policyType

        type(sparseCOOType), allocatable :: COO(:)

    end type policyType

 

    type modelObjectsType

        ! real (kind=sp), allocatable :: V(:, :, :,:,:)

        !real (kind=sp), allocatable :: policy(:, :, :, :,:,:,:)

        type(policyType), allocatable :: policy(:,

        !real (kind=rk), allocatable :: u(:, :, :, :,:,:)

        !real (kind=rk), allocatable :: q(:, :, :, :,:)

        !real (kind=sp), allocatable :: EV(:, :, :,:,:)

    end type modelObjectsType

 

    type(modelObjectsType) :: model, model2

 

    allocate(model%policy(2,2))

    allocate(model%policy(1,1)%coo(1),model%policy(1,2)%coo(1),model%policy(2,1)%coo(1),model%policy(2,2)%coo(2))

 

    model%policy(1,1)%coo(1)%row = 1

    model%policy(1,1)%coo(1)%col = 1

    model%policy(1,1)%coo(1)%val = 1.0

 

    model%policy(1,2)%coo(1)%row = 1

    model%policy(1,2)%coo(1)%col = 2

    model%policy(1,2)%coo(1)%val = 1.0

 

    model%policy(2,1)%coo(1)%row = 2

    model%policy(2,1)%coo(1)%col = 1

    model%policy(2,1)%coo(1)%val = 1.0

 

    model%policy(2,2)%coo(1)%row = 2

    model%policy(2,2)%coo(1)%col = 2

    model%policy(2,2)%coo(1)%val = 0.5

 

    model%policy(2,2)%coo(2)%row = 1

    model%policy(2,2)%coo(2)%col = 1

    model%policy(2,2)%coo(2)%val = 0.5

   

    open (unit=201,form="unformatted", file='test', status='unknown', action='write') !ACCESS='stream'!recl=requiredl

    write (201)  model%policy !(:,ixaime,:,:,:)

    close( unit=201)

 

    deallocate(model%policy(1,1)%coo,model%policy(1,2)%coo,model%policy(2,1)%coo,model%policy(2,2)%coo)

    deallocate(model%policy)

 

    allocate(model2%policy(2,2))

    !allocate(model2%policy(1,1)%coo(1),model2%policy(1,2)%coo(1),model2%policy(2,1)%coo(1),model2%policy(2,2)%coo(2))

    open (unit=201,form="unformatted", file='test', status='unknown', action='read') !ACCESS='stream'

    read (201) model2%policy

    close( unit=201 )

    end program

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
1,640 Views

(I wrote and posted a long explanation - and it disappeared. Sigh...)

Short answer - your program is not valid Fortran because your types do not have user-defined derived type I/O procedures and have allocatable components. The compiler is not required to diagnose this, but it should have done so. I will file a support request about that.

You will need to write defined input/output procedures for both policyType and modelObjectsType that read or write their components in the proper order. The one for policyType will implicitly invoke the one for modelObjectsType.

Also, please use the code insert button to prevent code from being turned into emoji. Click the ... button and then the </> button, select Fortran as the language.

View solution in original post

0 Kudos
14 Replies
Steve_Lionel
Honored Contributor III
1,527 Views

This program violates the standard, though in a way that the standard does not require a compiler to diagnose.  

  • If a list item of derived type in an unformatted input/output statement is not processed by a defined input/output procedure (12.6.4.8), and if any subobject of that list item would be processed by a defined input/output procedure, the list item is treated as if all of the components of the object were specified in the list in component order (7.5.4.7); those components shall be accessible in the scoping unit containing the data transfer statement and shall not be pointers or allocatable.
  • If a derived-type list item is not processed by a defined input/output procedure and is not treated as a list of its individual components, all the subcomponents of that list item shall be accessible in the scoping unit containing the data transfer statement and shall not be pointers or allocatable.

(12.6.3p7)

The first bullet says that your derived type is not to be treated as a list of components because none of the components has a defined input/output procedure. The second bullet then says that none of the components may be pointer or allocatable.

I am disappointed that the compiler doesn't complain about this, and I will submit a support request asking that it does in the future.

The solution here is to write a defined input/output procedure for types PolicyType and ModelObjectsType that read or write each of the components in order. Note that the procedure for PolicyType will implicitly invoke the one for ModelObjectsType. 

I'll also note that the forum replaced some of your code with an emoji. To prevent that in the future, use the "insert code" button in the edit bar. You'll have to click on the ... to see it - it looks like </>.

Compare:

type(policyType), allocatable :: policy(:,

 

 

type(policyType), allocatable :: policy(:,:) 

 

 

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,641 Views

(I wrote and posted a long explanation - and it disappeared. Sigh...)

Short answer - your program is not valid Fortran because your types do not have user-defined derived type I/O procedures and have allocatable components. The compiler is not required to diagnose this, but it should have done so. I will file a support request about that.

You will need to write defined input/output procedures for both policyType and modelObjectsType that read or write their components in the proper order. The one for policyType will implicitly invoke the one for modelObjectsType.

Also, please use the code insert button to prevent code from being turned into emoji. Click the ... button and then the </> button, select Fortran as the language.

0 Kudos
Ron_Green
Moderator
1,623 Views

thanks for the bug report, Steve.  Bug ID is CMPLRLLVM-21856

0 Kudos
mecej4
Honored Contributor III
1,613 Views

Ron,

Please treat the arbitrary and high-handed deletion of longer posts as an urgent problem that Intel should address. Please pass this warning along to the manager of the forum software.

Steve L. had this happen to him in this thread. I have had my posts deleted several times since July, in this and in the MKL forum. I think that it is the new forum software that is to blame, because no human being could justify deleting even one of Steve's thousands of responses, which most of us have read for two decades. 

Does Intel really want to give the impression that it it is so callous as to treat thoughtful posts with contempt and delete them with no explanation? I submit to Intel's right to moderate, but please treat us as you would treat guests -- politely and with respect.

Ron, this plea is not directed to you personally. I just don't know whom else to complain to.

0 Kudos
Steve_Lionel
Honored Contributor III
1,610 Views

I do know whom to complain to and I will.

0 Kudos
hentall_maccuish__ja
New Contributor II
1,564 Views

Thank you I got this working by writing an I/O procedure as you suggested. I was looking for the code insert button but couldn't find it, knowing where it is I should find it next time. Having your response disappear must be extremely annoying. I got what you wrote to my inbox and will try and repost here for posterity (in two parts if needed).

hentall_maccuish__ja
New Contributor II
1,558 Views

Steve's original reply

"

This program violates the standard, though in a way that the standard does not require a compiler to diagnose.  

If a list item of derived type in an unformatted input/output statement is not processed by a defined input/output procedure (12.6.4.8), and if any subobject of that list item would be processed by a defined input/output procedure, the list item is treated as if all of the components of the object were specified in the list in component order (7.5.4.7); those components shall be accessible in the scoping unit containing the data transfer statement and shall not be pointers or allocatable. If a derived-type list item is not processed by a defined input/output procedure and is not treated as a list of its individual components, all the subcomponents of that list item shall be accessible in the scoping unit containing the data transfer statement and shall not be pointers or allocatable.

(12.6.3p7)

The first bullet says that your derived type is not to be treated as a list of components because none of the components has a defined input/output procedure. The second bullet then says that none of the components may be pointer or allocatable.

I am disappointed that the compiler doesn't complain about this, and I will submit a support request asking that it does in the future.

The solution here is to write a defined input/output procedure for types PolicyType and ModelObjectsType that read or write each of the components in order. Note that the procedure for PolicyType will implicitly invoke the one for ModelObjectsType. "

0 Kudos
Steve_Lionel
Honored Contributor III
1,528 Views

Excellent!

I have now added user derived type procedures to my list for future Doctor Fortran topics.

0 Kudos
JohnNichols
Valued Contributor III
1,514 Views

Capture.GIF(I wrote and posted a long explanation - and it disappeared. Sigh...)

Although the new website does have some form of save feature that if you do not post and come back it offers you the unsubmitted text.  Quite helpful. 

I am slowly starting to understand the User Interface, it is a bit like ending up in a Singapore Airport for 8 hours in a room with a lady who only speaks German -- amazing how fast you remember High School German -- 

0 Kudos
Steve_Lionel
Honored Contributor III
1,504 Views

I had completed the post and submitted it. I then edited it and saved the changes. It still disappeared.

0 Kudos
mecej4
Honored Contributor III
1,500 Views

My experience leads me to guess that the post deletion algorithm has the following as criteria that contribute to a decision to delete: (i) length of post (ii) number of edits and (iii) time intervals between edits.

In one case, I had posted a long response along with some code, and made two or three edits, following the last of which I received a "success" pop up. Next morning, I found that post gone without a clue that it had been there. 

0 Kudos
Ron_Green
Moderator
1,493 Views

I will bring this to the attention of the Khoros Forum support team. 

0 Kudos
mecej4
Honored Contributor III
1,486 Views

Thanks for passing along the forum complaints, Ron.

0 Kudos
Ron_Green
Moderator
1,460 Views

This appears to be a bug in the Khoros software - or a "feature": I am wondering if anti-spam filtering is being overly aggressive.  I'll see if there are records of posts that Khoros removed as suspect spam - we may have to teach this filter Fortran

0 Kudos
Reply