Option to align COMMON on page boundary

Option to align COMMON on page boundary

In our application, we accomplish IPC by using shared memory, whereby multiple programs map Fortran COMMON blocks to a single shared memory area (via the Linux "shmat" call, with the SHM_REMAP flag). The only problem for us is that for this to work properly, the COMMON blocks need to be page-aligned (which, on Linux, is 4096 bytes). We accomplish this now by using an ugly hack, which involves replacing the ifort intrinsic _FTN_ALLOC with our own (and using the -dyncom compiler option), which allocates the COMMON block memory using posix_memalign().

Having a compile and/or link flag that activated a feature built-in to the ifort compiler to do this automatically (page-aligning COMMON blocks) would be a plus.

15 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Are you requesting that the named COMMON block not be allocated via _FNT_ALLOC but rather be statically linked at a page boundary?

If so (I haven't tried this) make the common block EXTERN in your Fortran program and then make a C stub with apage aligned data block of (at least) the appropriate size).

Jim Dempsey

www.quickthreadprogramming.com

Quoting - ereisch
In our application, we accomplish IPC by using shared memory, whereby multiple programs map Fortran COMMON blocks to a single shared memory area (via the Linux "shmat" call, with the SHM_REMAP flag). The only problem for us is that for this to work properly, the COMMON blocks need to be page-aligned (which, on Linux, is 4096 bytes). We accomplish this now by using an ugly hack, which involves replacing the ifort intrinsic _FTN_ALLOC with our own (and using the -dyncom compiler option), which allocates the COMMON block memory using posix_memalign().

Having a compile and/or link flag that activated a feature built-in to the ifort compiler to do this automatically (page-aligning COMMON blocks) would be a plus.

It's not a compile flag (you'll have to edit your source) but you could try this:

!dec$ attributes align: 4096 :: a
common /a/ i
data i /5/
common /b/ j
data j /15/
print *, i, j
end

This aligns A on the page boundary, but not B

Quoting - Lorri Menard (Intel)

It's not a compile flag (you'll have to edit your source) but you could try this:

!dec$ attributes align: 4096 :: a
common /a/ i
data i /5/
common /b/ j
data j /15/
print *, i, j
end

This aligns A on the page boundary, but not B

Lorri,

Can you have your document writers address this. In your IVF documentation

cDEC$ ATTRIBUTES ALIGN: n:: var

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for Compiler Directives.)

n
Is the number of bytes for the minimum alignment boundary.

For allocatable variables, the boundary value must be a power of 2 between 1 and 16384, such as 1, 2, 4, 8, 16, 32, 64, 128, and so on.

For non-allocatable variables, the boundary value must be a power of 2 between 1 and 64 on Windows* systems, between 1 and 2**16 on Linux* systems, or between 1 and 2**12 on Mac OS* X systems.

var
Is the variable to be aligned.

--------------------------------
In your response to this forum you are using a common block name, not a variable.
In your documentation

common blocks
directive modifying alignment data in

cDEC$ OPTIONS option[option]

...

cDEC$ END OPTIONS

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for Compiler Directives.)

option
Is one (or both) of the following:

/WARN=[NO]ALIGNMENT
Controls whether warnings are issued by the compiler for data that is not naturally aligned. By default, you receive compiler messages when misaligned data is encountered (/WARN=ALIGNMENT).

/[NO]ALIGN[= p]
Controls alignment of fields in record structures and data items in common blocks. The fields and data items can be naturally aligned (for performance reasons) or they can be packed together on arbitrary byte boundaries.p
Is a specifier with one of the following forms:

[class=]rule

(class= rule,...)

ALL

NONE

class
Is one of the following keywords:

COMMONS: For common blocks

RECORDS: For records

STRUCTURES: A synonym for RECORDS

rule
Is one of the following keywords:

PACKED
Packs fields in records or data items in common blocks on arbitrary byte boundaries.

NATURAL
Naturally aligns fields in records and data items in common blocks on up to 64-bit boundaries (inconsistent with the Fortran 95/90 standard).

This keyword causes the compiler to naturally align all data in a common block, including INTEGER(KIND=8), REAL(KIND=8), and all COMPLEX data.

STANDARD
Naturally aligns data items in common blocks on up to 32-bit boundaries (consistent with the Fortran 95/90 standard).

