0

This is a similar question as in here, but using OPTIONS MSTORED SASMSTORE instead. The issue is having functions stored in a library utils, and calling them inside a RSUBMIT statement. A minimum code would be like:

LIBNAME utils 'path/to/utils';
OPTIONS MSTORED SASMSTORE=utils;

%MACRO foo() / STORE;
*sas code;
%MEND foo;

%MACRO run_foo_parallel() / STORE;
options sascmd="sas"
SIGNON task;
RSUBMIT task;
%foo();
ENDRSUBMIT;
WAITFOR _all_;
SIGNOFF _all_;
%MEND;

In my real problem, I am parallelizing and running foo() in several datasets at a time. I don't know how to tell SAS to identify %foo(); in the correct utils folder. Things I've considered:

  • %SYSLPUT but this is only for macro variables
  • Use RSUBMIT task inheritlib(utils); and add OPTIONS MSTORED SASMSTORE=utils; inside the RSUBMIT. But then it raises an error A lock is not available for UTILS.SASMCR.CATALOG

Any help would be valuable! The "easy trick" is to write foo() inside the RSUBMIT without the STORE option, but it does not seem best practice.

Thank you all

1 Answers1

2

You can't run a macro defined in one session in another session. So make the macros available to both sessions. You have used these two lines to make %foo() available.

LIBNAME utils 'path/to/utils';
OPTIONS MSTORED SASMSTORE=utils;

So run those lines in the remote session before trying to call the macro.

SIGNON task;
RSUBMIT task;
  LIBNAME utils 'path/to/utils';
  OPTIONS MSTORED SASMSTORE=utils;
  %foo();
ENDRSUBMIT;

Make sure the path used in the remote session is valid where ever that session is running. Possibly you could upload the compiled macro catalog, similar to the file upload in the topic you linked. But that would require that the remove session is using the same version of SAS so that the catalog is readable.

Since you appear to be using this for parallel processing and not actually to connect to some SAS server that is actually remote then you can just setup the command you use to launch SAS to automatically setup the search path then just use !sascmd to launch the parallel sessions should yield the same setup.

So put the two setup lines in your AUTOEXEC (or config file or -initstmt command line option, etc.) so they run before the code in your actual program. Then when you spin up the parallel session using:

signon task cmd='!sascmd';

They will run also. So now both sessions have the same set of defined macros available.

Tom
  • 47,574
  • 2
  • 16
  • 29
  • Thank you! I forgot to specify that I had tried this option too. I get an error saying there is a lock on UTILS.SASMACR.CATALOG, similar to [here](https://stackoverflow.com/questions/50695952/a-lock-is-not-available-for-mylib-sasmacr-catalog). Would you expect that? Or your proposed code should work? I'll check the !sascmd option. – Marc de la Barrera i Bardalet Mar 08 '22 at 13:56
  • 1
    Did you try making sure that the libref used to point to the catalog is defined with the ACCESS=READONLY option? Or better have the file readonly at the filesystem level? Otherwise why not just use normal autocall functionality where each macro definition is stored in its own text file instead of bothering to create the catalog at all. – Tom Mar 08 '22 at 14:14
  • Using LIBNAME utils 'path' ACCESS=READONLY; solved the issue. But following your advice, I opted for the autocall functions. In each RSUBMIT, just add FILENAME whatever 'path'; and OPTIONS MAUTOSOURCE SASAUTOS = (SASAUTOS whatever) and worked as well. Thank's a lot! – Marc de la Barrera i Bardalet Mar 09 '22 at 15:59