You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@spark.apache.org by mengxr <gi...@git.apache.org> on 2014/06/18 01:48:49 UTC

[GitHub] spark pull request: [WIP][SPARK-2174][MLLIB] treeReduce and treeAg...

GitHub user mengxr opened a pull request:

    https://github.com/apache/spark/pull/1110

    [WIP][SPARK-2174][MLLIB] treeReduce and treeAggregate

    In `reduce` and `aggregate`, the driver node spends linear time on the number of partitions. It becomes a bottleneck when there are many partitions and the data from each partition is big.
    
    SPARK-1485 (#506) tracks the progress of implementing AllReduce on Spark. I did several implementations including butterfly, reduce + broadcast, and treeReduce + broadcast. treeReduce + BT broadcast seems to be right way to go for Spark. Using binary tree may introduce some overhead in communication, because the driver still need to coordinate on data shuffling. In my experiments, n -> sqrt(n) -> 1 gives the best performance in general, which is why I set "depth = 2" in MLlib algorithms. But it certainly needs more testing.
    
    I left `treeReduce` and `treeAggregate` public for easy testing.

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/mengxr/spark tree

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/spark/pull/1110.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #1110
    
----
commit fe42a5e8f5d002d22bd53a4cbcb81607efa10ab1
Author: Xiangrui Meng <me...@databricks.com>
Date:   2014-06-17T08:16:01Z

    add treeAggregate

commit eb71c330973fe3392a08882788553fcba28e7541
Author: Xiangrui Meng <me...@databricks.com>
Date:   2014-06-17T08:40:03Z

    add treeReduce

commit 0f944908cb4b5ce8b91456d103d913bfbf764687
Author: Xiangrui Meng <me...@databricks.com>
Date:   2014-06-17T08:52:20Z

    add docs

commit be6a88a9ddebb26111b2df339f8e2217eec73033
Author: Xiangrui Meng <me...@databricks.com>
Date:   2014-06-17T09:08:46Z

    use treeAggregate in mllib

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50446850
  
    QA results for PR 1110:<br>- This patch FAILED unit tests.<br>- This patch merges cleanly<br>- This patch adds no public classes<br><br>For more information see test ouptut:<br>https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17345/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [WIP][SPARK-2174][MLLIB] treeReduce and treeAg...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-46380509
  
    Merged build started. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508295
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    --- End diff --
    
    is this used at all? if not maybe we don't need it?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508808
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    if (self.partitions.size == 0) {
    +      return Utils.clone(zeroValue, self.context.env.closureSerializer.newInstance())
    +    }
    +    val cleanSeqOp = self.context.clean(seqOp)
    +    val cleanCombOp = self.context.clean(combOp)
    +    val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)
    +    var local = self.mapPartitions(it => Iterator(aggregatePartition(it)))
    +    var numPartitions = local.partitions.size
    +    val scale = math.max(math.ceil(math.pow(numPartitions, 1.0 / depth)).toInt, 2)
    +    while (numPartitions > scale + numPartitions / scale) {
    +      numPartitions /= scale
    +      local = local.mapPartitionsWithIndex { (i, iter) =>
    +        iter.map((i % numPartitions, _))
    +      }.reduceByKey(new HashPartitioner(numPartitions), cleanCombOp).values
    --- End diff --
    
    that would be great ~


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508571
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/linalg/distributed/RowMatrix.scala ---
    @@ -104,13 +105,11 @@ class RowMatrix(
         val nt: Int = n * (n + 1) / 2
     
         // Compute the upper triangular part of the gram matrix.
    -    val GU = rows.aggregate(new BDV[Double](new Array[Double](nt)))(
    +    val GU = rows.treeAggregate(new BDV[Double](new Array[Double](nt)))(
           seqOp = (U, v) => {
             RowMatrix.dspr(1.0, v, U.data)
             U
    -      },
    -      combOp = (U1, U2) => U1 += U2
    -    )
    +      }, combOp = (U1, U2) => U1 += U2, depth = 2)
    --- End diff --
    
    maybe you can set depth to be 2 by default so you don't need to repeat this ...


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50451405
  
    QA results for PR 1110:<br>- This patch FAILED unit tests.<br>- This patch merges cleanly<br>- This patch adds no public classes<br><br>For more information see test ouptut:<br>https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17347/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50447677
  
    QA results for PR 1110:<br>- This patch PASSES unit tests.<br>- This patch merges cleanly<br>- This patch adds no public classes<br><br>For more information see test ouptut:<br>https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17346/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [WIP][SPARK-2174][MLLIB] treeReduce and treeAg...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-46382961
  
    Merged build finished. All automated tests passed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508331
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    --- End diff --
    
    the convention is 4 space indent for arguments


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508725
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    --- End diff --
    
    done


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508543
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    if (self.partitions.size == 0) {
    +      return Utils.clone(zeroValue, self.context.env.closureSerializer.newInstance())
    +    }
    +    val cleanSeqOp = self.context.clean(seqOp)
    +    val cleanCombOp = self.context.clean(combOp)
    +    val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)
    +    var local = self.mapPartitions(it => Iterator(aggregatePartition(it)))
    +    var numPartitions = local.partitions.size
    +    val scale = math.max(math.ceil(math.pow(numPartitions, 1.0 / depth)).toInt, 2)
    +    while (numPartitions > scale + numPartitions / scale) {
    +      numPartitions /= scale
    +      local = local.mapPartitionsWithIndex { (i, iter) =>
    +        iter.map((i % numPartitions, _))
    +      }.reduceByKey(new HashPartitioner(numPartitions), cleanCombOp).values
    --- End diff --
    
    This is beyond your PR -- but @mateiz and I talked about adding some native primitive to shuffle to improve specifically this pattern (basically there is no need to create numPartitions streams within each map task).


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508491
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    if (self.partitions.size == 0) {
    +      return Utils.clone(zeroValue, self.context.env.closureSerializer.newInstance())
    +    }
    +    val cleanSeqOp = self.context.clean(seqOp)
    +    val cleanCombOp = self.context.clean(combOp)
    +    val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)
    +    var local = self.mapPartitions(it => Iterator(aggregatePartition(it)))
    --- End diff --
    
    I think partial or partiallyAggregated is probably a better name


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark issue #1110: [SPARK-2174][MLLIB] treeReduce and treeAggregate

