You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by ur...@apache.org on 2026/09/18 10:05:34 UTC
(spark) branch master updated: [SPARK-59522][ML] Add descriptive messages to the bare require checks in InstanceBlock
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 2ae8e4361b6f [SPARK-59522][ML] Add descriptive messages to the bare require checks in InstanceBlock
2ae8e4361b6f is described below
commit 2ae8e4361b6fbf04145d96e0d473b3706aafef0f
Author: Uros <22...@users.noreply.github.com>
AuthorDate: Fri Sep 18 10:05:20 2026 +0000
[SPARK-59522][ML] Add descriptive messages to the bare require checks in InstanceBlock
### What changes were proposed in this pull request?
`InstanceBlock` (in `Instance.scala`) has six `require(...)` invariant checks with no failure message, so a violation throws a bare `requirement failed`. This adds descriptive messages that interpolate the offending values:
- the `InstanceBlock` constructor checks -- labels vs matrix rows, the matrix being transposed, and labels vs weights;
- `InstanceBlock.blokifyWithMaxMemUsage` -- `maxMemUsage > 0` (both overloads) and the consistent-feature-dimension check.
The conditions themselves are unchanged.
### Why are the changes needed?
These checks guard internal invariants of the block-encoding path. A bare `requirement failed` is hard to act on; including the invariant and the actual values (lengths, feature dimensions, `maxMemUsage`) makes such failures diagnosable. This matches the messages already attached to sibling `require` checks elsewhere in `mllib`.
### Does this PR introduce _any_ user-facing change?
No. `InstanceBlock` is `private[spark]`; this only changes the message of the `IllegalArgumentException` thrown on an internal invariant violation.
### How was this patch tested?
Existing tests. This only adds messages to existing `require` checks; the conditions are unchanged, and each interpolated value is an expression already used in the corresponding condition, so this is a message-only edit.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8)
Closes #58812 from uros-b/instance-require-messages.
Authored-by: Uros <22...@users.noreply.github.com>
Signed-off-by: Uros Bojanic <22...@users.noreply.github.com>
---
.../scala/org/apache/spark/ml/feature/Instance.scala | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/mllib/src/main/scala/org/apache/spark/ml/feature/Instance.scala b/mllib/src/main/scala/org/apache/spark/ml/feature/Instance.scala
index 2c7a9d2a91e6..af99d02f5dbc 100644
--- a/mllib/src/main/scala/org/apache/spark/ml/feature/Instance.scala
+++ b/mllib/src/main/scala/org/apache/spark/ml/feature/Instance.scala
@@ -41,10 +41,15 @@ private[spark] case class InstanceBlock(
labels: Array[Double],
weights: Array[Double],
matrix: Matrix) {
- require(labels.length == matrix.numRows)
- require(matrix.isTransposed)
+ require(labels.length == matrix.numRows,
+ s"The number of labels (${labels.length}) must match the number of matrix rows " +
+ s"(${matrix.numRows}).")
+ require(matrix.isTransposed,
+ "The matrix must be transposed (row-major for dense, CSR for sparse).")
if (weights.nonEmpty) {
- require(labels.length == weights.length)
+ require(labels.length == weights.length,
+ s"The number of weights (${weights.length}) must match the number of labels " +
+ s"(${labels.length}).")
}
def size: Int = labels.length
@@ -147,7 +152,7 @@ private[spark] object InstanceBlock {
def blokifyWithMaxMemUsage(
instanceIterator: Iterator[Instance],
maxMemUsage: Long): Iterator[InstanceBlock] = {
- require(maxMemUsage > 0)
+ require(maxMemUsage > 0, s"maxMemUsage must be positive but got $maxMemUsage.")
new Iterator[InstanceBlock]() {
private var numCols = -1L
@@ -164,7 +169,9 @@ private[spark] object InstanceBlock {
while (instanceIterator.hasNext && blockMemUsage < maxMemUsage) {
val instance = instanceIterator.next()
if (numCols < 0L) numCols = instance.features.size
- require(numCols == instance.features.size)
+ require(numCols == instance.features.size,
+ s"All instances must have the same number of features: expected $numCols " +
+ s"but got ${instance.features.size}.")
buff += instance
buffCnt += 1L
@@ -183,7 +190,7 @@ private[spark] object InstanceBlock {
def blokifyWithMaxMemUsage(
instances: RDD[Instance],
maxMemUsage: Long): RDD[InstanceBlock] = {
- require(maxMemUsage > 0)
+ require(maxMemUsage > 0, s"maxMemUsage must be positive but got $maxMemUsage.")
instances.mapPartitions(iter => blokifyWithMaxMemUsage(iter, maxMemUsage))
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org