This is an automated email from the ASF dual-hosted git repository.

uros-b pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 811e666add40 [SPARK-58550][ML] Delay GaussianMixture aggregation 
allocations
811e666add40 is described below

commit 811e666add4063f45e9cf04b55015c2ee9521501
Author: Ruifeng Zheng <[email protected]>
AuthorDate: Wed Aug 5 08:48:26 2026 +0000

    [SPARK-58550][ML] Delay GaussianMixture aggregation allocations
    
    ### What changes were proposed in this pull request?
    
    This PR delays allocation of `ExpectationSum` in `GaussianMixture` until an 
aggregation partition receives its first point. Empty partitions and 
intermediate tree branches use `null` as the aggregation identity.
    
    ### Why are the changes needed?
    
    The previous `treeAggregate` zero value eagerly allocated the mixture 
weights, means, and one dense covariance matrix per cluster. That can be 
substantial for large models and is also serialized to every partition, even 
empty ones.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Not run (not requested). Added coverage using an RDD with an empty 
partition. Static checks: `git diff --check`, ASCII scan, and changed-line 
length scan.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Codex (GPT-5)
    
    Closes #57750 from zhengruifeng/gaussian-mixture-lazy-aggregate-dev3.
    
    Authored-by: Ruifeng Zheng <[email protected]>
    Signed-off-by: Uros Bojanic <[email protected]>
---
 .../spark/mllib/clustering/GaussianMixture.scala       | 18 +++++++++++++++---
 .../spark/mllib/clustering/GaussianMixtureSuite.scala  |  4 ++--
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git 
a/mllib/src/main/scala/org/apache/spark/mllib/clustering/GaussianMixture.scala 
b/mllib/src/main/scala/org/apache/spark/mllib/clustering/GaussianMixture.scala
index 562e5b3995cf..9103d83db41d 100644
--- 
a/mllib/src/main/scala/org/apache/spark/mllib/clustering/GaussianMixture.scala
+++ 
b/mllib/src/main/scala/org/apache/spark/mllib/clustering/GaussianMixture.scala
@@ -201,10 +201,22 @@ class GaussianMixture private (
       val compute = sc.broadcast(ExpectationSum.add(weights, gaussians)_)
 
       // aggregate the cluster contribution for all sample points
+      // Avoid allocating and serializing a large zero value for empty 
partitions.
       val sums = breezeData.treeAggregate[ExpectationSum](
-        zeroValue = ExpectationSum.zero(k, d),
-        seqOp = (agg: ExpectationSum, v: BV[Double]) => compute.value(agg, v),
-        combOp = (agg1: ExpectationSum, agg2: ExpectationSum) => agg1 += agg2,
+        zeroValue = null.asInstanceOf[ExpectationSum],
+        seqOp = (maybeAgg: ExpectationSum, v: BV[Double]) => {
+          val agg = if (maybeAgg == null) ExpectationSum.zero(k, d) else 
maybeAgg
+          compute.value(agg, v)
+        },
+        combOp = (agg1: ExpectationSum, agg2: ExpectationSum) => {
+          if (agg1 == null) {
+            agg2
+          } else if (agg2 == null) {
+            agg1
+          } else {
+            agg1 += agg2
+          }
+        },
         depth = 2,
         finalAggregateOnExecutor = true)
 
diff --git 
a/mllib/src/test/scala/org/apache/spark/mllib/clustering/GaussianMixtureSuite.scala
 
b/mllib/src/test/scala/org/apache/spark/mllib/clustering/GaussianMixtureSuite.scala
index 2ba987b96ef7..10c86472ac0d 100644
--- 
a/mllib/src/test/scala/org/apache/spark/mllib/clustering/GaussianMixtureSuite.scala
+++ 
b/mllib/src/test/scala/org/apache/spark/mllib/clustering/GaussianMixtureSuite.scala
@@ -40,12 +40,12 @@ class GaussianMixtureSuite extends SparkFunSuite with 
MLlibTestSparkContext {
     }
   }
 
-  test("single cluster") {
+  test("single cluster with empty partitions") {
     val data = sc.parallelize(Seq(
       Vectors.dense(6.0, 9.0),
       Vectors.dense(5.0, 10.0),
       Vectors.dense(4.0, 11.0)
-    ))
+    ), 4)
 
     // expectations
     val Ew = 1.0


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to