PGI User Forum
 SearchSearch   MemberlistMemberlist     RegisterRegister   ProfileProfile    Log inLog in 

CUDA-x86.

casting derived-type data with allocatable components

 
Post new topic   Reply to topic    PGI User Forum Forum Index -> Programming and Compiling
View previous topic :: View next topic  
Author Message
delete000



Joined: 03 Jul 2012
Posts: 4

PostPosted: Wed Jul 04, 2012 3:02 am    Post subject: casting derived-type data with allocatable components Reply with quote

Here's a code that attempts to do what the title says:

Code:
module Increments

  TYPE :: structure
    real s
    integer q
    real, allocatable :: flt1d(:)
  END TYPE structure

contains

  subroutine IncrementAndPrintReal(data)
    character(len=1) :: data(:)
    real             :: r
    r = transfer(data, r)
    r = r + 1.0
    print *,r
    data = transfer(r, data)
  end subroutine

  subroutine IncrementAndPrintInteger(data)
    character(len=1) :: data(:)
    integer          :: i   
    i = transfer(data, i)
    i = i + 1
    print *,i
    data = transfer(i, data)
  end subroutine

  subroutine IncrementTenTimes(incrFunc, data)
    character(len=1) :: data(:)
    integer :: i
    interface
      subroutine incrFunc(data)
        character(len=1) :: data(:)
      end subroutine
    end interface
    do i = 1, 10
      call incrFunc(data)
    enddo   
  end subroutine

  subroutine IncrementAndPrintStructure(data)
    character(len=1) :: data(:)
    type(structure) :: t0
    t0 = transfer(data, t0)
    print *, t0%flt1d
    t0%flt1d = t0%flt1d(1) + 1
    print*
    data = transfer(t0, data)
  end subroutine

end module

program main
  use Increments
  character(len=1), allocatable :: data(:)
  integer                       :: lengthData
  real                          :: r = 5.0
  integer                       :: i = 10
  type(structure)               :: t

  t%s = 1
  t%q = 2
  allocate(t%flt1d(11))
  t%flt1d = 3

  lengthData = size(transfer(r, data))
  allocate(data(lengthData))
  data = transfer(r, data)
  call IncrementTenTimes(IncrementAndPrintReal, data)
  deallocate(data)

  lengthData = size(transfer(i, data))
  allocate(data(lengthData))
  data = transfer(i, data)
  call IncrementTenTimes(IncrementAndPrintInteger, data)
  deallocate(data)

  lengthData = size(transfer(t, data))
  allocate(data(lengthData))
  data = transfer(t, data)
  call IncrementTenTimes(IncrementAndPrintStructure, data)
  deallocate(data)

end program


And here are the results for a few compilers:

Code:
ifort (v11.1 and v12.1.5):
==============


   6.000000   
   7.000000   
   8.000000   
   9.000000   
   10.00000   
   11.00000   
   12.00000   
   13.00000   
   14.00000   
   15.00000   
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
   3.000000       3.000000       3.000000       3.000000       3.000000   
   3.000000       3.000000       3.000000       3.000000       3.000000   
   3.000000   

  0.0000000E+00  0.0000000E+00   4.000000       4.000000       4.000000   
   4.000000       4.000000       4.000000       4.000000       4.000000   
   4.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   

  0.0000000E+00  0.0000000E+00   1.000000       1.000000       1.000000   
   1.000000       1.000000       1.000000       1.000000       1.000000   
   1.000000   



gfortran (gcc version 4.4.3):
=============================


   6.0000000   
   7.0000000   
   8.0000000   
   9.0000000   
   10.000000   
   11.000000   
   12.000000   
   13.000000   
   14.000000   
   15.000000   
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
   3.0000000       3.0000000       3.0000000       3.0000000       3.0000000       3.0000000       3.0000000       3.0000000       3.0000000       3.0000000       3.0000000   

  1.82795013E-38   0.0000000       4.0000000       4.0000000       4.0000000       4.0000000      1.54142831E-44  1.12103877E-44  2.80259693E-45   4.0000000       4.0000000   

