Module: PRuby::PArrayRange

Defined in:
lib/pruby/array-range.rb

Overview

Definition des methodes paralleles qui s'appliquent directement (et uniquement) a des Array ou des Range.

Les methodes publiques sont les suivantes:

  • peach

  • peach_index

  • pmap

  • preduce

Ces methodes sont definies dans le present module, mais ensuite les classes Array et Range sont etendues avec ces methodes (vie des includes).

Instance Method Summary collapse

Instance Method Details

#peach(opts = {}, &b) ⇒ self, self.to_a

Note:

Par defaut, si aucune option n’est specifiee, ceci est equivalent a utiliser PRuby.nb_threads threads avec un mode :static true. Donc: “pfoo()” = “pfoo( nb_threads: PRuby.nb_threads, static: true )” (pour pfoo = peach, peach_index, pmap, preduce).

Execute un bloc de code sur chacun des elements d'un Array ou Range

Examples:

a = [10, 20, 30]
b = Array.new(3)
r = a.peach { |x| b[x / 10 - 1] = x + 1 }
a == [10, 20, 30]
r.equal? a
b == [11, 21, 31]

Parameters:

  • b

    Le bloc a executer

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :nb_threads (Fixnum)

    Le nombre de threads avec lesquels on desire que le traitement soit fait

  • :static (Bool)

    si true alors repartition uniforme par tranches d’elements adjacents

  • :static (Fixnum)

    Distribution cyclique en groupe de :static elements

  • :dynamic (Bool)

    si true alors dynamique avec taille de tache = 1

  • :dynamic (Fixnum)

    Distribution dynamique avec taille de tache = :dynamic

Returns:

  • (self, self.to_a)

    Le tableau initial ou un tableau obtenu du Range (avec to_a)



41
42
43
44
45
# File 'lib/pruby/array-range.rb', line 41

def peach( opts = {}, &b )
  return to_a.peach( opts, &b ) if self.class == Range

  __pforall__( self, false, opts, &b )
end

#peach_index(opts = {}, &b) ⇒ self

Note:

Par defaut, si aucune option n’est specifiee, ceci est equivalent a utiliser PRuby.nb_threads threads avec un mode :static true. Donc: “pfoo()” = “pfoo( nb_threads: PRuby.nb_threads, static: true )” (pour pfoo = peach, peach_index, pmap, preduce).

Execute un bloc de code sur chacun des indices d'un Array

Examples:

a = [10, 20, 30]
b = Array.new(3)
r = a.peach_index { |k| b[k] = k + 1 }
a == [10, 20, 30]
r.equal? a
b == [1, 2, 3]

Parameters:

  • b

    Le bloc a executer

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :nb_threads (Fixnum)

    Le nombre de threads avec lesquels on desire que le traitement soit fait

  • :static (Bool)

    si true alors repartition uniforme par tranches d’elements adjacents

  • :static (Fixnum)

    Distribution cyclique en groupe de :static elements

  • :dynamic (Bool)

    si true alors dynamique avec taille de tache = 1

  • :dynamic (Fixnum)

    Distribution dynamique avec taille de tache = :dynamic

Returns:

  • (self)

    Le tableau initial ou un tableau obtenu du Range (avec to_a)

Requires:

  • self.class != Range



62
63
64
65
66
67
# File 'lib/pruby/array-range.rb', line 62

def peach_index( opts = {}, &b )
  DBC.require( self.class != Range,
               "*** La methode peach_index ne peut pas etre utilisee avec un Range" )

  __pforall__( self, true, opts, &b )
end

#pmap(opts = {}, &b) ⇒ Array

Note:

Par defaut, si aucune option n’est specifiee, ceci est equivalent a utiliser PRuby.nb_threads threads avec un mode :static true. Donc: “pfoo()” = “pfoo( nb_threads: PRuby.nb_threads, static: true )” (pour pfoo = peach, peach_index, pmap, preduce).

