[SYSTEMDS-3524] Add multi-threaded unique in LibMatrixSketch#2542
Open
shieru1214 wants to merge 5 commits into
Open
[SYSTEMDS-3524] Add multi-threaded unique in LibMatrixSketch#2542shieru1214 wants to merge 5 commits into
shieru1214 wants to merge 5 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a multi-threaded path for
uniqueinLibMatrixSketch.The existing single-threaded implementation is kept and is still used as the baseline/fallback. I added a new overload:
getUniqueValues(MatrixBlock blkIn, Types.Direction dir, int k), wherekcontrols the requested number of threads.The implementation follows the existing SystemDS
uniquedirection semantics:RowCol: unique scalar values over the input matrix, returned as one columnRow: row-wise unique scalar values, preserving the number of rowsCol: column-wise unique scalar values, preserving the number of columnsImplementation
For
k > 1and sufficiently large inputs, the code uses balanced row or column ranges andCommonThreadPool.The parallel logic is direction-specific:
RowCol: each worker builds a localHashSet<Double>over its row range, and the local sets are merged afterwards.Row: rows are partitioned across workers. The code first computes the maximum number of unique values per row, allocates the output, and then fills the row-wise unique values in parallel.Col: columns are partitioned across workers. The code first computes the maximum number of unique values per column, allocates the output, and then fills the column-wise unique values in parallel.There are two parallel paths:
The batched path processes a limited number of ranges at a time, clears temporary local data earlier, and then continues with the next batch. If the input is small,
k <= 1, or batching is not useful, the code falls back to the original single-threaded path.Testing
I added a focused JUnit test:
src/test/java/org/apache/sysds/runtime/matrix/data/LibMatrixSketchUniqueParallelTest.javaIt checks
RowCol,Row, andCol, and compares the multi-threaded result against the single-threaded baseline.I also ran the existing unique tests:
mvn -Dtest=UniqueRow,UniqueRowCol testI ran the focused test locally as well, including one run with a smaller JVM heap to exercise the memory-aware path.
Runtime experiments
I ran local runtime experiments with fixed
k=4, comparing againstk=1.The experiment varies:
RowCol,Row,Col1%,10%,50%,100%Unique Valuesmeans:RowCol: distinct scalar values over the inputRow: distinct scalar values per rowCol: distinct scalar values per columnk=1 time / k=4 time, so values above 1 mean that the multi-threaded path was faster.The results are mostly in line with the expected trade-off. The row-wise and column-wise cases benefit from the parallel path because the work can be partitioned by independent rows or columns. In contrast,
RowColshows limited benefit in these local runs, since the thread-local sets still need to be merged into one global set and the merge overhead can dominate, especially when the number of unique scalar values is high.The table below shows the local runtime results. These numbers are from local runs and are meant as an initial comparison, not as a full benchmark.