initialize common block defined in a module in OMP

initialize common block defined in a module in OMP

stydofe1's picture

Define a common block in an include file, for example

 Test.ins

Common /test/ a b

 Then wrap up the include file in a module file, for example

 Module test

Include ‘test.ins’

End module

 

Basically I just define the common block in the module. I do not have issue to use the common block in the regular Fortran codes. However in OMP I define the common block as threadprivate and when I initialize the block for child threads with COPYIN directive, I got the error below.

 

error #7460: A common block name is required

 

Please let me know if I am not clear about the issue.

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
jimdempseyatthecove's picture

The error message "A common block name is required" is self explanitory.

type    TypeThreadContext
SEQUENCE
... declarations here
end type TypeThreadContext
type(TypeThreadContext) :: ThreadContext
COMMON /CONTEXT/ ThreadContext
!$OMP THREADPRIVATE(/CONTEXT/)
COMMON /FOO/ A,B,C
!$OMP THREADPRIVATE(/FOO/)

Jim Dempsey

www.quickthreadprogramming.com
jimdempseyatthecove's picture

Normally you do not place COMMON data in modules because the name of the COMMON block you use will get pre-pended with a module prefex name

In your case the actual name might be TEST_MP_TEST

You will have to check, and the compiler may change the prepend now or later. It may work to scope the declaration

!$OMP THREADPRIVATE(test::/test/)

I haven't tried the above, don't complain if it doesn't work.

I suggest using the user defined type and remove COMMON though this may be problematic for your case.

Usually where you had COMMON /FOO/ A,B,C,...
you would make a user defined type (e.g. FOO_t) and declare an instance of FOO_t as FOO. Then you can !$OMP THREADPRIVATE(FOO). And reference variables as FOO%A, ...

In the event you have no variable naming conflics amongst your various COMMONs, then these not need to be in a typed variable. And you can forgoe the FOO%...

Jim Dempsey

www.quickthreadprogramming.com
stydofe1's picture

The block has been defined as threadprivate in the include file,

 

Test.ins

Common /test/ a b

!$OMP threadprivate(test)

 

If the common block is refereed with the include file, the file with COPYIN statement is compiled successfully. But if it is refereed with the module file, which is simply a wrapper of the include file, OMP fails to compile with the error ‘A common block name is required’

I can not see the difference between these two methods. Is it a bug in compiler?

jimdempseyatthecove's picture

But your "include 'test.ins'" is enclosed in "module test" / "end module test", thus making the enclosed "COMMON /test/" within the scope of the module test. As stated in earlier post, all members of the module, in this case "test" have a prefix pre-pended to the name. In the case of "module test" the module name is test, and the prepend text is "TEST_MP_", thus producing a COMMON block name of /TEST_MP_TEST/ (implicit name) for given name /TEST/ within the scope of module test (TEST_MP_....).

Had you used "module foo" in your example then the name would be FOO_MP_TEST.

*** Note, the actual prefix may be of a different form (_FOO_MP_) or some other thing.

module foo
REAL :: A
COMMON /TEST/ B
end module foo

produces

REAL FOO_MP_A
COMMON /FOO_MP_TEST/ B

Jim Dempsey

www.quickthreadprogramming.com
Andrey Churbanov (Intel)'s picture

It looks like your program is non-conforming. Let's refer to specifications.

OpenMP: 

A common block name that appears in a copyin clause must be declared to be a Fortran common block in the same scoping unit in which the copyin clause appears.

Fortran:

Use association is the association of names in different scoping units specified by a USE statement.

Thus you are trying to specify in the copyin clause the common block declared in different scoping unit, that is not allowed.  Though it is possible to list the variables from common block of different unit (not the common block itself) in the copyin clause.

Regards,
Andrey

Login to leave a comment.