Applique un bloc de code sur chacun des elements d'un Array ou Range pour produire un nouvel Array avec les resultats

Examples:

a = [10, 20, 30]
r = a.pmap { |x| x+1 }
a == [10, 20, 30]
r == [11, 21, 31]

Parameters:

  • b

    Le bloc a executer

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :nb_threads (Fixnum)

    Le nombre de threads avec lesquels on desire que le traitement soit fait

  • :static (Bool)

    si true alors repartition uniforme par tranches d’elements adjacents

  • :static (Fixnum)

    Distribution cyclique en groupe de :static elements

  • :dynamic (Bool)

    si true alors dynamique avec taille de tache = 1

  • :dynamic (Fixnum)

    Distribution dynamique avec taille de tache = :dynamic

Returns:

  • (Array)

    Un nouveau tableau contenant le resultat de l’application du bloc sur chacun des elements du tableau ou range initial



82
83
84
85
86
# File 'lib/pruby/array-range.rb', line 82

def pmap( opts = {}, &b )
  return to_a.pmap( opts, &b ) if self.class == Range

  __pforall__( Array.new(size), false, opts, &b )
end

#preduce(val_initiale, opts = {}, &b) ⇒ T, Fixnum

Note:

Utilise toujours une repartition statique par tranche d’elements adjacents! Raison: pcq. trop complique de faire autrement… mais surtout pas necessaire, car il n’y a pas (il ne devrait pas y avoir!?) vraiment de difference dans le temps d’execution entre les taches!

Note:

La valeur initiale est utilisee… par chacun des threads! Ceci implique que si cette valeur n’est pas un element neutre de l’operation binaire, alors le resultat final dependra du nombre de threads utilises. Donc, il est preferable d’utiliser un element neutre.

Applique un bloc, qui devrait avoir deux arguments et etre associatif, pour produire la reduction des elements d'un Array ou d'un Range.

Examples:

a = [10, 20, 30]
r = a.preduce(0) { |x, y| x+y }
r == 60
a == [10, 20, 30]

r = a.preduce(23) { |x, y| [x, y].max }
r == 30
r = a.preduce(99) { |x, y| [x, y].max }
r == 99

a = [11, 2, 30, 40, 40, 39, 38, 5, 6]
r = a.preduce(0, nb_threads: 3, final_reduce: :+) do |m, x|
  [m, x].max
end
r == 30 + 40 + 38

Parameters:

  • val_initiale

    Valeur initiale a utiliser, qui devrait etre l’element neutre si l’operation est cumulative (+, *, etc.)

  • b

    Le bloc de code a executer sur chacun des elements d’une tranche

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :nb_threads (Fixnum)

    Le nombre de threads avec lesquels on desire que le traitement soit fait

  • :final_reduce (Symbol, Proc)

    L’operateur binaire a utiliser pour la reduction finale des resultats intermediaires (generalement associatif)

Returns:

  • (T, Fixnum)

    La valeur finale reduite. Si self.class == Array<T> alors return.class == T sinon return.class = Fixnum

Requires:

  • Le bloc recoit deux arguments… et devrait etre associatif

  • La fonction final_reduce recoit deux arguments… et devrait etre associative



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/pruby/array-range.rb', line 131

def preduce( val_initiale, opts = {}, &b )
  return to_a.preduce( val_initiale, opts, &b ) if self.class == Range

  return val_initiale if size == 0

  nb_threads = __nombre_de_threads__( opts[:nb_threads], size )
  resultat = (0...nb_threads).map { val_initiale }
  fork_and_wait_threads_adj( nb_threads, nil, true ) do |i|
    resultat[PRuby.thread_index] = yield( resultat[PRuby.thread_index], self[i] )
  end

  # La reduction finale peut devoir etre faite de facon differente.
  b = opts[:final_reduce] if opts[:final_reduce]
  resultat.reduce(&b)
end