Posted by debasish83 <gi...@git.apache.org>.
Github user debasish83 commented on the issue:

    https://github.com/apache/spark/pull/1110
  
    @mengxr say I have 20 nodes and 16 cores on each node, do you recommend running treeReduce with 320 partitions and OpenBLAS with numThreads=1 on each partition for SeqOp OR treeReduce with 20 partitions and OpenBLAS with numThreads=16 on each partition for SeqOp...Do you have plans on further improvement ideas of decreasing network shuffle using treeReduce/treeAggregate or if there is a JIRA open so that we can move the discussion on it ? Looks like shuffle is compressed by default on Spark using snappy already...do you recommend compressing the vector logically ?
    
    SparkContext: 20 nodes, 16 cores, sc.defaultParallelism 320
    
    def gramSize(n: Int) = (n*n+1)/2
    
    val combOp = (v1: Array[Float], v2: Array[Float]) => {
          var i = 0
          while (i < v1.length) {
            v1(i) += v2(i)
            i += 1
          }
          v1
        }
    
    val n = gramSize(4096)
    val vv = sc.parallelize(0 until sc.defaultParallelism).map(i => Array.fill[Float](n)(0))
    
    Option 1: 320 partitions, 1 thread on combOp per partition
    
    val start = System.nanoTime(); 
    vv.treeReduce(combOp, 2); 
    val reduceTime = (System.nanoTime() - start)*1e-9
    reduceTime: Double = 5.6390302430000006
    
    Option 2: 20 partitions, 1 thread on combOp per partition
    
    val coalescedvv = vv.coalesce(20)
    coalescedvv.count
    
    val start = System.nanoTime(); 
    coalescedvv.treeReduce(combOp, 2); 
    val reduceTime = (System.nanoTime() - start)*1e-9
    reduceTime: Double = 3.9140685640000004
    
    Option 3: 20 partitions, OpenBLAS numThread=16 per partition
    
    Setting up OpenBLAS on cluster, I will update soon.
    
    Let me know your thoughts. I think if underlying operations are Dense BLAS level1, level2 or level3, running with higher OpenBLAS threads and reducing number of partitions should help in decreasing cross partition shuffle.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50447573
  
    Jenkins, retest this please.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508695
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    --- End diff --
    
    done.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-47693931
  
    Merged build finished. All automated tests passed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50306409
  
    QA results for PR 1110:<br>- This patch PASSES unit tests.<br>- This patch merges cleanly<br>- This patch adds no public classes<br><br>For more information see test ouptut:<br>https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17275/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50445699
  
    LGTM.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50447939
  
    QA tests have started for PR 1110. This patch merges cleanly. <br>View progress: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17347/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508803
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    if (self.partitions.size == 0) {
    +      return Utils.clone(zeroValue, self.context.env.closureSerializer.newInstance())
    +    }
    +    val cleanSeqOp = self.context.clean(seqOp)
    +    val cleanCombOp = self.context.clean(combOp)
    +    val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)
    +    var local = self.mapPartitions(it => Iterator(aggregatePartition(it)))
    +    var numPartitions = local.partitions.size
    +    val scale = math.max(math.ceil(math.pow(numPartitions, 1.0 / depth)).toInt, 2)
    +    while (numPartitions > scale + numPartitions / scale) {
    --- End diff --
    
    done


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [WIP][SPARK-2174][MLLIB] treeReduce and treeAg...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-47686100
  
    @dbtsai Thanks for testing it! I'm going to move `treeReduce` and `treeAggregate` to `mllib.rdd.RDDFunctions`. For normal data processing, people generally use more partitions than number of cores. In those cases, the driver can collect task result while other tasks are running. This is not the optimal case for machine learning algorithms. So I think we can keep `treeReduce` and `treeAggregate` in mllib for now.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/spark/pull/1110


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508559
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    --- End diff --
    
    "in a tree pattern" -> "in a multi-level aggregation tree pattern". 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50444114
  
    QA tests have started for PR 1110. This patch merges cleanly. <br>View progress: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17346/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-47688798
  
    Merged build started. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508334
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    --- End diff --
    
    >=, not >


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508428
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    if (self.partitions.size == 0) {
    +      return Utils.clone(zeroValue, self.context.env.closureSerializer.newInstance())
    +    }
    +    val cleanSeqOp = self.context.clean(seqOp)
    +    val cleanCombOp = self.context.clean(combOp)
    +    val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)
    +    var local = self.mapPartitions(it => Iterator(aggregatePartition(it)))
    +    var numPartitions = local.partitions.size
    +    val scale = math.max(math.ceil(math.pow(numPartitions, 1.0 / depth)).toInt, 2)
    +    while (numPartitions > scale + numPartitions / scale) {
    --- End diff --
    
    would be great to add some comments here..


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508790
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    if (self.partitions.size == 0) {
    +      return Utils.clone(zeroValue, self.context.env.closureSerializer.newInstance())
    +    }
    +    val cleanSeqOp = self.context.clean(seqOp)
    +    val cleanCombOp = self.context.clean(combOp)
    +    val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)
    +    var local = self.mapPartitions(it => Iterator(aggregatePartition(it)))
    --- End diff --
    
    renamed to `partiallyAggregated`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [WIP][SPARK-2174][MLLIB] treeReduce and treeAg...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-46382962
  
    All automated tests passed.
    Refer to this link for build results: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/15860/


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-47688785
  
     Merged build triggered. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508785
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    +    combOp: (U, U) => U,
    +    depth: Int): U = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    if (self.partitions.size == 0) {
    +      return Utils.clone(zeroValue, self.context.env.closureSerializer.newInstance())
    +    }
    +    val cleanSeqOp = self.context.clean(seqOp)
    +    val cleanCombOp = self.context.clean(combOp)
    +    val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)
    +    var local = self.mapPartitions(it => Iterator(aggregatePartition(it)))
    +    var numPartitions = local.partitions.size
    +    val scale = math.max(math.ceil(math.pow(numPartitions, 1.0 / depth)).toInt, 2)
    +    while (numPartitions > scale + numPartitions / scale) {
    --- End diff --
    
    also just for the sake of program always terminating, i'd set a cap on max depth (like 8). 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-47693932
  
    All automated tests passed.
    Refer to this link for build results: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/16285/


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50303437
  
    Jenkins, retest this please.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508694
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    --- End diff --
    
    Not in this PR, but it is useful for testing (simpler than treeAggregate) and it could be used in the feature.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50293177
  
    QA results for PR 1110:<br>- This patch FAILED unit tests.<br>- This patch merges cleanly<br>- This patch adds no public classes<br><br>For more information see test ouptut:<br>https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17264/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [WIP][SPARK-2174][MLLIB] treeReduce and treeAg...

Posted by dbtsai <gi...@git.apache.org>.
Github user dbtsai commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-47683286
  
    We benchmarked treeReduce in our random forest implementation, and since the trees generated from each partition are fairly large (more than 100MB), we found that treeReduce can significantly reduce the shuffle time from 6mins to 2mins. Nice work! 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [WIP][SPARK-2174][MLLIB] treeReduce and treeAg...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-46380502
  
     Merged build triggered. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50447729
  
    Merging this in master. Thanks!



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50303706
  
    QA tests have started for PR 1110. This patch merges cleanly. <br>View progress: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17275/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by rxin <gi...@git.apache.org>.
Github user rxin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508170
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    --- End diff --
    
    greater or equal to? 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50443472
  
    QA tests have started for PR 1110. This patch merges cleanly. <br>View progress: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17345/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by mengxr <gi...@git.apache.org>.
Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/1110#discussion_r15508718
  
    --- Diff: mllib/src/main/scala/org/apache/spark/mllib/rdd/RDDFunctions.scala ---
    @@ -44,6 +47,65 @@ class RDDFunctions[T: ClassTag](self: RDD[T]) {
           new SlidingRDD[T](self, windowSize)
         }
       }
    +
    +  /**
    +   * Reduces the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#reduce]]
    +   */
    +  def treeReduce(f: (T, T) => T, depth: Int): T = {
    +    require(depth >= 1, s"Depth must be greater than 1 but got $depth.")
    +    val cleanF = self.context.clean(f)
    +    val reducePartition: Iterator[T] => Option[T] = iter => {
    +      if (iter.hasNext) {
    +        Some(iter.reduceLeft(cleanF))
    +      } else {
    +        None
    +      }
    +    }
    +    val local = self.mapPartitions(it => Iterator(reducePartition(it)))
    +    val op: (Option[T], Option[T]) => Option[T] = (c, x) => {
    +      if (c.isDefined && x.isDefined) {
    +        Some(cleanF(c.get, x.get))
    +      } else if (c.isDefined) {
    +        c
    +      } else if (x.isDefined) {
    +        x
    +      } else {
    +        None
    +      }
    +    }
    +    RDDFunctions.fromRDD(local).treeAggregate(Option.empty[T])(op, op, depth)
    +      .getOrElse(throw new UnsupportedOperationException("empty collection"))
    +  }
    +
    +  /**
    +   * Aggregates the elements of this RDD in a tree pattern.
    +   * @param depth suggested depth of the tree
    +   * @see [[org.apache.spark.rdd.RDD#aggregate]]
    +   */
    +  def treeAggregate[U: ClassTag](zeroValue: U)(
    +    seqOp: (U, T) => U,
    --- End diff --
    
    done


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] spark pull request: [SPARK-2174][MLLIB] treeReduce and treeAggrega...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the pull request:

    https://github.com/apache/spark/pull/1110#issuecomment-50291751
  
    QA tests have started for PR 1110. This patch merges cleanly. <br>View progress: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/17264/consoleFull


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---