Software Archive
Read-only legacy content
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17060 Discussions

Fortran Commons/Virtual Memory

Intel_C_Intel
Employee
855 Views
Hello,

I'm porting code from Alpha to Win2K. The fortran code I have uses a fortran common mapped to a map section to share data between processes. I'm trying now to port that code to a PC. I want to map the fortran common to virtual memory (thru MapViewOfFileEx, i.e.).

On Alpha, I use the COLLECT statement in the link options file to equate the common name with the map section name, but there does not seem to be the equivalent on the PC. The documentation says that fortran commons are relocatable, but there is no reference on how to do that.

Any help would be greatly appreciated. Thanks.

Dave Yasko
0 Kudos
8 Replies
Intel_C_Intel
Employee
855 Views
We have used 'shared memory' through MAPVIEWOFFILE etc. to replicate what used to be called the GLOBAL SECTION on VAX/UNIX(?). I can post / send you some example code if it will help...?
0 Kudos
Intel_C_Intel
Employee
855 Views
Dan,

Thanks. That would be great. The code that I'm porting uses a large (sometimes greater than 512K, 512K is the maximum on VAX) fortran common. I thought I had several solutions to mapping a common to shared memory, but none of them worked. Example code would be great. Please post here. Thanks again.

Dave
0 Kudos
Intel_C_Intel
Employee
855 Views
*------------------------------------------------------------------------------  
*
* MM MM DDDDDDD CCCCCC
* MMM MMM DD DD CC CC Copyright 2001 MDC Technology Limited
* MMMM MMMM DD DD CC Library : USER
* MM MMM MM DD DD CC File : SHARED_FILE.FOR
* MM M MM DD DD CC CC Author : D. J. Crosby
* MM MM DDDDDDD CCCCCC
*
*
* Description
* -----------
* Create a file and expand it to the size of the item, stream item_key,
* or stream_key arrays, or a preset size, whichever is the smaller.
*
* Arguments
* ---------
* share_name name of shared memory
* kind the 'kind' of share to create
* handle shared file handle
* number_of_records file size
*
* Returns
* -------
* TRUE if shared file created OK, otherwise FALSE
*
* Revision History
* ----------------
*
* Version Date By HD No. Reason
* 1 12-Jan-99 DR ---- Produce working trans_gs
*
*------------------------------------------------------------------------------

LOGICAL*4 FUNCTION shared_file (share_name, kind, handle, number_of_records)

*------------------------------------------------------------------------------

IMPLICIT NONE

* --------
* Includes
* --------

INCLUDE 'MODEL_PRIV.CMN'
INCLUDE 'MODEL_ERROR.PRM'
INCLUDE 'RTOSHR.CMN'
INCLUDE 'FILE_IO.CMN'
INCLUDE 'WIN32RTO.INC'

* ---------
* Arguments
* ---------

CHARACTER*9 share_name ! name of shared memory
CHARACTER*4 kind ! A string, containing:
! 'item': map item to memory
! 'strm': map stream to memory
! 'itky': map item_key to memory
! 'stky': map stream_key to memory
INTEGER*4 handle ! shared file handle
INTEGER*4 number_of_records ! file size (#items/strms)

* ---------
* Variables
* ---------

INTEGER*4 my_error ! error code from Win32 API
CHARACTER*255 the_file ! filename to open/create
INTEGER*4 path_len ! length of RTO+ path
INTEGER*4 lpBuffer ! address of an RTO+ array
INTEGER*4 nNumberOfBytesToWrite ! self-explanatory
INTEGER*4 lpOverlapped ! not used
INTEGER*4 result_1 ! whether file-write worked okay
INTEGER*4 lpNumberOfBytesWritten ! self-explanatory
INTEGER*4 dwSize ! size of file in bytes
LOGICAL*4 created_here ! .TRUE. if new file created

* ---------
* Functions
* ---------

LOGICAL*4 rto_file_mapping

*------------------------------------------------------------------------------
* -------------------
* Assume it will work
* -------------------

shared_file = .TRUE.
created_here = .FALSE.

* ----------------------------------
* Obtain the path to create the file
* ----------------------------------

* Avoid the trailing null-terminator
path_len = LEN_TRIM (DiagnosticPath(1:254))
the_file(1:path_len) = DiagnosticPath(1:path_len)

* -------------------------------
* Add the name for the RTO+ array
* -------------------------------

* first the file name
the_
0 Kudos
Intel_C_Intel
Employee
855 Views
OK - so it didn't like me posting that much!
Dave , if you can be specific about what you need, I can post some relevant snippets. Otherwise e-mail me at crosbyd!!!@!!!mdctech.com (without the !s)

Dan
0 Kudos
Intel_C_Intel
Employee
855 Views
Although I can't help with your problem I am also looking for the same solution. Have you had any success ?

Thanks - Mark
0 Kudos
Intel_C_Intel
Employee
855 Views
Mark,

Our method works for our problem, whether it solved Dave's I don't know. I can forward you the files I sent to Dave if you mail me at crosbyd_spamguard_@mdctech.com. (remove the _spamguard_) - they may help!

Dan
0 Kudos
Intel_C_Intel
Employee
855 Views
Mark,

The code that Dan Crosby sent gave me a lot to think about. It was very useful. Without it, I don't think I would have figured out how to access the Win32 functions.

I don't know exacly what you need, but I found that I need the functionality of the COLLECT link options file statement. Without it, I need to modify neerly all of my Fortran code. On the PC, running CVF, there appears to be no equivalent statement. I was lucky though, that project got put on the back burner for now, so I don't have to worry about it yet.

I found, to port my Fortran code from Alpha to Win32, I had thee options:

1) I could save myself needing to modify every line of code that uses variables in my (shared) global common by providing a pointer to each variable and populating them after mapping to shared memory. It looks like:

(in header file)
COMMON / GLOBAL / STARTCOM, , ...
INTEGER*4 STARTCOM
INTEGER*4
...
INTEGER*4 PARAMETER :: OS__ =
POINTER (P__, )
...
(in intitialization code)
STARTCOMP__ = MAPVIEWOFFILE(...)
P__ = STARTCOMP__ + OS__

This works for us because the include file is automatically generated by a utility that can be modified (See comment after option #3).

2) I could change my global common to a structure, assign a pointer to it, and set that pointer's value from pointer returned from MapViewOfFile(...). This is the easiest to impliment and understand, but it does require you to prepend the name of the instance of that record (i.e. SIMCOM%) to each global common variable name in your code.

3) I could convert all of my code to C or C++. The Fortran code is pretty simple, but there is a bunch of it, so this was the last option.

My choice was #2 above, because the include file that defines our global common is generated by a utility that was written about 15 years ago. It has been modified a few times, but doing so is an exercise frought with peril. Modifications for option #2 to that program are probably much easier than for option #1.

I know I get a bit wordy, but I hope this helps you.

Happy Holidays!!!
Dave Yasko
0 Kudos
Steven_L_Intel1
Employee
855 Views
See the DLLEXP1 and DLLEXP2 examples - it's easy and similar to using shareable images on VMS.

Steve
0 Kudos
Reply