Recently, I stumbled upon the Memrc Argument in the SAS hash object Definedone Method. The purpose of the argument is to be able to take an alternate action if the hash object can not contain the required memory. The documentation does not contain much information. It merely says that

If a call fails because of insufficient memory to load a data set, a nonzero return code is returned. The hash object frees the principal memory in the underlying array. The only allowable operation after this type of failure is deletion via the DELETE method.

In this post, I will investigate the Memrc option. Furthermore, I provide a few examples and make a few points not clear in the documentation.

In the examples to come, it is important that you can deliberately run out of memory. Therefore, check the realmemsize option in your SAS session with the code below.

/* Find the available memory and real (non-pagable) memory */
proc options option=(memsize realmemsize);
run;

The Memrc Option

The Memrc argument was introduced in SAS 9.2. Let us see an example of how to use the Memrc argument. First, I create a data set, that is too big to hold in memory. In the next data step, I create a has object h and read the big data set into it. I use the Memrc Argument and call the Definedone Method assigned. This gives me a non-zero return code.

However, it does not yield any error. It would yield an error if you omit the Memrc Argument and run out of hash memory.

data big;
   do x = 1 to 1e9;
      output;
   end;
run;
 
data _null_;
 
   declare hash h (dataset : 'big');
   h.definekey ('x');
   rc = h.definedone (memrc : 'y'); 
 
   put rc = ;
 
   x = .;
 
run;

What the Documentation Does Not Mention

If the Memrc Argument returns a non-zero return code, it means that the hash object ran out of memory. According to the documentation, the only allowable action is to call the Delete Method. However, this is true only for the instance of the hash object. I am allowed to create a new instance of h and work with that. See the example below.

data big;
   do x = 1 to 1e9;
      output;
   end;
run;
 
data small;
   do x = 1 to 10;
      output;
   end;
run;
 
data _null_;
 
   declare hash h (dataset : 'big');
   h.definekey ('x');
   rc = h.definedone (memrc : 'y');
 
   put rc =;
 
   h = _new_ hash (dataset : 'small');
   h.definekey ('x');
   rc = h.definedone (memrc : 'y');
 
   put rc =;
 
   x = 1;
 
   rc = h.find ();
 
run;

Summary

In this post, I attempt to provide a few examples of the SAS hash object memrc option. The documentation is not very detailed and it provides not details. The Memrc argument enables memory recovery when there is not enough memory available for the content in the object. If the data load fails, Definedone returns a non-zero return code and the underlying memory is released. I have not used the Memrc option in a real life situation yet. However, it is nice to know it is there. Finally, I opened a thread at the SAS Community to ask for other SAS users opinion on the argument. You can read the thread here.

Also, read the related posts Using the Suminc and Keysum Arguments in SAS Hash Object and An interesting PDV Application of the SAS Hash Object.

You can download the entire code from this post here.