water
water

Reputation: 21

There seems to be data loss upon assignment in Fortran

I have a problem after assigning values. There seems to be some data loss upon assignment. Unfortunately, it is difficult to reproduce the problem in a simple example. Let me give an overview of the problem.

I have a complex derived type (say, emulator_sp) containing several components, including an single-precision allocatable coarray. I can copy values from one instance of the type to another using a custom subroutine (copy_emulator) that has been checked to work (e.g., all components of the original instance and of its copy are equal).

Furthermore, I have the following (Example 0):

type(emulator_sp) :: I1
call do_some_things(I1,...)

Here is where the bug comes: Example 1

type(emulator_sp) :: I1, I2
call copy_emulator(I2, from=I1)
call do_some_things(I2,...)

The results of Example 1 and Example 0 are different. Now, it gets more interesting than that (Example 2):

type(emulator_sp) :: I1, I2,I3
call copy_emulator(I2, from=I1)
call copy_emulator(I3, from=I2)
call do_some_things(I3,...)

The results of Example 2 are the same as the results of Example 1 - but both different from the output of Example 0.

These are the type definition and the copy subroutine (as you can see, there is nothing here that, in my view, can cause the problem)

  type emulator_sp
     real, allocatable                        :: pars(:,:,:,:)[:]
     character(128), dimension(3), private    :: state_var_names 
     character(128), dimension(5), private    :: forc_var_names 
     logical                                  optimized
     integer, dimension(2)                    :: train_yrs
     character(10)                            :: parnames(15)
     character(128)                           :: parunits(15)
  end type emulator_sp

  ! To copy one emulator to another
  subroutine copy_emulator(to, from)

    implicit none
    type(emulator_sp), intent(inout) :: to
    type(emulator_sp), intent(in)    :: from

    integer :: shp(4)

    if (allocated(to%pars)) deallocate(to%pars)
    if (allocated(from%pars)) then
       shp = shape(from%pars)
       allocate(to%pars(shp(1), shp(2), shp(3), shp(4))[*])
       to%pars = from%pars
    end if
    to%state_var_names = from%state_var_names
    to%forc_var_names  = from%forc_var_names
    to%optimized       = from%optimized
    to%train_yrs       = from%train_yrs
    to%parnames        = from%parnames
    to%parunits        = from%parunits    

  end subroutine copy_emulator

I would appreciate any thoughts:) Thank you. (If you think my compiler is too old I would budge and urge our team to update one).

ifort (IFORT) 19.0.3.199 20190206 Copyright (C) 1985-2019 Intel Corporation. All rights reserved.

Upvotes: 0

Views: 49

Answers (0)

Related Questions