Welcome to Intel® Software Network Quick Login | Join | Help |
Search in Intel® Software Network Forums
in Go

Private allocatable arrays inside subroutine in parallel region.

Last post 05-06-2008, 5:38 AM by Steve Lionel. 5 replies.
Sort Posts: Previous Next
 05-04-2008, 9:38 PM 30254080  

Private allocatable arrays inside subroutine in parallel region.

I was searching forum but didn’t find any similar problem.
I am having a problem with parallelizing some code. 
It seems to be according to spec but still causes errors. 
I have parallel do loop which has several small allocation and 
deallocation of arrays which is private to each thread, and subroutine 
call, so I would like to use that arrays inside subroutine, but looks 
like it can’t see that arrays are allocated and gives such error: 
 
forrtl: severe <408>: fort: <2>: Subscript #3 of the array GLOBAL has 
value 1 which is greater than the upper bound of -1.
 
Here is the sample code which demonstrates this problem. 

module variables

   

    integer :: row, col

    integer :: omp_threads_id, omp_num_of_nodes 

    real*8, allocatable, dimension ( : ) :: GLOBAL ( :, :, : )

    real*8, allocatable, dimension ( : ) :: LOCAL( :, : ) 

end module variables
 

    program openmp

    use variables

    use sublocal

    use omp_lib

   

    implicit none

   

    print*, '----------------------------------------------'     

    omp_num_of_nodes = omp_get_num_procs()

    call omp_set_num_threads( omp_num_of_nodes )   

    print*, 'Number of threads available: ', omp_num_of_nodes

 

!$omp parallel

    omp_threads_id = omp_get_thread_num()

    print*, 'Thread number: ', omp_threads_id, 'responded.'

!$omp end parallel  

    print*, '----------------------------------------------'

 

!$omp parallel default(shared)

!$omp do private(row, col, GLOBAL, LOCAL) 

    do row=1, 10

        allocate(GLOBAL(2, 10, 10))

        GLOBAL = 0

 

        do col=1, 10

        omp_threads_id = omp_get_thread_num()

        call sub

        print*, GLOBAL(1, row, col), omp_threads_id, row, col

        end do

        deallocate(GLOBAL)

    end do

!$omp end do   

!$omp end parallel   

 

 

    call system("PAUSE")

 

    end program openmp

 

 

module sublocal

use variables

implicit none

contains

   

    subroutine sub

    integer :: i, j

    do i = 1, 2

    allocate(LOCAL(2, 2))

    LOCAL = 0

        do j = 1, 2

        LOCAL(i, j) = i+j*4

        GLOBAL(1, i, j) = LOCAL(i, j)

       

        print*, GLOBAL(1, i, j)

        end do       

    deallocate(LOCAL) 

    end do

        print*, 'Hello world.'

       

    end subroutine sub

end module sublocal 

So my question is what is happening with private allocatable array when it goes inside subroutine?

I don’t know how helpful will be this, but I use Intel Visual Fortran Compiler 9.1 Professional with Microsoft Visual Studio 2005 Professional, and I have Core 2 Duo processor. OS is Windows Vista Ultimate.

Any help will be appreciated.

 
 05-05-2008, 12:04 AM 30254088 in reply to 30254080  

Re: Private allocatable arrays inside subroutine in parallel region.

I tried to pass array as an argument that all threads will know address of any such object, so that they may access the original data and not local copies. It runs but my array has wrong numbers.

But since GLOBAL is private, each thread should have its own local copy. Hence, we do not need to pass in an address in this case. But it’s not working as it should.

 

 
 05-05-2008, 1:38 AM 30254093 in reply to 30254080  

Re: Private allocatable arrays inside subroutine in parallel region.

If you want LOCAL to be local to sub, why not put the declaration in sub?  I'm no expert, but placing it in the module as you have seems to make it global.

Gib
 
 05-05-2008, 7:28 AM 30254103 in reply to 30254093  

Re: Private allocatable arrays inside subroutine in parallel region.

My bad code above doesn’t have exactly everything I wanted to do. I need to store some values from the main program into array which is private to each thread and then use it inside subroutine, after that get results back to main program. I have one big 3 dimensional matrix which store local elements inside, each local element can be calculated separately since they store in different location of the global array, for example GLOBAL_MESH (LocalElementNumber, row, col) so I can store element number 1 in LOCAL(row, col)  and calculated and store results back to GLOBAL_MESH.

By declaring array private inside subroutine will create local copy of array which doesn’t have information which I need from main program. Yes you are right they become global so how can I change that, and I wonder whether it is even OK ("legal") to put a private variable in a module?

I am concerned with the following statement in OpenMP:

2.6.3 Data environment rules

