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

Allocating in a different module / Passing a derived typ

dalmo
Beginner
503 Views

Hello:

I'm creating a module to deal with time series data (mdlTS). I want it to take care of file reading, perform necessary allocations,anddefine,fill, and return astructure with the data. Because I must deal with several files, I want to pass the storage structure to the routine that reads the file header and allocates storage, and to the routine that reads chunks of data from the file.

The storage structures (type(tTimeSeries) in the example) are inside another module (mdlSimul), to give access to other simulation routines. Although no errors are reported, it does not work. Somehow when the type TimeSeries is passed to the allocation function, its contents get changed (maybe because of undefined pointers?).

ItDID work, however, when type(tTimeSeries) :: ts1 was declared in the routine that calls the allocation/filling routines. Why didit stop working when I moved ts1 to the mdlSimul module? (the debugger does notshow it correctly, but the results were fine.)

Unless there's a solution, I'll have to redesign everything, so suggestions welcome!

Thanks in advance for any help...

Here's a much simplified version that illustrates the problem:

PROGRAM

TEST

use mdlSimul

use mdlTS

call InitTS

END

PROGRAM TEST

!===========================

MODULE

mdlSimul

use mdlTS

implicit none

! If ts1 is accessed thru USE, it does not work

TYPE(tTimeSeries) :: ts1

CONTAINS

SUBROUTINE

InitTS

! But it works if ts1 is declared here

!TYPE(tTimeSeries) :: ts1

call TSAlloc( ts1 )

call TSFill( ts1 )

! Timeset(1) should have values 11, 12, 13, 101, 102, 103, 1001, 1002, 1003

! Timeset(2) should have values 21, 22, 23, 201, 202, 203, 2001, 2002, 2003

END SUBROUTINE

InitTS

END MODULE

mdlSimul

!===========================

MODULE

mdlTS

TYPE tTimeSet

SEQUENCE

REAL, POINTER :: X(:), Y(:)

REAL, POINTER :: Value(:) => NULL()

END TYPE tTimeSet

TYPE tTimeSeries

SEQUENCE

INTEGER :: NumTimesets, NumSamples

TYPE(tTimeSet), POINTER :: Timesets(:) => NULL()

END TYPE tTimeSeries

CONTAINS

SUBROUTINE

TSAlloc(TimeSeries)

implicit none

TYPE(tTimeSeries) :: TimeSeries

! test values (would come from TS file header)

integer, parameter :: nTimesets = 2

integer, parameter :: nSamples = 3

integer i, j, iStat

TimeSeries%NumTimesets = nTimesets

TimeSeries%NumSamples = nSamples

! Allocate storage structure

allocate(TimeSeries%Timesets(TimeSeries%NumTimesets))

do i=1,TimeSeries%NumTimesets

allocate(TimeSeries%Timesets(i)%Value(TimeSeries%NumSamples), STAT=iStat)

allocate(TimeSeries%Timesets(i)%X(TimeSeries%NumSamples), STAT=iStat)

allocate(TimeSeries%Timesets(i)%Y(TimeSeries%NumSamples), STAT=iStat)

!Just fill with -1

do j=1,TimeSeries%NumSamples

TimeSeries%Timesets(i)%Value(j) = -1.0

TimeSeries%Timesets(i)%X(j) = -1.0

TimeSeries%Timesets(i)%Y(j) = -1.0

enddo

enddo

return

END SUBROUTINE

TSAlloc

!-----------------------------------

SUBROUTINE

TSFill(TimeSeries)

implicit none

TYPE(tTimeSeries) :: TimeSeries

integer i, j

! test values (real ones would come from a section in the TS file)

! Fill structure

do i=1,TimeSeries%NumTimesets

do j=1,TimeSeries%NumSamples

TimeSeries%Timesets(i)%Value(j) = i*10 + j

TimeSeries%Timesets(i)%X(j) = i*100 + j

TimeSeries%Timesets(i)%Y(j) = i*1000 + j

enddo

enddo

return

END SUBROUTINE

TSFill

END MODULE

mdlTS

0 Kudos
4 Replies
Steven_L_Intel1
Employee
503 Views
What exactly do you mean by "doesn't work"? Perhaps you mean "can't view in the debugger"? If so, it is a known problem that host-associated variables cannot be viewed in the debugger.

What you can do in this case, since variable ts1 is a module variable, is go to the Watch window and type in:

mdlsimul::ts1

This will allow you to view the variable no matter where you are.

If you mean that the program executes incorrectly, your test program does not demonstrate that.
0 Kudos
dalmo
Beginner
503 Views

Steve:

You're right. Apparently my test program outputs correct results. It is the debugger that gets confused (and in turn got me confused!). On my machine, for this test case, the debugger shows everything correctly when ts1 is declared in the subroutine (it shows in "Locals"), but when ts1 is in the module, even using mldSimul::ts1 in the watch window, the arrays are shown as scalars, filledwith some tiny numbers (garbage).

I think it's the first time I see problems when the Watch window is used. I could see the contents, though,by setting up a local pointer tots1. That should help with debugging until ivf10 fixes these debugger problems!

This means my "real" module must have a different problem, because it does not allocate correctly and crashes.

Thanks for taking the time for testing and the prompt reply.

Dalmo

0 Kudos
jimdempseyatthecove
Honored Contributor III
503 Views

Dalmo,

In circumstances where the debugger has problems referencing a variable I insert conditional compilation code that for the debug configuration inserts into thesubrouting a local pointer to the object of interest then in the code section a conditional compile section that points the pointer at the object of interest. Then from anywhere inside the subroutine (after pointer set/reset) I have a convienent means to reference the variable.

Steve, I also have problems in trying to view locally declared variables that have SAVE attribute when compiled for OpenMP. Scoping the variable to the routine name or compile file namedoes not work. And the Dissassembly window shows only the hex address (i.e. not symbol+offset). So I am unable to descern the scoping text to apply to the variable name.

Jim

0 Kudos
Steven_L_Intel1
Employee
503 Views
Jim,

Please submit a problem report about the OpenMP issue along with a test case.
0 Kudos
Reply