Contenu principal

Cette page a été traduite par traduction automatique. Cliquez ici pour voir la dernière version en anglais.

Variables découpées en tranches

Une variable découpée est une variable dont la valeur peut être divisée en segments, ou tranches, qui sont ensuite exploités séparément par différents workers. Chaque itération de la boucle fonctionne sur une tranche différente du tableau. L’utilisation de variables découpées peut réduire la communication entre le client et les workers.

Dans cet exemple, les workers appliquent f aux éléments de A séparément.

parfor i = 1:length(A)
    B(i) = f(A(i));
end

Caractéristiques d'une variable découpée

Si une variable dans une boucle parfor possède toutes les caractéristiques suivantes, alors la variable est découpée :

  • Type d'indexation de premier niveau — Le premier niveau d'indexation est constitué soit de parenthèses, (), soit d'accolades, {}.

  • Liste d’index fixes — Dans les parenthèses ou les accolades de premier niveau, la liste des indices est la même pour toutes les occurrences d’une variable donnée.

  • Forme d’indexation — Dans la liste des indices de la variable, un seul index implique la variable de boucle.

  • Forme du tableau — Le tableau conserve une forme constante. Lors de l'affectation à une variable découpée en tranches, le côté droit de l'affectation ne peut pas être [] ou '', car ces opérateurs tentent de supprimer des éléments.

Type d'indexation de premier niveau

Pour une variable découpée en tranches, le premier niveau d'indexation est placé entre parenthèses, (), ou entre accolades, {}.

Voici les formulaires pour le premier niveau d'indexation pour les tableaux qui sont découpés et non découpés.

Non tranchéTranché
A.xA(...)
A.(...)A{...}

Après le premier niveau, vous pouvez utiliser n’importe quel type d’indexation MATLAB® valide dans le deuxième niveau et les niveaux suivants.

La variable A montrée ici à gauche n'est pas découpée ; celle montrée à droite est découpée.

A.q{i,12}                         A{i,12}.q

Liste d'index fixe

Dans l'indexation de premier niveau d'une variable découpée, la liste des indices est la même pour toutes les occurrences d'une variable donnée.

La variable A à gauche n'est pas découpée car A est indexée par i et i+1 à des endroits différents. Dans le code de droite, la variable A est découpée correctement.

Non tranchéTranché
parfor i = 1:k
    B(:) = h(A(i), A(i+1));
end
parfor i = 1:k
    B(i) = f(A(i));
    C(i) = g(A{i});
end

L'exemple de droite montre des occurrences d'indexation de premier niveau utilisant à la fois des parenthèses et des accolades dans la même boucle, ce qui est acceptable.

L'exemple suivant à gauche ne découpe pas A car l'indexation de A n'est pas la même à tous les endroits. L'exemple de droite découpe à la fois A et B. L'indexation de A n'est pas la même que l'indexation de B . Cependant, l'indexation de A et B est cohérente individuellement.

Non tranchéTranché
parfor i=1:10
    b = A(1,i) + A(2,i)
end
A = [ 1  2  3  4  5  6  7  8  9  10; 
     10 20 30 40 50 60 70 80 90 100];
B = zeros(1,10);
parfor i=1:10
    for n=1:2
        B(i) = B(i)+A(n,i)
    end
end

Forme d'indexation

Au premier niveau d'indexation d'une variable découpée, une seule expression d'indexation est de la forme i, i+k, i-k ou k+i. L'index i est la variable de boucle et k est une constante entière scalaire ou une variable de diffusion simple (non indexée). Toute autre expression d'indexation est une constante entière positive, une variable de diffusion simple (non indexée), une variable d'index de boucle for imbriquée, colon, une expression deux points impliquant des variables de diffusion simples ou des constantes entières scalaires, ou end.

Avec i comme variable de boucle, les variables A affichées à gauche ne sont pas découpées, tandis que les variables A affichées à droite sont découpées.

Non tranchéTranché

A(i+f(k),j,:,3) % f(k) invalid for slicing
A(i,:,s.field1) % s.field1 not simple broadcast var
A(i,[20,21,30],end)  % array literal not supported

Avant R2024b :

A(i,20:30,end)

A(i+k,j,:,3)
A(i,:,end)
A(i,:,k)
A(i,20:30,end) (depuis R2024b)

Vous pouvez contourner les expressions d’indexation non prises en charge en les déclarant comme variables de diffusion. Dans cet exemple, le code de gauche ne fonctionne pas car il utilise directement des expressions d’indexation non prises en charge pour indexer les variables de tranche. Le code de droite fournit une solution de contournement en déclarant les expressions comme variables de diffusion avant le corps de la boucle.

Non tranchéTranché
parfor i = 1:n
  A(i, [false,true,true]) = 7; % not supported
  B(i, [20,21,30]) = 7; % also not supported
end
b1 = [false,true,true];
b2 = [20,21,30];
parfor i = 1:n
  A(i,b1) = 7; % works
  B(i,b2) = 7; % also works
end

Lorsque vous utilisez d'autres variables avec la variable de boucle pour indexer un tableau, vous ne pouvez pas définir ces variables à l'intérieur de la boucle. En effet, ces variables sont constantes pendant toute l’exécution de l’instruction parfor. Vous ne pouvez pas combiner la variable de boucle avec elle-même pour former une expression d'index.