...

7.... Common blocks and modules in called routines in the dynamic extent of a parallel region always have an implicit SHARED attribute, unless they are THREADPRIVATE common blocks.

It seems to me, any variables defined in the data segments of Fortran 90 MODULEs would be limited to be SHARED.

So even if I declare them threadprivate, it gives me allocation error. Like this:


!$omp parallel default(shared)

!$threadprivate(/GLOBAL/, /LOCAL/)  

!$copyin(/GLOBAL/,LOCAL)

!$omp do private(row, col)

    do row=1, 2

        allocate(GLOBAL(2, 2, 2)) !forrtl: severe<151>: allocatable array is already allocated

        GLOBAL = 0

 

        do col=1, 2

        omp_threads_id = omp_get_thread_num()

        GLOBAL(1, row, col) = 1

        call sub

        end do

        deallocate(GLOBAL)

    end do

!$omp end do   

!$omp end parallel


 I am not sure since I don’t have much experience coding in OpenMP.

But thanks for respond.

 
 05-05-2008, 4:14 PM 30254148 in reply to 30254103  

Re: Private allocatable arrays inside subroutine in parallel region.

I am been such a nube, here how it works:


module variables

    use omp_lib

    integer :: row, col

    integer :: omp_threads_id, omp_num_of_nodes 

    real*8, allocatable, dimension ( : ) :: GLOBAL ( :, :, : )

    real*8, allocatable, dimension ( : ) :: LOCAL( :, : )

!$omp threadprivate(GLOBAL, LOCAL)   

 

end module variables

 

module sublocal

use variables

implicit none

contains

   

    subroutine sub

    integer :: i, j

    do i = 1, 2

    allocate(LOCAL(2, 2))

    LOCAL = 0

   

        do j = 1, 2

        LOCAL(i, j) = i+j*4

        GLOBAL(1, i, j) = LOCAL(i, j)

        print*, 'SUB: ',GLOBAL(1, i, j)

        end do       

 

    deallocate(LOCAL) 

    end do     

 

       

    end subroutine sub

   

end module sublocal

 

    program openmp

    use variables

    use sublocal

    use omp_lib

   

    implicit none

   

       print*, '----------------------------------------------'     

    omp_num_of_nodes = omp_get_num_procs()

    call omp_set_num_threads( omp_num_of_nodes )   

       print*, 'Number of threads available: ', omp_num_of_nodes

 

!$omp parallel

    omp_threads_id = omp_get_thread_num()

    print*, 'Thread number: ', omp_threads_id, 'responded.'

!$omp end parallel  

    print*, '----------------------------------------------'

 

!$omp parallel default(shared)

!$omp do private(row, col)

    do row=1, 2

        allocate(GLOBAL(2, 2, 2))

        GLOBAL = 0

        do col=1, 2

        omp_threads_id = omp_get_thread_num()

        call sub

        print*, 'MAIN: 'GLOBAL(1, row, col)

        end do

        deallocate(GLOBAL)

    end do

!$omp end do   

!$omp end parallel   

 

 

    call system("PAUSE")

 

    end program openmp

 


Rules:

A variable can only appear in a THREADPRIVATE directive in the scope in which it is declared, and a THREADPRIVATE variable or common block may only appear once in a given scope. The variable must not be an element of a common block, or be declared in an EQUIVALENCE statement.

 

NOTE: I wanted to know how often Intel support checks this forum thread? Since my question was here more than 24 hours, and if I post my question wrong can you highlight which part in order to post next time more correct question to get faster respond.

 

Thanks for everything.

 

 
 05-06-2008, 5:38 AM 30254174 in reply to 30254080  

Re: Private allocatable arrays inside subroutine in parallel region.

This forum is checked frequently, but this is a user forum and for "how to" questions we encourage other users to help.

I am not an OpenMP expert, but reading the manual, what happens in your DO PRIVATE section is that a copy of the module variables is made, the section uses the copy and nothing done to the copy inside the section is reflected in the module variable. 

However, I do see the following text in the Language Reference section on PRIVATE:

  • Contents, allocation state, and association status of variables defined as PRIVATE are undefined when they are referenced outside the lexical extent (but inside the dynamic extent) of the construct, unless they are passed as actual arguments to called routines.
This tells me that in your call to SUB, the module variables referenced in SUB are the original, unallocated variables and not the private copy. To fix this, you should pass the variable as an argument and not rely on use or host association.

I also note that you are using an old compiler version that is not supported on Vista, though I doubt that the OS has any bearing on the issue.

Steve

Doctor Fortran: intel.com/software/drfortran
 
View as RSS news feed in XML

Shortcuts


Tags For This Post

...

Community Tags

...