Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
17 Views

Threading legacy code with SAVE attribute

Colleages,

We are threading legacy code and have encountered the following:

  1. A loop that iterates through a list of equipment data files
  2. Within that loop, and for each iteration, a routine is called multiple times (loop with the outer loop):
    1. The first time it is called in the inner loop, it opens the current equipment data file (determined by the outer loop), reads its data, and does some initial processing. Some of this data is in variables with the SAVE attribute
    2. The 2nd and subsequent times this routine is called in the inner loop, the data file is not opened/read, rather the SAVEd data is used
    3. On these subsequent calls, some of this SAVEd data is written to other files (this step is not germane to the issue at hand)

We want to thread this loop. Not surprisingly, the SAVEd variables get scrambled between (?) threads and the results are rubbish. We have changed the code to write the data previously SAVEd to a temp file (unique to each thread) and (re)read it as necessary. Naturally this is very much slower and defeats any improvement offered by threading. The routine in questions has been declared RECURSIVE.  We are using OpemMP.

Are there alternatives to writing/reading temp files?

David

 

0 Kudos
2 Replies
Highlighted
Valued Contributor I
17 Views

Create an array of the SAVEd items, indexed by the thread_id, ie a unique identifier of each thread, then reference the quantities by active thread, ie myvar(this_thread).

I have found it useful to create a UDT array, call it thread_args(), which includes all the items which are thread-specific to the calculational activity.  If you make this array a target, then your local variables can point to the safe quantities, ie, myvar => thread_args(this_thread)%myvar, and you can put this in once at the top, no change to the rest of the code.

0 Kudos
Highlighted
New Contributor I
17 Views

You can declare SAVEd variables as threadprivate.  Each thread would have its own copy of the variable.  For example:

integer,save:: ii
real,save:: aa
!$OMP threadprivate(ii,aa)

 

0 Kudos