Back to Eric's Home Page

Memory mapped files for IDL


Intro - Specs - Compiling - Usage - Sparse Files - Shared Memory - Bugs - Download - Release History

Introduction

Shortly after beginning to use IDL, I became annoyed with a couple features of IDL. First, when working with many large images, I would often run out of virtual memory, despite having 127 MB available. Second, the ASSOC feature, which associates a file with an IDL array, does not work as I had hoped. Rather than easily allowing access to any element of any array contained in a file, it requires that elements be copied into temporary arrays, and then written back to the file array. Eventually I got tired of it both of these problems and decided to do something about it. I sat down and wrote VARRAY. It has the advantages of solving both problems, and a couple I never thought of.

VARRAY: Specifications

VARRAY is in external system routine in IDL. It is written in C and has been tested on IDL 4.X and 5.X under SunOS 4.1.3, Solaris 2.X, and RedHat Linux 6.1. It should, however, work with minor modifications under most UNIX systems that support the mmap() and ftruncate() functions. Making it work under Win32 is more of an effort, but should be possible. I have no idea whether there is a mmap() equivalent under VMS.

Compiling VARRAY

VARRAY is shipped with a Makefile that may require some modifications depending upon the system used. Macros are provided for SunOS systems with GCC and ACC compilers (GCC is recommended), Solaris, and Linux systems. Once the Makefile has been modified, VARRAY is compiled with the command:
make varray.so

VARRAY: Usage

The shared object file "varray.so" needs to be linked into the running IDL process using the LINKIMAGE routine. I place the following command in my IDL_STARTUP routine:

LINKIMAGE,'VARRAY','~/idl/mmap/varray.so',1,'varray',min_args=1,max_args=10,/keywords
Once the shared object is loaded, the VARRAY function becomes available. The syntax of the VARRAY function is:

array=VARRAY([filename],element,[dim1,dim2,dim3,...dim8],[/writable],[/status])
where

For example, the command

A=VARRAY("test.dat",byte(0),512,512,/writable)
opens a file named "test.dat", creating it if it doesn't exist, and assigns it to a 512 by 512 byte array. The elements of this array can be accessed and written to. For example:
A(*,*)=byte(255*randomu(seed,512,512))
will write random values into the file. When the variable is deleted (i.e DELVAR,A) or reallocated (i.e. A=SOMETHING) all changes will be updated on disk.

Sparse Files

VARRAY supports sparse files. In a sparse file, only those portions of the file that contain non-zero data are written to disk. Try the following in IDL:
a=fltarr(8192,8192)
Chances are, you just saw the message (unless you had 256 MB free):
% Unable to allocate memory: to make array.
  Not enough memory
% Execution halted at:  $MAIN$                 
Now, with VARRAY loaded try the following:
a=varray("test.dat",float(0),8192,8192,/writable)
help,a
You should see...
A               FLOAT     = Array(8192, 8192)
Going to UNIX and doing "ls -l", we see that the file is 268435456 bytes long and takes up 24k of disk space. Now convince yourself that the array is real by doing
a(4096,4096)=!pi
print,a(4096,4096)
You'd better see 3.14159. Checking the file size again you'll see that it's still 268435456 bytes long, but now it takes up 40k of disk space. Check that things are repeatable by deleting the variable, and reloading it.
delvar,a
a=varray("test.dat",float(0),8192,8192,/writable)
print,a(4096,4096)
You should still see 3.14159. If you want to sit around for a long time you can even "print,total(a)".

Shared Memory

A happy circumstance of VARRAY is that it allows memory to be shared between IDL processes. If you map a file with the /writable keyword, the changes will be shared with any other process that maps the file. As an example, start two idl processes and link "varray.so" to them. In each, enter:
a=varray("shm.dat",fix(0),100,/writable)
now, in one enter "a(0)=1" then in the other, enter "print,a(0)." Presto, interprocess communication. Of course there's no protection for simultaneous access, so for each variable I would recommend that one process read and the other write.

Bugs and Stuff-To-Do

There's always another bug or feature. Here are a few you should note:

Download VARRAY

This software is Copyright 1998 UC Regents, All Rights Reserved. Permission to modify and distribute this program is granted, provided the copyright notice in the source code remains unchanged. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. The authors and copyright holders are not liable for any damages resulting from the use or misuse of this software.

Download Source Code

Download SPARC SunOS 4.1.3 Shared Object

Download SPARC Solaris 2.6 Shared Object

Download RedHat Linux 6.1 (glibc 2.1) Shared Object

Release History

Acknowledgements

My thanks to Angelos Vourlidas at the Naval Research Lab, for providing the Solaris binary and for pointing out the bug in the munmap() call.

Thanks to Nick Bower for providing the RedHat binary and reminding me to fix the printf bug.

You are visitor
Counter provided by LE FastCounter

Intro - Specs - Compiling - Usage - Sparse Files - Shared Memory - Bugs - Download - Release History

Copyright © 1998 Eric Korpela
korpela@ssl.berkeley.edu