[Polly] Fix parallelism check for reductions
Tobias Grosser
tobias at grosser.es
Fri Jul 11 02:34:38 PDT 2014
On 10/07/2014 01:32, Johannes Doerfert wrote:
> Hey,
>
> We talked about this today and while I think it is correct I would like a
> last comment here.
> This patch basically is combined out of the [Fix] we discussed earlier and
> the initial (and I think "accepted") isl ast patch.
> I also added comments to parts which might be confusing or need attention in
> the future.
>
> What do you guys think?
> // The node is the innermost parallel loop.
> int IsInnermostParallel;
> +
> + // The node is only parallel because of reductions
// The node is parallel only if reductions are ignored or
privatized.
Reductions don't make a loop parallel, no?
> /// @brief The type of the dependences.
> ///
> - /// Reduction dependences are seperated because they can be ignored during
> - /// the scheduling. This is the case since the order in which the reduction
> - /// statements are executed does not matter. However, if they are executed
> - /// in parallel we need to take additional measures (e.g., privatization)
> - /// to ensure a correct result.
> + /// Reduction dependences are seperated from RAW/WAW/WAR dependences because
separated
> + /// we can ignore them during the scheduling. This is the case since the order
> + /// in which the reduction statements are executed does not matter. However,
> + /// if they are executed in parallel we need to take additional measures
> + /// (e.g, privatization) to ensure a correct result. The (reverse) transitive
> + /// closure of the reduction dependences are used to check for parallel
> + /// executed reduction statements during code generation.
> + ///
> + /// FIXME: As soon as the code generation can handle reductions we can get
> + /// rid of the current TYPE_RED dependences and rename the TYPE_TC_RED
> + /// to TYPE_RED.
I don't get this FIXME. What is needed in the code generation to remove
TC_RED? (You can just remove it, if you don't want to discuss this now).
> enum Type {
> // Write after read
> - TYPE_WAR = 0x1,
> + TYPE_WAR = 1 << 0,
>
> // Read after write
> - TYPE_RAW = 0x2,
> + TYPE_RAW = 1 << 1,
>
> // Write after write
> - TYPE_WAW = 0x4,
> + TYPE_WAW = 1 << 2,
>
> // Reduction dependences
> - TYPE_RED = 0x8,
> + TYPE_RED = 1 << 3,
> +
> + // Transitive closure of the reduction dependences (& the reverse)
Please describe how they look like, not how they are computed. Also, we
should mention here that thy are cyclic and possibly reversed.
> void Dependences::addPrivatizationDependences() {
> - isl_union_map *PrivRAW, *PrivWAW, *PrivWAR, *TransClosure;
> -
> - // The transitive closure might be over approximated but we only use it to
> - // compute the privatization dependences. Thus, overapproximation will lead
> - // "only" to more conservative privatization dependences.
> - // FIXME: Take precautions to ensure only forward dependences are created.
> - TransClosure = isl_union_map_transitive_closure(isl_union_map_copy(RED), 0);
> + isl_union_map *PrivRAW, *PrivWAW, *PrivWAR;
> +
> + // The transitive closure might be over approximated, thus could lead to
> + // dependency cycles in the privatization dependences. To make sure this
> + // will not happen we remove all negative dependences after we computed
> + // the transitive closure.
> + TC_RED = isl_union_map_transitive_closure(isl_union_map_copy(RED), 0);
> +
> + // FIXME: Apply the current schedule instead of assuming the identity schedule
> + // here. The current approach is only valid as long as we compute the
> + // dependences only with the initial (identity schedule). Any other
> + // schedule could change "the direction of the backward depenendes" we
> + // want to eliminate here.
> + isl_union_set *UDeltas = isl_union_map_deltas(isl_union_map_copy(TC_RED));
> + isl_union_set *Universe = isl_union_set_universe(isl_union_set_copy(UDeltas));
> + isl_union_set *Zero = isl_union_set_empty(isl_union_set_get_space(Universe));
> + isl_union_set_foreach_set(Universe, fixSetToZero, &Zero);
> + isl_union_map *NonPositive = isl_union_set_lex_le_union_set(UDeltas, Zero);
Did you face any issues with applying the schedule? Or you just decided
to leave it for later.
>
> +/// @brief Check if the current scheduling dimension is parallel
> +///
> +/// In case the dimension is parallel we also check if any reduction
> +/// dependences is broken when we exploit this parallelism. If so,
are
> +/// @p IsReductionParallel will be set to true. The reduction dependences we use
is set
> +/// to check are actually the union of the transitive closure of the initial
> +/// reduction dependences together with their reveresal. Even though these
> +/// dependences connect all iterations with each other (thus they are cyclic)
> +/// we can perform the parallelism check as we are only interested in a zero
> +/// (or non-zero) dependence distance on the dimension in question.
Otherwise looks good to me. Feel free to commit.
Cheers,
Tobias
More information about the llvm-commits
mailing list