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
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.