Tracer pendant le balayage des paramètres avec parfor
Effectuez un balayage des paramètres en parallèle et tracez la progression pendant les calculs parallèles.
Vous pouvez utiliser un DataQueue
pour surveiller les résultats lors des calculs sur un pool parallèle. Vous pouvez également utiliser un DataQueue
avec des fonctionnalités de langage parallèle telles que parfor
, parfeval
et spmd
.
L'exemple montre comment effectuer un balayage de paramètres sur un système classique, l'oscillateur Van der Pol. Ce système peut être exprimé comme un ensemble d'ODE dépendant des deux paramètres de l'oscillateur Van der Pol, et :
Vous pouvez effectuer un balayage parallèle des paramètres sur les paramètres et à l'aide d'une boucle parfor
pour connaître la période moyenne de lors de leur variation. L'animation suivante montre une exécution de cet exemple dans un cluster local.
Configurer les valeurs de balayage des paramètres
Définissez la plage de valeurs des paramètres à explorer. Créez une grille maillée pour tenir compte des différentes combinaisons de paramètres.
gridSize = 6; mu = linspace(100, 150, gridSize); nu = linspace(0.5, 2, gridSize); [M,N] = meshgrid(mu,nu);
Préparez un tracé de surface pour visualiser les résultats
Déclarez une variable pour stocker les résultats du balayage. Utilisez nan
pour la préallocation afin d'éviter de tracer une surface initiale. Créez un tracé de surface pour visualiser les résultats du balayage pour chaque combinaison de paramètres. Préparez les paramètres tels que le titre, les étiquettes et les limites.
Z = nan(size(N)); c = surf(M, N, Z); xlabel('\mu Values','Interpreter','Tex') ylabel('\nu Values','Interpreter','Tex') zlabel('Mean Period of y') view(137, 30) axis([100 150 0.5 2 0 500]);
Configurer une DataQueue pour récupérer les résultats pendant le balayage des paramètres
Créez un DataQueue
pour envoyer les résultats intermédiaires des workers au client. Utilisez la fonction afterEach
pour définir un rappel dans le client qui met à jour la surface chaque fois qu'un worker envoie le résultat actuel.
D = parallel.pool.DataQueue; D.afterEach(@(x) updateSurface(c, x));
Effectuer le balayage des paramètres et tracer les résultats
Utilisez parfor
pour effectuer un balayage de paramètres parallèle. Demandez aux workers de résoudre le système pour chaque combinaison de paramètres dans la grille maillée et de calculer la période moyenne. Renvoyez immédiatement le résultat de chaque itération au client lorsque le worker termine les calculs.
parfor ii = 1:numel(N) [t, y] = solveVdp(M(ii), N(ii)); l = islocalmax(y(:, 2)); send(D, [ii mean(diff(t(l)))]); end
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Mise à l'échelle jusqu'à un cluster
Si vous avez accès à un cluster, vous pouvez augmenter votre calcul. Pour ce faire, supprimez le parpool
précédent et ouvrez-en un nouveau à l'aide du profil de votre cluster plus grand. Le code ci-dessous montre un profil de cluster nommé 'MyClusterInTheCloud'
. Pour exécuter ce code vous-même, vous devez remplacer 'MyClusterInTheCloud'
par le nom de votre profil de cluster. Ajustez le nombre de workers. L'exemple montre 4 ouvriers. Augmentez la taille du calcul global en augmentant la taille de la grille.
gridSize = 25; delete(gcp('nocreate')); parpool('MyClusterInTheCloud',4);
Starting parallel pool (parpool) using the 'MyClusterInTheCloud' profile ... Connected to the parallel pool (number of workers: 4).
Si vous exécutez à nouveau le code de balayage des paramètres après avoir défini le profil de cluster, les workers du cluster calculent et envoient les résultats au client MATLAB lorsqu'ils deviennent disponibles. L'animation suivante montre une exécution de cet exemple dans un cluster.
Fonctions d'assistance
Créez une fonction d'assistance pour définir le système d'équations et appliquez-lui le solveur.
function [t, y] = solveVdp(mu, nu) f = @(~,y) [nu*y(2); mu*(1-y(1)^2)*y(2)-y(1)]; [t,y] = ode23s(f,[0 20*mu],[2; 0]); end
Déclarez une fonction pour DataQueue afin de mettre à jour le graphique avec les résultats provenant des workers.
function updateSurface(s, d) s.ZData(d(1)) = d(2); drawnow('limitrate'); end