sanha commented on a change in pull request #193: [NEMO-338] SkewSamplingPass
URL: https://github.com/apache/incubator-nemo/pull/193#discussion_r257978296
 
 

 ##########
 File path: 
compiler/optimizer/src/main/java/org/apache/nemo/compiler/optimizer/pass/compiletime/reshaping/SamplingSkewReshapingPass.java
 ##########
 @@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.nemo.compiler.optimizer.pass.compiletime.reshaping;
+
+import org.apache.nemo.common.KeyExtractor;
+import org.apache.nemo.common.dag.Edge;
+import org.apache.nemo.common.ir.IRDAG;
+import org.apache.nemo.common.ir.edge.IREdge;
+import org.apache.nemo.common.ir.edge.executionproperty.*;
+import org.apache.nemo.common.ir.vertex.IRVertex;
+import org.apache.nemo.common.ir.vertex.utility.MessageAggregatorVertex;
+import org.apache.nemo.common.ir.vertex.utility.MessageBarrierVertex;
+import org.apache.nemo.common.ir.vertex.utility.SamplingVertex;
+import org.apache.nemo.compiler.optimizer.pass.compiletime.Requires;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Optimizes the PartitionSet property of shuffle edges to handle data skews 
using the SamplingVertex.
+ *
+ * This pass effectively partitions the IRDAG by non-oneToOne edges, clones 
each subDAG partition using SamplingVertex
+ * to process sampled data, and executes each cloned partition prior to 
executing the corresponding original partition.
+ *
+ * Suppose the IRDAG is partitioned into two sub-DAGs as follows:
+ * P1 - P2
+ *
+ * Then, this pass will produce something like:
+ * P1' - P1 - P2
+ *          - P2' - P2
+ * where Px' consists of SamplingVertex objects that clone the execution of Px.
+ *
+ * For each Px' this pass also inserts a MessageBarrierVertex, to use its data 
statistics for dynamically optimizing
+ * the execution behaviors of Px.
+ */
+@Requires(CommunicationPatternProperty.class)
+public final class SamplingSkewReshapingPass extends ReshapingPass {
+  private static final Logger LOG = 
LoggerFactory.getLogger(SamplingSkewReshapingPass.class.getName());
+  private static final float SAMPLE_RATE = 0.1f;
+
+  /**
+   * Default constructor.
+   */
+  public SamplingSkewReshapingPass() {
+    super(SamplingSkewReshapingPass.class);
+  }
+
+  @Override
+  public IRDAG apply(final IRDAG dag) {
+    dag.topologicalDo(v -> {
+      for (final IREdge e : dag.getIncomingEdgesOf(v)) {
+        if (CommunicationPatternProperty.Value.Shuffle.equals(
+          e.getPropertyValue(CommunicationPatternProperty.class).get())) {
+          // Compute the partition and its source vertices
+          final IRVertex shuffleWriter = e.getSrc();
+          final Set<IRVertex> partitionAll = 
recursivelyBuildPartition(shuffleWriter, dag);
+          final Set<IRVertex> partitionSources = 
partitionAll.stream().filter(vertexInPartition ->
+            !dag.getIncomingEdgesOf(vertexInPartition).stream()
+              .map(Edge::getSrc)
+              .anyMatch(partitionAll::contains)
+          ).collect(Collectors.toSet());
+
+          // Insert sampling vertices.
+          final Set<SamplingVertex> samplingVertices = partitionAll
+            .stream()
+            .map(vertexInPartition -> new SamplingVertex(vertexInPartition, 
SAMPLE_RATE))
+            .collect(Collectors.toSet());
+          dag.insert(samplingVertices, partitionSources);
+
+          // Insert the message vertex.
+          // We first obtain a clonedShuffleEdge to analyze the data 
statistics of the shuffle outputs of
+          // the sampling vertex right before shuffle.
+          final SamplingVertex rightBeforeShuffle = samplingVertices.stream()
+            .filter(sv -> sv.getOriginalVertex().equals(e.getSrc()))
+            .findFirst()
+            .orElseThrow(() -> new IllegalStateException());
+          final IREdge clonedShuffleEdge = 
rightBeforeShuffle.getCloneOfOriginalEdge(e);
+
+          final KeyExtractor keyExtractor = 
e.getPropertyValue(KeyExtractorProperty.class).get();
 
 Review comment:
   We need to add control edges from the message aggregation vertex to the 
`partitionSources` instead of the vertex that receives the original shuffle 
edge.
   
   For the example DAG that is partitioned into two sub-DAGs as follows: P1 
-(shuffle)- P2,
   the expected outcome looks like P1' -(o2o)- MCV -(shuffle)- MAV -(control)- 
P1 -(shuffle)- p2.
   
   This is because that we **must** optimze the partitioning way of the target 
shuffle edge before the execution of P1.
   
   Also, the P1' and message collection vertex must be in a single stage. If 
not, the whole intermediate data will be duplicated.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to