<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Is there a way to persist a hash in an FCMP function between function calls ? in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703666#M215650</link>
    <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;In C, if you declare a variable as static.&lt;/P&gt;
&lt;P&gt;All RAND functions in SAS need to do that.&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So a VARIABLE is static. Not a Function.&lt;/P&gt;
&lt;P&gt;I might be misunderstanding.&lt;/P&gt;</description>
    <pubDate>Fri, 04 Dec 2020 15:44:08 GMT</pubDate>
    <dc:creator>ballardw</dc:creator>
    <dc:date>2020-12-04T15:44:08Z</dc:date>
    <item>
      <title>Is there a way to persist a hash in an FCMP function between function calls ?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703621#M215624</link>
      <description>&lt;P&gt;It appears I was hasty in my speculation and incorrect in presuming non-persistence -- oh the dangers of assume.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Based on Art Carpenters 2018 paper&amp;nbsp;&lt;A href="https://www.sas.com/content/dam/SAS/support/en/sas-global-forum-proceedings/2018/2399-2018.pdf" target="_self" rel="nofollow noopener noreferrer"&gt;Using Memory Resident Hash Tables to Manage Your Lookup Control Files&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt; (thanks for the link&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/15410"&gt;@data_null__&lt;/a&gt;&amp;nbsp;) I worked up some code that appears to clearly verify a declared hash variable (and it's initialization via &lt;CODE&gt;dataset:&lt;/CODE&gt; keyword) is persisted between calls &lt;STRONG&gt;within the scope of a single step&lt;/STRONG&gt;. This example uses a view to load the hash in order to Log a message when the view is processed, and that message appears only once.&amp;nbsp; This would indicated to me that internally the hash component is caching or singleton'ing declared instantiations.&amp;nbsp; This would mean methods such as .defineKey, .defineData and .defineDone will only do something, in regards to setting up the component, once, at execution points prior to a first .defineDone.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Tested in SAS 9.4M6&lt;/P&gt;
&lt;PRE&gt;dm 'clear output';

data names / view=names;
  set sashelp.class;
  where name in: ('A' 'J');
  if _n_ = 1 then 
    putlog 'NOTE: ----------'                        /* this goes into the Log window */
         / 'NOTE: Names view being accessed'
         / 'NOTE: ----------' 
         / '00'x 
         ;
run;

proc fcmp outlib=work.sandbox.functions;
  function found(name $);

    declare hash h(dataset:'names');
    rc = h.defineKey('name');
    rc = h.defineDone();

    put 'function found(), checking ' name=;   /* this goes only to the OUTPUT window (not LOG, not ODS) */

    return (h.check() = 0);
  endsub;
quit;

options cmplib=work.sandbox;
proc print data=sashelp.class;                 /* this goes to the ODS destinations */
  where found(name);
run;

dm 'output' output;
&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Art's paper also talks about how&amp;nbsp;FUTURE DEVELOPMENT should address the issue of keeping a hash table in memory &lt;STRONG&gt;across&lt;/STRONG&gt; step boundaries.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;---- Original post ----&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The paper &lt;A href="http://support.sas.com/resources/papers/proceedings13/129-2013.pdf" target="_self"&gt;"Hashing in PROC FCMP to Enhance Your Productivity"&lt;/A&gt;&amp;nbsp;&lt;SUB&gt;Andrew Henrick, Donald Erdman, and Stacey Christian&lt;/SUB&gt;&amp;nbsp;demonstrates how to use a hash in an FCMP function.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;data names;
  set sashelp.class;
  where name in: ('A' 'J');
run;

proc fcmp outlib=work.sandbox.functions;
  function found(name $);
    declare hash h(dataset: "work.names");
    rc = h.defineKey("name");
    rc = h.defineDone();
    return (h.check() = 0);
  endsub;
quit;

options cmplib=work.sandbox;
proc print data=sashelp.class;
  where found(name);
run;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;All well and good, except for the fact that the DECLARE statement in the function FOUND instantiates a hash and reads the table WORK.NAMES from disk into the hash EVERY TIME the function FOUND() is called from the where statement in the Proc PRINT.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Is there a setting or strategy for persisting the hash in memory between function calls ?&amp;nbsp; I would like to read the table one time, for the duration of the thread associated with the Proc PRINT.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This is a simple example, but the bigger application is exploring how to use hash, in an FCMP function, whose role is to act as a cache.&amp;nbsp; The data elements of the hash would be the result of a expensive i/o+cpu computation that would want to be avoided if the same set of inputs are passed to the function a second time.&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 21:32:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703621#M215624</guid>
      <dc:creator>RichardDeVen</dc:creator>
      <dc:date>2020-12-04T21:32:29Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a way to persist a hash in an FCMP function between function calls ?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703651#M215641</link>
      <description>&lt;P&gt;This paper might be helpful.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://www.sas.com/content/dam/SAS/support/en/sas-global-forum-proceedings/2018/2399-2018.pdf" target="_self"&gt;Using Memory Resident Hash Tables to Manage Your Lookup Control Files &lt;/A&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 15:04:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703651#M215641</guid>
      <dc:creator>data_null__</dc:creator>
      <dc:date>2020-12-04T15:04:20Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a way to persist a hash in an FCMP function between function calls ?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703653#M215642</link>
      <description>&lt;P&gt;Are you aware of any Function in any programming language that persists data from previous calls?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 15:09:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703653#M215642</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2020-12-04T15:09:50Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a way to persist a hash in an FCMP function between function calls ?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703660#M215647</link>
      <description>&lt;P&gt;In C, if you declare a variable as static.&lt;/P&gt;
&lt;P&gt;All RAND functions in SAS need to do that.&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 15:23:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703660#M215647</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2020-12-04T15:23:57Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a way to persist a hash in an FCMP function between function calls ?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703666#M215650</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;In C, if you declare a variable as static.&lt;/P&gt;
&lt;P&gt;All RAND functions in SAS need to do that.&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So a VARIABLE is static. Not a Function.&lt;/P&gt;
&lt;P&gt;I might be misunderstanding.&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 15:44:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703666#M215650</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2020-12-04T15:44:08Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a way to persist a hash in an FCMP function between function calls ?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703683#M215658</link>
      <description>&lt;P&gt;If a static variable is defined within a function definition, it is local to the function, but will persist from call to call.&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 17:33:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703683#M215658</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2020-12-04T17:33:02Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a way to persist a hash in an FCMP function between function calls ?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703712#M215673</link>
      <description>&lt;P&gt;Edited note:&amp;nbsp; I take everything below back.&amp;nbsp; Memory does not increase using the hash-inside-fcmp when I increased the number of observations (by a factor of 100) sent to proc print.&amp;nbsp; So apparently the object IS being removed from memory in each "iteration" of the proc print.&amp;nbsp; It is apparently not persisting.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/12477"&gt;@RichardDeVen&lt;/a&gt;&amp;nbsp;is not saying that the hash object doesn't persist - it's that successive function calls do not automatically recognize that the object is still in memory and presumably available.&amp;nbsp; Instead it honors the declare statement and makes a new one, with exactly the same name and content, i.e. a duplicate.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The fact that the object has the same name doesn't cause SAS to relinquish the memory taken up by the first instantiation.&amp;nbsp; (After all, that would defeat the ability to do hash-of-hashes).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So, no doubt that addition to the cpu and i/o expense of repeatedly reading in the data table, there will also be a giant memory cost as well.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Editted correction. Oops - just realized that this is for a proc, not a data step - so I presume _N_ is not available.&amp;nbsp; &lt;STRIKE&gt;Is the automatic variable _N_ available within proc fcmp?&amp;nbsp; If so, and if you always use the function at _n_=1, then I guess you could use the same "if _n_=1 then do" technique of instantiating the hash object.&amp;nbsp; &amp;nbsp;&lt;/STRIKE&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 20:24:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-way-to-persist-a-hash-in-an-FCMP-function-between/m-p/703712#M215673</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2020-12-04T20:24:26Z</dc:date>
    </item>
  </channel>
</rss>