This keyword only applies to common blocks; so, you can specify /ALIGN=COMMONS=STANDARD, but you cannot specify /ALIGN=STANDARD.

ALL
Is the same as specifying OPTIONS /ALIGN, OPTIONS /ALIGN=NATURAL, and OPTIONS /ALIGN=(RECORDS=NATURAL,COMMONS=NATURAL).

NONE
Is the same as specifying OPTIONS /NOALIGN, OPTIONS /ALIGN=PACKED, and OPTIONS /ALIGN=(RECORDS=PACKED,COMMONS=PACKED).

Which does not provide for the user to specify numeric value for alignment requirement.

Jim Dempsey

www.quickthreadprogramming.com

Quoting - jimdempseyatthecove

Lorri,

Can you have your document writers address this. In your IVF documentation

cDEC$ ATTRIBUTES ALIGN: n:: var

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for Compiler Directives.)

n
Is the number of bytes for the minimum alignment boundary.

For allocatable variables, the boundary value must be a power of 2 between 1 and 16384, such as 1, 2, 4, 8, 16, 32, 64, 128, and so on.

For non-allocatable variables, the boundary value must be a power of 2 between 1 and 64 on Windows* systems, between 1 and 2**16 on Linux* systems, or between 1 and 2**12 on Mac OS* X systems.

var
Is the variable to be aligned.

--------------------------------
In your response to this forum you are using a common block name, not a variable.
In your documentation

common blocks
directive modifying alignment data in

cDEC$ OPTIONS option[option]

...

cDEC$ END OPTIONS

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for Compiler Directives.)

option
Is one (or both) of the following:

/WARN=[NO]ALIGNMENT
Controls whether warnings are issued by the compiler for data that is not naturally aligned. By default, you receive compiler messages when misaligned data is encountered (/WARN=ALIGNMENT).

/[NO]ALIGN[= p]
Controls alignment of fields in record structures and data items in common blocks. The fields and data items can be naturally aligned (for performance reasons) or they can be packed together on arbitrary byte boundaries.p
Is a specifier with one of the following forms:

[class=]rule

(class= rule,...)

ALL

NONE

class
Is one of the following keywords:

COMMONS: For common blocks

RECORDS: For records

STRUCTURES: A synonym for RECORDS

rule
Is one of the following keywords:

PACKED
Packs fields in records or data items in common blocks on arbitrary byte boundaries.

NATURAL
Naturally aligns fields in records and data items in common blocks on up to 64-bit boundaries (inconsistent with the Fortran 95/90 standard).

This keyword causes the compiler to naturally align all data in a common block, including INTEGER(KIND=8), REAL(KIND=8), and all COMPLEX data.

STANDARD
Naturally aligns data items in common blocks on up to 32-bit boundaries (consistent with the Fortran 95/90 standard).

This keyword only applies to common blocks; so, you can specify /ALIGN=COMMONS=STANDARD, but you cannot specify /ALIGN=STANDARD.

ALL
Is the same as specifying OPTIONS /ALIGN, OPTIONS /ALIGN=NATURAL, and OPTIONS /ALIGN=(RECORDS=NATURAL,COMMONS=NATURAL).

NONE
Is the same as specifying OPTIONS /NOALIGN, OPTIONS /ALIGN=PACKED, and OPTIONS /ALIGN=(RECORDS=PACKED,COMMONS=PACKED).

Which does not provide for the user to specify numeric value for alignment requirement.

Jim Dempsey

OK. I agree 100% that we should beef up DEC$ ATTRIBUTES ALIGN to include named COMMON, and I'll talk to our doc person later today.

The other one, well, we can have a debate on that one. It's intended to describe the alignment *inside* the COMMON block, not the alignment of the start of the COMMON block. I know that's a strange distinction, but there is a difference between how you want the contents ofthe COMMON aligned (perhaps packed?) versus where you want that COMMON to be placed (perhaps on quad boundary?)

- Lorri

Quoting - Lorri Menard (Intel)

It's not a compile flag (you'll have to edit your source) but you could try this:

!dec$ attributes align: 4096 :: a
common /a/ i
data i /5/
common /b/ j
data j /15/
print *, i, j
end

This aligns A on the page boundary, but not B

Ok, in that case, I believe I have come across a bug in either the compiler or the documentation then :-)

