Namespaces
Variants

std::experimental::parallel:: transform_reduce

From cppreference.net
Défini dans l'en-tête <experimental/numeric>
template < class InputIt, class UnaryOp, class T, class BinaryOp >

T transform_reduce ( InputIt first, InputIt last,

UnaryOp unary_op, T init, BinaryOp binary_op ) ;
(1) (TS parallélisme)
template < class ExecutionPolicy,

class InputIt, class UnaryOp, class T, class BinaryOp >
T transform_reduce ( ExecutionPolicy && policy,
InputIt first, InputIt last,

UnaryOp unary_op, T init, BinaryOp binary_op ) ;
(2) (TS parallélisme)

Applique unary_op à chaque élément dans l'intervalle [ first , last ) et réduit les résultats (éventuellement permutés et agrégés de manière non spécifiée) avec la valeur initiale init via binary_op .

Le comportement est non déterministe si binary_op n'est pas associatif ou n'est pas commutatif.

Le comportement est indéfini si unary_op ou binary_op modifie un élément quelconque ou invalide un itérateur dans [ first , last ) .

Table des matières

Paramètres

first, last - la plage d'éléments à laquelle appliquer l'algorithme
init - la valeur initiale de la somme généralisée
policy - la politique d'exécution
unary_op - FunctionObject unaire qui sera appliqué à chaque élément de la plage d'entrée. Le type de retour doit être acceptable en entrée pour binary_op
binary_op - FunctionObject binaire qui sera appliqué dans un ordre non spécifié aux résultats de unary_op , aux résultats d'autres binary_op et à init
Exigences de type
-
InputIt doit satisfaire aux exigences de LegacyInputIterator .

Valeur de retour

Somme généralisée de init et unary_op ( * first ) , unary_op ( * ( first + 1 ) ) , ... unary_op ( * ( last - 1 ) ) sur binary_op , où la somme généralisée GSUM(op, a 1 , ..., a N ) est définie comme suit :

  • si N = 1 , a 1 ,
  • si N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N ))
  • b 1 , ..., b N peut être n'importe quelle permutation de a1, ..., aN et
  • 1 < K + 1 = M ≤ N

en d'autres termes, les résultats de unary_op peuvent être groupés et arrangés dans un ordre arbitraire.

Complexité

O(last - first) applications de chacune des fonctions unary_op et binary_op .

Exceptions

  • Si l'exécution d'une fonction invoquée dans le cadre de l'algorithme lève une exception,
  • si policy est parallel_vector_execution_policy , std::terminate est appelé.
  • si policy est sequential_execution_policy ou parallel_execution_policy , l'algorithme se termine avec une exception_list contenant toutes les exceptions non capturées. S'il n'y avait qu'une seule exception non capturée, l'algorithme peut la relancer sans l'encapsuler dans exception_list . Il n'est pas spécifié combien de travail l'algorithme effectuera avant de retourner après la première exception rencontrée.
  • si policy est d'un autre type, le comportement est défini par l'implémentation.
  • Si l'algorithme ne parvient pas à allouer de la mémoire (soit pour lui-même, soit pour construire une exception_list lors de la gestion d'une exception utilisateur), std::bad_alloc est levée.

Notes

unary_op n'est pas appliqué à init .

Si la plage est vide, init est retourné, inchangé.

  • Si policy est une instance de sequential_execution_policy , toutes les opérations sont exécutées dans le thread appelant.
  • Si policy est une instance de parallel_execution_policy , les opérations peuvent être exécutées dans un nombre non spécifié de threads, de manière séquentiellement indéterminée les unes par rapport aux autres.
  • Si policy est une instance de parallel_vector_execution_policy , l'exécution peut être parallélisée et vectorisée : les limites du corps de fonction ne sont pas respectées et le code utilisateur peut être entrelacé et combiné de manière arbitraire (cela implique notamment qu'un Callable fourni par l'utilisateur ne doit pas acquérir de mutex pour accéder à une ressource partagée).

Exemple

transform_reduce peut être utilisé pour paralléliser std::inner_product :

#include <boost/iterator/zip_iterator.hpp>
#include <boost/tuple.hpp>
#include <experimental/execution_policy>
#include <experimental/numeric>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
    std::vector<double> xvalues(10007, 1.0), yvalues(10007, 1.0);
    double result = std::experimental::parallel::transform_reduce(
        std::experimental::parallel::par,
        boost::iterators::make_zip_iterator(
            boost::make_tuple(std::begin(xvalues), std::begin(yvalues))),
        boost::iterators::make_zip_iterator(
            boost::make_tuple(std::end(xvalues), std::end(yvalues))),
        [](auto r) { return boost::get<0>(r) * boost::get<1>(r); }
        0.0,
        std::plus<>()
    );
    std::cout << result << '\n';
}

Sortie :

10007

Voir aussi

additionne ou plie une série d'éléments
(modèle de fonction)
applique une fonction à une série d'éléments, stockant les résultats dans une plage de destination
(modèle de fonction)
(parallelism TS)
similaire à std::accumulate , mais sans ordre
(modèle de fonction)