*** glibc detected *** ./tr: double free or corruption (fasttop): 0x0000000000c70b20 ***
======= Backtrace: =========
/lib/libc.so.6(+0x77806)[0x7f9fb0e59806]
/lib/libc.so.6(cfree+0x73)[0x7f9fb0e600d3]
./tr[0x4010af]
./tr[0x401175]
./tr[0x40262e]
./tr[0x4026ea]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f9fb0e00c4d]
./tr[0x400a59]
======= Memory map: ========
00400000-00403000 r-xp 00000000 00:16 123                                /home/stefanos/Documents/dig/progs/other/transfer/tr
00602000-00603000 r--p 00002000 00:16 123                                /home/stefanos/Documents/dig/progs/other/transfer/tr
00603000-00604000 rw-p 00003000 00:16 123                                /home/stefanos/Documents/dig/progs/other/transfer/tr
00c70000-00c91000 rw-p 00000000 00:00 0                                  [heap]
7f9fac000000-7f9fac021000 rw-p 00000000 00:00 0
7f9fac021000-7f9fb0000000 ---p 00000000 00:00 0
7f9fb0de2000-7f9fb0f5c000 r-xp 00000000 08:01 5512795                    /lib/libc-2.11.1.so
7f9fb0f5c000-7f9fb115b000 ---p 0017a000 08:01 5512795                    /lib/libc-2.11.1.so
7f9fb115b000-7f9fb115f000 r--p 00179000 08:01 5512795                    /lib/libc-2.11.1.so
7f9fb115f000-7f9fb1160000 rw-p 0017d000 08:01 5512795                    /lib/libc-2.11.1.so
7f9fb1160000-7f9fb1165000 rw-p 00000000 00:00 0
7f9fb1165000-7f9fb117b000 r-xp 00000000 08:01 5505258                    /lib/libgcc_s.so.1
7f9fb117b000-7f9fb137a000 ---p 00016000 08:01 5505258                    /lib/libgcc_s.so.1
7f9fb137a000-7f9fb137b000 r--p 00015000 08:01 5505258                    /lib/libgcc_s.so.1
7f9fb137b000-7f9fb137c000 rw-p 00016000 08:01 5505258                    /lib/libgcc_s.so.1
7f9fb137c000-7f9fb13fe000 r-xp 00000000 08:01 5505028                    /lib/libm-2.11.1.so
7f9fb13fe000-7f9fb15fd000 ---p 00082000 08:01 5505028                    /lib/libm-2.11.1.so
7f9fb15fd000-7f9fb15fe000 r--p 00081000 08:01 5505028                    /lib/libm-2.11.1.so
7f9fb15fe000-7f9fb15ff000 rw-p 00082000 08:01 5505028                    /lib/libm-2.11.1.so
7f9fb15ff000-7f9fb16ea000 r-xp 00000000 08:01 787983                     /usr/lib/libgfortran.so.3.0.0
7f9fb16ea000-7f9fb18e9000 ---p 000eb000 08:01 787983                     /usr/lib/libgfortran.so.3.0.0
7f9fb18e9000-7f9fb18ea000 r--p 000ea000 08:01 787983                     /usr/lib/libgfortran.so.3.0.0
7f9fb18ea000-7f9fb18eb000 rw-p 000eb000 08:01 787983                     /usr/lib/libgfortran.so.3.0.0
7f9fb18eb000-7f9fb18ec000 rw-p 00000000 00:00 0
7f9fb18ec000-7f9fb190c000 r-xp 00000000 08:01 5512780                    /lib/ld-2.11.1.so
7f9fb1ad9000-7f9fb1add000 rw-p 00000000 00:00 0
7f9fb1b09000-7f9fb1b0b000 rw-p 00000000 00:00 0
7f9fb1b0b000-7f9fb1b0c000 r--p 0001f000 08:01 5512780                    /lib/ld-2.11.1.so
7f9fb1b0c000-7f9fb1b0d000 rw-p 00020000 08:01 5512780                    /lib/ld-2.11.1.so
7f9fb1b0d000-7f9fb1b0e000 rw-p 00000000 00:00 0
7fff5e340000-7fff5e356000 rw-p 00000000 00:00 0                          [stack]
7fff5e396000-7fff5e397000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted



