-
Notifications
You must be signed in to change notification settings - Fork 29.3k
[SPARK-12869] Implemented an improved version of the toIndexedRowMatrix #10839
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
4d7c297
fe1842e
c043e77
d3c780d
6c0b58d
25c5f66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,11 +19,11 @@ package org.apache.spark.mllib.linalg.distributed | |
|
|
||
| import scala.collection.mutable.ArrayBuffer | ||
|
|
||
| import breeze.linalg.{DenseMatrix => BDM, Matrix => BM} | ||
| import breeze.linalg.{DenseMatrix => BDM, DenseVector => BDV, Matrix => BM, SparseVector => BSV, Vector => BV} | ||
|
|
||
| import org.apache.spark.{Logging, Partitioner, SparkException} | ||
| import org.apache.spark.annotation.Since | ||
| import org.apache.spark.mllib.linalg.{DenseMatrix, Matrices, Matrix, SparseMatrix} | ||
| import org.apache.spark.mllib.linalg._ | ||
| import org.apache.spark.rdd.RDD | ||
| import org.apache.spark.storage.StorageLevel | ||
|
|
||
|
|
@@ -263,13 +263,33 @@ class BlockMatrix @Since("1.3.0") ( | |
| new CoordinateMatrix(entryRDD, numRows(), numCols()) | ||
| } | ||
|
|
||
|
|
||
| /** Converts to IndexedRowMatrix. The number of columns must be within the integer range. */ | ||
| @Since("1.3.0") | ||
| def toIndexedRowMatrix(): IndexedRowMatrix = { | ||
| require(numCols() < Int.MaxValue, "The number of columns must be within the integer range. " + | ||
| s"numCols: ${numCols()}") | ||
| // TODO: This implementation may be optimized | ||
| toCoordinateMatrix().toIndexedRowMatrix() | ||
|
|
||
| val rows = blocks.flatMap { case ((blockRowIdx, blockColIdx), mat) => | ||
| mat.rowIter.zipWithIndex.map { | ||
| case (vector, rowIdx) => | ||
| blockRowIdx * rowsPerBlock + rowIdx -> (blockColIdx, vector.toBreeze) | ||
| } | ||
| }.groupByKey().map { case (rowIdx, vectors) => | ||
|
|
||
| val wholeVector = vectors.head match { | ||
| case (idx, v: BDV[_]) => BDV.zeros[Double](numCols().toInt) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| case (idx, v: BSV[_]) => BSV.zeros[Double](numCols().toInt) | ||
| case _ => throw new SparkException(s"Cannot convert an empty vector to an indexed row") | ||
| } | ||
|
|
||
| vectors.foreach { case (blockColIdx: Int, vec: BV[Double]) => | ||
| val offset = colsPerBlock * blockColIdx | ||
| wholeVector(offset until offset + vec.size) := vec | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (minor) |
||
| } | ||
| new IndexedRow(rowIdx, Vectors.fromBreeze(wholeVector)) | ||
| } | ||
| new IndexedRowMatrix(rows) | ||
| } | ||
|
|
||
| /** Collect the distributed matrix on the driver as a `DenseMatrix`. */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output vector type should depend on the total number of active elements (or nonzeros) instead of the first one. Could you try
vectors.map(_.activeSize).sumand compare it with numCols to decide which vector type to use?