Since our sim needs to be portable between both Linux and VMS, we must use the larger of the two page alignment values, which is VMS (8192). In the documentation for ATTRIBUTES ALIGN, it lists the upper limit as 2**16 (65536) on Linux systems, and 2**12 (4096) on Mac OS X systems. However, when I put in 8192 as my alignment value and try to compile on our Linux system, we're presented with an error:
error #7943: The val in 'ALIGN:val' must be a power of 2 value from 1 up to 4096 (2**12).

This is compiling on a Debian GNU/Linux x86, using compiler version 11.0.

Thanks again.

Lorri,

When they address the issue have them consider (in consultation with engineering, and with ANSI committee member (Steve L.?))

cDEC$ ATTRIBUTES ALIGN:align: 4096::bn
COMMON /bn/ var

verses

cDEC$ ATTRIBUTES ALIGN:align: 4096::var
COMMON /bn/ var

The two situations are not syntactically equivalent, the results may or may not be equivalent in IVF which may or may not differ with ANSI standards.

Jim Dempsey

www.quickthreadprogramming.com

Quoting - ereisch

Ok, in that case, I believe I have come across a bug in either the compiler or the documentation then :-)

Since our sim needs to be portable between both Linux and VMS, we must use the larger of the two page alignment values, which is VMS (8192). In the documentation for ATTRIBUTES ALIGN, it lists the upper limit as 2**16 (65536) on Linux systems, and 2**12 (4096) on Mac OS X systems. However, when I put in 8192 as my alignment value and try to compile on our Linux system, we're presented with an error:
error #7943: The val in 'ALIGN:val' must be a power of 2 value from 1 up to 4096 (2**12).

This is compiling on a Debian GNU/Linux x86, using compiler version 11.0.

Thanks again.

OK --- so noted. :-)

Best Reply

I will comment that Lorri is also an X3J3 Fortran standards committee member. She is the first alternate for Intel and I am the second alternate. Stan Whitlock is the primary representative for Intel.

I will further comment that we already have the requested option, though I understand why you didn't find it. The spelling is:

!DEC$ PSECT /common-name/ ALIGN=PAGE

Steve - Intel Developer Support

Quoting - Steve Lionel (Intel)
I will comment that Lorri is also an X3J3 Fortran standards committee member. She is the first alternate for Intel and I am the second alternate. Stan Whitlock is the primary representative for Intel.

I will further comment that we already have the requested option, though I understand why you didn't find it. The spelling is:

!DEC$ PSECT /common-name/ ALIGN=PAGE

Thanks Steve.

Is PAGE determined at runtime?
i.e. 4KB or 4MB (or other depending on platform)

Jim

www.quickthreadprogramming.com

PAGE is not run-time determined. It is 2**12 (4096) on Linux, which seems to be the maximum available in the object language.

Steve - Intel Developer Support

Quoting - Steve Lionel (Intel)

PAGE is not run-time determined. It is 2**12 (4096) on Linux, which seems to be the maximum available in the object language.

There's still no support on ia32 nor x86_64 platforms for page sizes between 4KB and 2MB. That was a useful feature which never got extended outside of ia64.

Quoting - tim18

There's still no support on ia32 nor x86_64 platforms for page sizes between 4KB and 2MB. That was a useful feature which never got extended outside of ia64.

Agreed. As noted above, I'm trying to use 8k so the same source will run when using the DEC compiler, though Steve's alternate method seems as though it's working too. The documentation on the ALIGN directive could be a little more clear on align limits for the various architectures though.

The PSECT attribute came from the DEC compilers. ("PSECT" is a VMS term.) I agree that the documentation could be improved here.

Steve - Intel Developer Support

Quoting - Steve Lionel (Intel)

The PSECT attribute came from the DEC compilers. ("PSECT" is a VMS term.) I agree that the documentation could be improved here.

Also, it should be noted that the ALIGN=PAGE does not work for me on Linux. When I use the ATTRIBUTES ALIGN: 4096 :: COMMON_NAME, I have no problem mapping the common block to shared memory using shmat(). However, on that same common block, if I recompile using the PSECT /COMMON_NAME/ ALIGN=PAGE flag, my common block start is located at a different memory address, and I get an illegal alignment error when I try to map to a shared area using shmat().

Leave a Comment

Please sign in to add a comment. Not a member? Join today