pgfortran (v12.5):
==================


    6.000000   
    7.000000   
    8.000000   
    9.000000   
    10.00000   
    11.00000   
    12.00000   
    13.00000   
    14.00000   
    15.00000   
           11
           12
           13
           14
           15
           16
           17
           18
           19
           20
    3.000000        3.000000        3.000000        3.000000     
    3.000000        3.000000        3.000000        3.000000     
    3.000000        3.000000        3.000000   

    4.000000        4.000000        4.000000        4.000000     
    4.000000        4.000000        4.000000        4.000000     
    4.000000        4.000000        4.000000   

    5.000000        5.000000        5.000000        5.000000     
    5.000000        5.000000        5.000000        5.000000     
    5.000000        5.000000        5.000000   

    6.000000        6.000000        6.000000        6.000000     
    6.000000        6.000000        6.000000        6.000000     
    6.000000        6.000000        6.000000   

    7.000000        7.000000        7.000000        7.000000     
    7.000000        7.000000        7.000000        7.000000     
    7.000000        7.000000        7.000000   

    8.000000        8.000000        8.000000        8.000000     
    8.000000        8.000000        8.000000        8.000000     
    8.000000        8.000000        8.000000   

    9.000000        9.000000        9.000000        9.000000     
    9.000000        9.000000        9.000000        9.000000     
    9.000000        9.000000        9.000000   

    10.00000        10.00000        10.00000        10.00000     
    10.00000        10.00000        10.00000        10.00000     
    10.00000        10.00000        10.00000   

    11.00000        11.00000        11.00000        11.00000     
    11.00000        11.00000        11.00000        11.00000     
    11.00000        11.00000        11.00000   

    12.00000        12.00000        12.00000        12.00000     
    12.00000        12.00000        12.00000        12.00000     
    12.00000        12.00000        12.00000   


The PGI compiler shows the desired behaviour, but the code is clearly non-trivial. I am trying to understand why this is so and what the standard-conforming behaviour is.

On a more general note, I was wondering it there is any other way to pass derived-type variables with allocatable components to a procedure, without the procedure knowing the type definition.

Can anyone help?
Back to top
View user's profile
mkcolg



Joined: 30 Jun 2004
Posts: 6129
Location: The Portland Group Inc.

PostPosted: Thu Jul 05, 2012 3:22 pm    Post subject: Reply with quote

Hi delete000,

We took a look at your code and didn't find anything illegal. Though, you may investigate to instead use unlimited polymorphic objects ( e.g., class(*) ) to allow them to pass an object to a procedure without the procedure knowing what the type is. This can also work for allocatables.

For example
Code:
subroutine foo(this)
class(*), allocatable :: this
:
end subroutine


Though, you may want to determine the type using the "select type" construct

For example,
Code:

subroutine foo(this)
class(*), allocatable :: this

select type(this)
type is (integer)
    ! integer specific code
type is(real)
    ! real specific code
type is (complex)
   ! complex specific code
class is (my_type)
   ! code for derived type "my_type" and all of its type extensions
class default
   ! default case - any other type executes this code
end select

end subroutine


For additional examples and more details about these constructs, please take a look at the PGInsider articles Object-Oriented Programming in Fortran 2003 Part 1: Code Reusability and Object-Oriented Programming in Fortran 2003 Part 2: Data Polymorphism.

Best Regards,
Mat
Back to top
View user's profile
delete000



Joined: 03 Jul 2012
Posts: 4

PostPosted: Sat Jul 07, 2012 6:00 am    Post subject: Reply with quote

Hi Mat,

thanks, this seems to be exactly what I'm looking for.

delete000
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    PGI User Forum Forum Index -> Programming and Compiling All times are GMT - 7 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © phpBB Group