Forme du tableau

Une variable découpée en tranches doit conserver une forme constante. La variable A affichée ici n'est pas découpée :

A(i,:) = [];

A n'est pas découpé car modifier la forme d'un tableau découpé violerait les hypothèses régissant la communication entre le client et les workers.

Variables d'entrée et de sortie découpées

Une variable découpée peut être une variable d'entrée, une variable de sortie ou les deux. MATLAB transmet les variables d'entrée découpées du client aux workers et les variables de sortie découpées des workers au client. Si une variable est à la fois une entrée et une sortie, elle est transmise dans les deux sens.

Dans cette boucle parfor, A est une variable d'entrée découpée et B est une variable de sortie découpée.

A = rand(1,10);
parfor ii = 1:10
    B(ii) = A(ii);
end

Cependant, si MATLAB détermine que, à chaque itération, les éléments variables découpés sont définis avant toute utilisation, alors MATLAB ne transmet pas la variable aux workers. Dans cet exemple, tous les éléments de A sont définis avant toute utilisation.

parfor ii = 1:n
    if someCondition
        A(ii) = 32;
    else
       A(ii) = 17;
    end
    % loop code that uses A(ii)
end

Les variables de sortie découpées peuvent croître de manière dynamique grâce à des affectations indexées avec des valeurs par défaut insérées à des indices intermédiaires. Dans cet exemple, vous pouvez voir que la valeur par défaut de 0 a été insérée à plusieurs endroits dans A .

A = [];
parfor idx = 1:10
    if rand < 0.5
        A(idx) = idx;
    end
end

disp(A);
     0     2     0     4     5     0     0     8     9    10

Même si une variable découpée n'est pas explicitement référencée comme entrée, une utilisation implicite peut le rendre ainsi. Dans l'exemple suivant, tous les éléments de A ne sont pas nécessairement définis à l'intérieur de la boucle parfor. Par conséquent, les valeurs originales du tableau sont reçues, conservées, puis renvoyées depuis la boucle.

A = 1:10;
parfor ii = 1:10
    if rand < 0.5
        A(ii) = 0;
    end
end

Dans certaines circonstances, les boucles parfor doivent supposer qu'un worker peut avoir besoin de tous les segments d'une variable découpée. Dans cet exemple, il n'est pas possible de déterminer quels éléments de la variable découpée seront lus avant l'exécution, donc parfor envoie tous les segments possibles.

A = 1:10;
parfor ii=1:11
    if ii <= randi([10 11])
        A(ii) = A(ii) + 1;
    end
end
Notez que dans ces circonstances, le code peut tenter d'indexer une variable découpée en dehors des limites du tableau et générer une erreur.

Boucles for imbriquées avec variables découpées

Lorsque vous indexez une variable découpée en tranches avec une variable de boucle for imbriquée, gardez ces exigences à l'esprit :

  • La variable découpée doit être incluse dans la boucle for correspondante.

    Dans cet exemple, le code de gauche ne fonctionne pas car il indexe la variable découpée A en dehors de la boucle for imbriquée qui définit j .

    Non tranchéTranché
    A = zeros(10);
    parfor i=1:10
        for j=1:10
        end
        A(i,j)=1;
    end
    A = zeros(10);
    parfor i=1:10
        for j=1:10
            A(i,j) = 1;
        end
    end
  • La plage de la variable for-loop doit être un vecteur de lignes de nombres constants positifs ou de variables.

    Dans cet exemple, le code de gauche ne fonctionne pas car il définit la limite supérieure de la boucle for imbriquée avec un appel de fonction. Le code de droite fournit une solution de contournement en définissant la limite supérieure dans une variable constante en dehors de la boucle parfor.

    Non tranchéTranché
    A = zeros(10);
    
    parfor i=1:10
        for j=1:size(A,2)
            A(i,j)=1;
        end
    end
    A = zeros(10);
    L = size(A,2);
    parfor i=1:10
        for j=1:L
            A(i,j)=1;
        end
    end
  • La variable de boucle for ne doit pas être affectée autrement que par son instruction for.

    Dans cet exemple, le code de gauche ne fonctionne pas car il réaffecte la variable for-loop à l'intérieur de la boucle for. Le code de droite fournit une solution de contournement en affectant i à la variable temporaire t .

    Non tranchéTranché
    A = zeros(10);                          
    parfor i=1:10
        for j=1:10
            if i == j
                j = i;
                A(i,j) = j;
            end
        end
    end
    A = zeros(10);
    parfor i=1:10
        for j=1:10
            if i == j
                t = i;
                A(i,j) = t;
            end
        end
    end

Limitations des types de données

  • Certains types de données MATLAB ne prennent pas en charge l'utilisation comme variables d'entrée ou de sortie découpées pour une boucle parfor. Pour utiliser une variable comme variable découpée, l'implémentation parfor doit pouvoir étendre la variable à l'aide de l'indexation.

    Les types de données suivants ne sont pas pris en charge en tant que variables découpées :

    • dictionary

    • table

  • Lorsque vous utilisez des tableaux découpés en tranches d'objets handle, MATLAB construit des éléments par défaut. Pour plus d'informations, voir Create and Initialize Object Arrays.

Voir aussi

Rubriques