Dépannage des variables dans les boucles parfor
Assurez-vous que les variables de boucle parfor
sont des entiers croissants consécutifs
Les variables de boucle dans une boucle parfor
doivent être des entiers consécutifs croissants. Pour cette raison, les exemples suivants renvoient des erreurs :
parfor i = 0:0.2:1 % not integers parfor j = 1:2:11 % not consecutive parfor k = 12:-1:1 % not increasing
iValues = 0:0.2:1; parfor idx = 1:numel(iValues) i = iValues(idx); ... end
Éviter les débordements dans les boucles parfor
Si MATLAB® détecte que la variable de boucle parfor
peut déborder, il signale une erreur.
Condition de débordement | Exemple | Solution |
---|---|---|
La longueur de la plage de boucle | Ici, MATLAB signale une erreur car parfor idx=int8(-128:127) idx; end | Utilisez un type de données plus grand pour la variable parfor idx=-128:127 int8(idx); end |
La valeur initiale de la plage de boucles | Ici, MATLAB signale une erreur car parfor idx=uint32(0:1) idx; end |
|
Résoudre les problèmes de classification des variables dans les boucles parfor
Lorsque MATLAB reconnaît un nom dans une boucle parfor
comme une variable, la variable est classée dans l'une des nombreuses catégories, présentées dans le tableau suivant. Assurez-vous que vos variables sont classées de manière unique et répondent aux exigences de la catégorie. Les boucles parfor
qui violent l'exigence renvoient une erreur.
Classification | Description |
---|---|
Variables de boucle | Indices de boucle |
Variables découpées en tranches | Tableaux dont les segments sont exploités par différentes itérations de la boucle |
Variables de diffusion | Variables définies avant la boucle dont la valeur est requise à l'intérieur de la boucle, mais jamais affectée à l'intérieur de la boucle |
Reduction Variables | Variables qui accumulent une valeur au fil des itérations de la boucle, quel que soit l'ordre d'itération |
Variables temporaires | Variables créées à l'intérieur de la boucle et non accessibles en dehors de la boucle |
Pour savoir quelles variables vous avez, examinez le fragment de code. Toutes les classifications de variables dans le tableau sont représentées dans ce code :
Si vous rencontrez des problèmes de classification de variables, envisagez ces approches avant de recourir à la méthode plus difficile consistant à convertir le corps d'une boucle parfor
en fonction.
Si vous utilisez une boucle
for
imbriquée pour indexer dans un tableau découpé, vous ne pouvez pas utiliser ce tableau ailleurs dans la boucleparfor
. Le code de gauche ne fonctionne pas carA
est découpé et indexé à l'intérieur de la bouclefor
imbriquée. Le code de droite fonctionne carv
est attribué àA
en dehors de la boucle imbriquée. Vous pouvez calculer une ligne entière, puis effectuer une seule affectation dans la sortie découpée.Invalide Valide A = zeros(4, 10); parfor i = 1:4 for j = 1:10 A(i, j) = i + j; end disp(A(i, 1)) end
A = zeros(4, 10); parfor i = 1:4 v = zeros(1, 10); for j = 1:10 v(j) = i + j; end disp(v(1)) A(i, :) = v; end
Le code de gauche ne fonctionne pas car la variable
x
dansparfor
ne peut pas être classée. Cette variable ne peut pas être classée car il existe plusieurs affectations à différentes parties dex
. Par conséquent,parfor
ne peut pas déterminer s’il existe une dépendance entre les itérations de la boucle. Le code de droite fonctionne car vous écrasez complètement la valeur dex
.parfor
peut désormais déterminer sans ambiguïté quex
est une variable temporaire.Invalide Valide parfor idx = 1:10 x(1) = 7; x(2) = 8; out(idx) = sum(x); end
parfor idx = 1:10 x = [7, 8]; out(idx) = sum(x); end
Cet exemple montre comment découper le champ d'un tableau structuré. Voir
struct
pour plus de détails. Le code de gauche ne fonctionne pas car la variablea
dansparfor
ne peut pas être classée. Cette variable ne peut pas être classée car la forme d’indexation n’est pas valide pour une variable découpée. Le premier niveau d'indexation n'est pas l'opération d'indexation en tranches, même si le champx
dea
semble être découpé correctement. Le code de droite fonctionne car vous extrayez le champstruct
dans une variable séparéetmpx
.parfor
peut désormais déterminer correctement que cette variable est découpée. En général, vous ne pouvez pas utiliser les champs destruct
ou les propriétés d'objets comme variables d'entrée ou de sortie découpées dansparfor
.Invalide Valide a.x = []; parfor idx = 1:10 a.x(idx) = 7; end
tmpx = []; parfor idx = 1:10 tmpx(idx) = 7; end a.x = tmpx;
Tableaux de structures dans les boucles parfor
Créer des structures temporaires
Vous ne pouvez pas créer une structure dans une boucle parfor
en utilisant l'affectation de notation par points. Dans le code de gauche, les deux lignes à l’intérieur de la boucle génèrent une erreur de classification. Dans le code de droite, comme solution de contournement, vous pouvez utiliser la fonction struct
pour créer la structure dans la boucle ou dans le premier champ.
Invalide | Valide |
---|---|
parfor i = 1:4 temp.myfield1 = rand(); temp.myfield2 = i; end | parfor i = 1:4 temp = struct(); temp.myfield1 = rand(); temp.myfield2 = i; end parfor i = 1:4 temp = struct('myfield1',rand(),'myfield2',i); end |
Champs de structure de découpage
Vous ne pouvez pas utiliser de champs de structure comme tableaux d'entrée ou de sortie découpés dans une boucle parfor
En d’autres termes, vous ne pouvez pas utiliser la variable de boucle pour indexer les éléments d’un champ de structure. Dans le code de gauche, les deux lignes de la boucle génèrent une erreur de classification à cause de l'indexation. Dans le code de droite, comme solution de contournement pour la sortie découpée, vous utilisez des tableaux découpés séparés dans la boucle. Ensuite, vous attribuez les champs de structure une fois la boucle terminée.
Invalide | Valide |
---|---|
parfor i = 1:4 outputData.outArray1(i) = 1/i; outputData.outArray2(i) = i^2; end | parfor i = 1:4 outArray1(i) = 1/i; outArray2(i) = i^2; end outputData = struct('outArray1',outArray1,'outArray2',outArray2); |
La solution de contournement pour l'entrée découpée consiste à affecter le champ de structure à un tableau distinct avant la boucle. Vous pouvez utiliser ce nouveau tableau pour l’entrée découpée.
inArray1 = inputData.inArray1; inArray2 = inputData.inArray2; parfor i = 1:4 temp1 = inArray1(i); temp2 = inArray2(i); end
Conversion du corps d'une boucle parfor
en fonction
Si tout le reste échoue, vous pouvez généralement résoudre les problèmes de classification de variables dans les boucles parfor
en convertissant le corps de la boucle parfor
en une fonction. Dans le code de gauche, Code Analyzer signale un problème avec la variable y, mais ne peut pas le résoudre. Dans le code de droite, vous résolvez ce problème en convertissant le corps de la boucle parfor
en une fonction.
Invalide | Valide |
---|---|
function parfor_loop_body_bad data = rand(5,5); means = zeros(1,5); parfor i = 1:5 % Code Analyzer flags problem % with variable y below y.mean = mean(data(:,i)); means(i) = y.mean; end disp(means); end | function parfor_loop_body_good data = rand(5,5); means = zeros(1,5); parfor i = 1:5 % Call a function instead means(i) = computeMeans(data(:,i)); end disp(means); end % This function now contains the body % of the parfor-loop function means = computeMeans(data) y.mean = mean(data); means = y.mean; end Starting parallel pool (parpool) using the 'Processes' profile ... connected to 4 workers. 0.6786 0.5691 0.6742 0.6462 0.6307 |
Noms de variables sans ambiguïté
Si vous utilisez un nom que MATLAB ne peut pas distinguer sans ambiguïté en tant que variable à l'intérieur d'une boucle parfor
, au moment de l'analyse, MATLAB suppose que vous faites référence à une fonction. Ensuite, au moment de l'exécution, si la fonction ne peut pas être trouvée, MATLAB génère une erreur. Voir Variable Names . Par exemple, dans le code suivant, f(5)
pourrait faire référence soit au cinquième élément d'un tableau nommé f
, soit à une fonction nommée f
avec un argument de 5
. Si f
n'est pas clairement défini comme variable dans le code, MATLAB recherche la fonction f
sur le chemin lorsque le code s'exécute.
parfor i = 1:n ... a = f(5); ... end
Boucles parfor
transparentes
Le corps d'une boucle parfor
doit être transparent : toutes les références aux variables doivent être «visibles» dans le texte du code. Pour plus de détails sur la transparence, voir Ensure Transparency in parfor-Loops or spmd Statements .
Variables globales et persistantes
Le corps d'une boucle parfor
ne peut pas contenir de déclarations de variables global
ou persistent
.
Voir aussi
Rubriques
- Décider quand utiliser parfor
- Convertir les boucles for en boucles parfor
- Ensure That parfor-Loop Iterations Are Independent
- Boucles imbriquées parfor et for et autres exigences parfor
- Ensure Transparency in parfor-Loops or spmd Statements
- Use parfor-Loops for Reduction Assignments
- Run Parallel Simulations (Simulink)