Multithreading, or the concurrent execution of threads, allows for substantial performance gains compared to sequential execution. For procedures running in CAS, the number of threads is determined by the installation. The multithreading model is primarily based on dividing the data processed on a single machine among the available threads. For example, if a table of 1,000 observations is processed by four threads, each thread handles 250 observations. All operations accessing data (such as variable normalization, matrix formation, calculation of objectives, gradients, Hessians, and observation scoring) are then multithreaded. Matrix operations also benefit from multithreading if the matrix size is sufficient to justify managing multiple threads.
Data Analysis
Type : CREATION_INTERNE
Examples use generated data (datalines) or SASHELP tables to ensure their autonomy.
1 Code Block
PROC FACTMAC Data
Explanation : This example illustrates a basic use of the FACTMAC procedure. It starts by creating a small CAS in-memory data table (`casuser.produits`). Then, `PROC FACTMAC` is executed on this table, specifying a simple model where 'prix' (price) is the dependent variable and 'produit' (product) and 'stock' are the predictors. The result is saved in a new CAS table, 'casuser.factmac_output'. Multithreading is automatically managed by the CAS server to optimize calculations, by distributing observations among available threads.
Copied!
/* Création d'une table CAS simple pour la démonstration */
data casuser.produits;
input produit $ prix stock;
datalines;
Pomme 1.0 100
Banane 0.5 200
Orange 1.2 150
Poire 0.8 120
Raisin 2.5 50
;
run;
/* Exécution basique de PROC FACTMAC */
proc factmac data=casuser.produits;
model prix = produit stock;
output out=casuser.factmac_output;
run;
/* Affichage des résultats (partiel) */
proc print data=casuser.factmac_output (obs=5);
run;
proc casutil incaslib="casuser";
droptable casdata="produits" quiet;
droptable casdata="factmac_output" quiet;
run;
1
/* Création d'une table CAS simple pour la démonstration */
2
DATA casuser.produits;
3
INPUT produit $ prix stock;
4
DATALINES;
5
Pomme 1.0100
6
Banane 0.5200
7
Orange 1.2150
8
Poire 0.8120
9
Raisin 2.550
10
;
11
RUN;
12
13
/* Exécution basique de PROC FACTMAC */
14
PROC FACTMACDATA=casuser.produits;
15
model prix = produit stock;
16
OUTPUT out=casuser.factmac_output;
17
RUN;
18
19
/* Affichage des résultats (partiel) */
20
PROC PRINTDATA=casuser.factmac_output (obs=5);
21
RUN;
22
23
PROC CASUTIL incaslib="casuser";
24
droptable casdata="produits" quiet;
25
droptable casdata="factmac_output" quiet;
26
RUN;
2 Code Block
PROC FOREST Data
Explanation : This example uses `PROC FOREST` to train a random forest model to predict customer loyalty. It includes common options such as `NTREE` to specify the number of trees to build, `MAXDEPTH` for the maximum depth of the trees, and `SEED` for reproducibility. Intensive calculations for tree building and data processing are automatically parallelized by CAS across multiple threads, accelerating model training. The results and the trained model are saved in CAS tables.
Copied!
/* Création d'une table CAS pour la démonstration de classification */
data casuser.clients;
call streaminit(123);
do i=1 to 1000;
age = rand('uniform', 18, 65);
revenu = rand('normal', 50000, 15000);
satisfaction_produit = ceil(rand('uniform', 1, 5));
if revenu > 60000 and age > 30 then
loyal = 1;
else
loyal = 0;
output;
end;
drop i;
run;
/* Exécution de PROC FOREST avec des options courantes */
proc forest data=casuser.clients;
input age revenu satisfaction_produit;
target loyal;
ods output FitStatistics=casuser.forest_stats;
train ntree=100 seed=1234 maxdepth=10;
save rstore=casuser.forest_model;
run;
/* Affichage des statistiques d'ajustement */
proc print data=casuser.forest_stats;
run;
proc casutil incaslib="casuser";
droptable casdata="clients" quiet;
droptable casdata="forest_stats" quiet;
droptable casdata="forest_model" quiet;
run;
1
/* Création d'une table CAS pour la démonstration de classification */
/* Exécution de PROC FOREST avec des options courantes */
18
PROC FORESTDATA=casuser.clients;
19
INPUT age revenu satisfaction_produit;
20
target loyal;
21
ods OUTPUT FitStatistics=casuser.forest_stats;
22
train ntree=100 seed=1234 maxdepth=10;
23
save rstore=casuser.forest_model;
24
RUN;
25
26
/* Affichage des statistiques d'ajustement */
27
PROC PRINTDATA=casuser.forest_stats;
28
RUN;
29
30
PROC CASUTIL incaslib="casuser";
31
droptable casdata="clients" quiet;
32
droptable casdata="forest_stats" quiet;
33
droptable casdata="forest_model" quiet;
34
RUN;
3 Code Block
PROC NNET Data
Explanation : This example demonstrates data scoring with a machine learning model, based on a common approach where a model (like NNET) would be trained and then used to predict on new data. Although `PROC NNET` itself is not explicitly called for training here (to simplify the demonstration without a complex pre-existing model), the concept of scoring a large volume of data is highly relevant to multithreading. The Data Step executes directly on data in CAS memory, and CAS automatically distributes computational tasks (here, scoring simulation) across multiple threads, allowing for efficient processing of large datasets.
Copied!
/* Création d'une table CAS avec des données de test */
data casuser.test_data;
call streaminit(456);
do i=1 to 200;
age = rand('uniform', 20, 70);
revenu = rand('normal', 60000, 20000);
satisfaction_produit = ceil(rand('uniform', 1, 5));
output;
end;
drop i;
run;
/* Utilisation d'un modèle NNET pré-entraîné (ici, simulé par des coefficients simples) */
/* Dans un scénario réel, un modèle NNET serait entraîné et sauvegardé */
/* Ici, nous simulons l'étape de scoring */
data casuser.scored_data;
set casuser.test_data;
/* Simulation d'un scoring simple basé sur les inputs */
score_loyal = 0.5 + 0.01 * age + 0.00001 * revenu - 0.1 * satisfaction_produit;
if score_loyal > 0.7 then predicted_loyal = 1; else predicted_loyal = 0;
run;
/* Affichage des données scorées */
proc print data=casuser.scored_data (obs=10);
run;
proc casutil incaslib="casuser";
droptable casdata="test_data" quiet;
droptable casdata="scored_data" quiet;
run;
1
/* Création d'une table CAS avec des données de test */
Explanation : This example uses `PROC GRADBOOST` to train a gradient boosting model on sales data, leveraging the distributed capabilities of CAS. The `PARTITION region_id` clause instructs CAS to process data by region, which can improve performance and scalability by distributing calculations across CAS nodes. Each partition can be processed in parallel by multiple threads. While there is no explicit `NTHREADS` option here, the underlying CAS server will automatically and efficiently allocate processing resources (i.e., threads) based on the environment configuration and data size, maximizing the benefit of multithreading for model training.
Copied!
/* Création d'une table CAS avec une variable de partitionnement */
data casuser.ventes;
call streaminit(789);
do i=1 to 5000;
region_id = ceil(rand('uniform', 1, 4)); /* 4 régions */
publicite = rand('uniform', 0, 1000);
prix = rand('uniform', 10, 100);
ventes_reelles = 500 + 2 * publicite - 3 * prix + (region_id * 100) + rand('normal', 0, 50);
output;
end;
drop i;
run;
/* Utilisation de PROC GRADBOOST avec PARTITION et options de thread (implicites CAS) */
proc gradboost data=casuser.ventes;
input publicite prix;
target ventes_reelles;
partition region_id;
/* Les options de multithreading sont gérées par le serveur CAS. */
/* L'option NTHREADS peut être utilisée dans certaines procs pour limiter explicitement. */
/* Ici, nous laissons CAS gérer l'allocation automatique des threads par défaut. */
ods output IterationHistory=casuser.gradboost_hist;
run;
/* Affichage de l'historique d'itération */
proc print data=casuser.gradboost_hist (obs=10);
run;
proc casutil incaslib="casuser";
droptable casdata="ventes" quiet;
droptable casdata="gradboost_hist" quiet;
run;
1
/* Création d'une table CAS avec une variable de partitionnement */
This material is provided "as is" by We Are Cas. There are no warranties, expressed or implied, as to merchantability or fitness for a particular purpose regarding the materials or code contained herein. We Are Cas is not responsible for errors in this material as it now exists or will exist, nor does We Are Cas provide technical support for it.
SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration. WeAreCAS is an independent community site and is not affiliated with SAS Institute Inc.
This site uses technical and analytical cookies to improve your experience.
Read more.