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

Port FORTRAN 77 Shared Common with C parallel process interoperability

tcdev_matt
Beginner
1,036 Views

Greetings all,

I will be porting old HPUX FORTAN 77 code to a new Linux FORTRAN (?).  The F code currently creates shared COMMON Blocks using the $SHARED_COMMON compiler directive.  This creates a shared memory structure in the HP Workstation's IPC system.  We then use shared memory functions in C (shmget, shmat, etc.) to access the data in a the C parallel application.

I'm trying to determine if the Intel FORTRAN can replicate this function.  I've read through the Global Data Overview in the Developer Guide and the ISO_C_BINDING intrinsic and BIND(C) do seem to address this.

The FORTRAN code creates the named COMMON Blocks (35) that are shared to IPC with the $SHARED_COMMON compiler declaration via header include file i.e.:
$SHARED_COMMON KEY='idcp'  SAVE /idcp/
and another include file to allocate the size of the common segments (only one segment shown):
COMMON /idcp/ IDCAP(0:128)

Our C code attaches to the shared memory thusly (only one segment shown):

#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/stat.h>

int idcapSmId, 
short *idcap_ptr

short idcap[129]

 void getsm()
{
 int i;
 for(i=0; i<=128; i++)
  idcap[i]=idcap_ptr[i];

int

main ()

 union
 { char c [4];
   key_t l ;
 } key;

 strncpy(key.c, "idcp", 4) ;
 if ((idcapSmId = shmget(key.l, 0, 0666 | IPC_CREAT)) == -1)
 { perror("attach_sm - idcap shmget failed");
  exit(1);
 }

 if((short)(idcap_ptr = (short*)shmat(idcapSmId,0,0))== -1)
 { perror("attach_sm -idcap shmat failed");
  exit(1);
 }

Would we be able to replicate a shared memory system like this with the Intel FORTRAN for Linux compiler?

 

Thank you!

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
1,025 Views

Fortran's C Interoperability features do allow a Fortran COMMON to share with a C variable that has external linkage, but that's not what you're doing. The way I would handle this in standard Fortran is to define a pointer variable of derived (and interoperable) type that has all the components, let the C code do its shmem thing, provide the address of the allocated region to a Fortran routine and use C_F_POINTER to convert that into a Fortran pointer. 

This does mean some rewrite as instead of direct variable access, you're accessing components of a derived type.

Intel Fortran does have a feature that might be of use to you, dynamic common. This lets you keep the Fortran code and COMMON blocks intact, but you tell the compiler that you'll provide your own routine for allocating memory for the selected COMMON blocks. This routine might get the address from the C code. I'll caution you that this feature has largely been neglected over the years, but it is still documented so it might work.

View solution in original post

0 Kudos
2 Replies
Steve_Lionel
Honored Contributor III
1,026 Views

Fortran's C Interoperability features do allow a Fortran COMMON to share with a C variable that has external linkage, but that's not what you're doing. The way I would handle this in standard Fortran is to define a pointer variable of derived (and interoperable) type that has all the components, let the C code do its shmem thing, provide the address of the allocated region to a Fortran routine and use C_F_POINTER to convert that into a Fortran pointer. 

This does mean some rewrite as instead of direct variable access, you're accessing components of a derived type.

Intel Fortran does have a feature that might be of use to you, dynamic common. This lets you keep the Fortran code and COMMON blocks intact, but you tell the compiler that you'll provide your own routine for allocating memory for the selected COMMON blocks. This routine might get the address from the C code. I'll caution you that this feature has largely been neglected over the years, but it is still documented so it might work.

0 Kudos
tcdev_matt
Beginner
991 Views

Thank you Steve,

I read through the Allocating Dynamic Blocks section of manual and this does appear to be a good solution, especially if the C code can access those blocks of memory with the standard IPC shmget and shmat using the block names.  Unsure about the address passing if that does not work in this case.  I suppose one and maybe only way to find out is to get the compiler and start in on it.

 

Thanks again,

Matt

0 Kudos
Reply