Hi SAS Communities!
I'm working on extending SAS Packages Framework (https://github.com/yabwon/SAS_PACKAGES) with new type: "CASLUDF" i.e., CAS-L user defined functions.
During the process the following question arose.
Lets assume I have this code:
proc fcmp outlib = work.f.p;
function fcmpFunction(x);
return(x*10);
endsub;
run;
options cmplib=work.f;
data _null_;
x = 17;
y = fcmpFunction(x);
put "x=" x "y=" y;
run;
so I have valid and working FCMP function to "solve my programming challenges".
Now I want to create new CAS-L user defined function:
proc cas;
/* insert code here */
function CASLfunction(x);
RETURN( fcmpFunction(x) + 1) ; /* <- here I want to use the FCMP function */
end func;
x = 17;
y = CASLfunction(x);
print "x=" x "y=" y;
quit;
The question is:
How can I modify above Proc CAS code (if it is possible at all) to use the FCMP function inside a CAS-L user defined function?
Is it documented some where?
I read the doc. about the "FCMP Action Set" but it seems to be doing job "in other way round", like: create FCMP function from within Proc CAS and store it inside a data set. For further use in data step.
All the best
Bart
The PROC FCMP in your example is running on the SAS client. I suspect you want the functions available on the CAS server so that you can call it from, for example, a DATA step running in CAS or the dataStep.runCode action. See the example in the FCMP action set ("fcmpact"): https://go.documentation.sas.com/doc/en/pgmsascdc/v_031/caspg/p08cbowc5u7okdn15wp2hmuuwrk4.htm
Hi Rick ( @Rick_SAS ) Thanks for the link! 🙂
I read that one already and it is not what I'm looking for.
My case is: I already have a dataset with FCMP functions. Question is how can I use those functions inside Proc CAS?
Second thing is that it looks like the doc. page is for latest release and not for Viya 3.5. 😞
When I executed this:
libname sascas1 cas caslib=casuser;
proc cas;
loadactionset "fcmpact";
setSessOpt{cmplib="casuser.f"};
run;
source BS_code; /**/
function fcmpFunction(x);
return(x*10);
endfunc;
endsource;
fcmpact.addRoutines /
saveTable = true,
funcTable = {name="f", caslib="casuser", replace=true},
package = "myPackage",
routineCode = BS_code;
run;
quit;
options fullstimer msglevel=I;
options cmplib=sascas1.f;
data sascas1.class;
set sashelp.class(obs=2);
run;
data _null_;
set sascas1.class;
x = 17;
y = fcmpFunction(x);
put "x=" x "y=" y;
run;
All steps except the last one run successfully (including note: "NOTE: Cloud Analytic Services saved the file F.sashdat in caslib CASUSER"), but the last data step gave:
115 data _null_; 116 set sascas1.class; 117 x = 17; 118 y = fcmpFunction(x); NOTE: The where clause is being processed by Cloud Analytic Services. NOTE: The where clause is being processed by Cloud Analytic Services. NOTE: No CMP or C functions found in library sascas1.f. 118 y = fcmpFunction(x); ------------ 68 ERROR 68-185: The function FCMPFUNCTION is unknown, or cannot be accessed. 119 put "x=" x "y=" y; 120 run; NOTE: The SAS System stopped processing this step because of errors.
There is also a big chance that I'm doing something wrong. 🙂
All the best
Bart
I can verify that your program works in Viya 4. I do not have Viya 3.5, so someone else will have to assist you.
Hi Bart @yabwon,
running Viya 3.5 I get exactly the same error.
There's a problem note but the fix does not work for me either.
https://support.sas.com/kb/62/620.html
What DOES work is to use the sas code within a cas fcmpact.runProgramm block.
In a data step it keeps giving error.
cas mySession sessopts=(caslib="casuser");
data casuser.cars;
set sashelp.cars;
run;
proc cas;
table.fetch / table={name="cars" caslib="casuser"} to=5;
run;
sessionProp.setSessOpt / cmplib="CASUSER.MULTIPLICATION ";
run;
fcmpact.addRoutines /
routineCode = "
function times2( a );
return(a*2);
endsub;
function times10( a );
return(a*10);
endsub;
function times3( a );
return(a*3);
endsub;"
package = "pkg"
saveTable = true
funcTable = {name="multiplication" replace=true};
run;
fcmpact.runProgram /
routineCode = "
length make_and_model varchar(*);
hp2 = times10(horsepower); /* Add a numeric variable. */
mpg_highway = hp2 + times3(mpg_highway); /* Replace a numeric variable. */
make_and_model = make || ', ' || model; /* Add a varchar variable. */
"
inputData={name="cars"}
outputData={name="cars_modified" replace=true};
run;
table.fetch /
table="cars_modified"
fetchVars={"make_and_model", "horsepower", "hp2", "mpg_highway"}
to=5;
run;
quit;
I wrote a blog about doing it. Here is the blog and code: https://blogs.sas.com/content/sgf/2023/10/30/create-user-defined-functions-udfs-for-the-cas-server-o...
Hi Peter! ( @Panagiotis )
Thanks for the link, very interesting article. I enjoyed reading and learned something new.
Unfortunately it still does not answers my question.
In my question I had a SAS dataset generated by FCMP as an input rather than "text of a function code" (like in your "source" statement).
But I guess I can do a workaround myself by creating a new text variable which concatenates (as a text string) the "Value" variable from the FCMP's dataset and push the result then to the actionSet, right ?
All the best
Bart
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.