Skip to content

Commit c69ba3c

Browse files
author
Biranavan Parameswaran
committed
[SYSTEMDS-3730] Add MatrixRollPerf.java
Introduced a new test class to properly measure the performance of single-threaded and multithreaded rolling and remove unnecessary if condition
1 parent 1d41175 commit c69ba3c

File tree

3 files changed

+109
-28
lines changed

3 files changed

+109
-28
lines changed

src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixReorg.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ public static MatrixBlock roll(MatrixBlock input, MatrixBlock output, int shift,
532532
return output;
533533
}
534534

535-
if(numThreads <= 1 || input.isEmptyBlock(false) || input.getLength() < PAR_NUMCELL_THRESHOLD) {
535+
if(numThreads <= 1 || input.getLength() < PAR_NUMCELL_THRESHOLD) {
536536
return roll(input, output, shift); // fallback to single-threaded
537537
}
538538

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package org.apache.sysds.performance.matrix;
2+
3+
import org.apache.sysds.performance.compression.APerfTest;
4+
import org.apache.sysds.performance.generators.ConstMatrix;
5+
import org.apache.sysds.performance.generators.IGenerate;
6+
import org.apache.sysds.runtime.functionobjects.IndexFunction;
7+
import org.apache.sysds.runtime.functionobjects.RollIndex;
8+
import org.apache.sysds.runtime.matrix.data.MatrixBlock;
9+
import org.apache.sysds.runtime.matrix.operators.ReorgOperator;
10+
import org.apache.sysds.test.TestUtils;
11+
import org.apache.sysds.utils.stats.InfrastructureAnalyzer;
12+
13+
import java.util.Random;
14+
15+
public class MatrixRollPerf extends APerfTest<Object, MatrixBlock> {
16+
17+
private final int rows;
18+
private final int cols;
19+
private final int shift;
20+
private final int k;
21+
22+
private final ReorgOperator reorg;
23+
private MatrixBlock out;
24+
25+
public MatrixRollPerf(int N, int W, IGenerate<MatrixBlock> gen, int rows, int cols, int shift, int k) {
26+
super(N, W, gen);
27+
this.rows = rows;
28+
this.cols = cols;
29+
this.shift = shift;
30+
this.k = k;
31+
32+
IndexFunction op = new RollIndex(shift);
33+
this.reorg = new ReorgOperator(op, k);
34+
}
35+
36+
public void run() throws Exception {
37+
MatrixBlock mb = gen.take();
38+
logInfos(rows, cols, shift, mb.getSparsity(), k);
39+
40+
41+
String info = String.format("rows: %5d cols: %5d sp: %.4f shift: %4d k: %2d",
42+
rows, cols, mb.getSparsity(), shift, k);
43+
44+
45+
warmup(this::rollOnce, W);
46+
47+
execute(this::rollOnce, info);
48+
}
49+
50+
private void logInfos(int rows, int cols, int shift, double sparsity, int k) {
51+
String matrixType = sparsity == 1 ? "Dense" : "Sparse";
52+
if (k == 1) {
53+
System.out.println("---------------------------------------------------------------------------------------------------------");
54+
System.out.printf("%s Experiment for rows %d columns %d and shift %d \n", matrixType, rows, cols, shift);
55+
System.out.println("---------------------------------------------------------------------------------------------------------");
56+
}
57+
}
58+
59+
private void rollOnce() {
60+
MatrixBlock in = gen.take();
61+
62+
if (out == null)
63+
out = new MatrixBlock(rows, cols, in.isInSparseFormat());
64+
65+
out.reset(rows, cols, in.isInSparseFormat());
66+
67+
in.reorgOperations(reorg, out, 0, 0, 0);
68+
69+
ret.add(null);
70+
}
71+
72+
@Override
73+
protected String makeResString() {
74+
return "";
75+
}
76+
77+
public static void main(String[] args) throws Exception {
78+
int kMulti = InfrastructureAnalyzer.getLocalParallelism();
79+
int reps = 2000;
80+
int warmup = 200;
81+
82+
int minRows = 2017;
83+
int minCols = 1001;
84+
double spSparse = 0.01;
85+
int minShift = -50;
86+
int maxShift = 1022;
87+
int iterations = 10;
88+
89+
Random rand = new Random(42);
90+
91+
for (int i = 0; i < iterations; i++) {
92+
int rows = minRows + rand.nextInt(500);
93+
int cols = minCols + rand.nextInt(500);
94+
int shift = rand.nextInt((maxShift - minShift) + 1) + minShift;
95+
96+
MatrixBlock denseIn = TestUtils.generateTestMatrixBlock(rows, cols, -100, 100, 1.0, 42);
97+
MatrixBlock sparseIn = TestUtils.generateTestMatrixBlock(rows, cols, -100, 100, spSparse, 42);
98+
99+
// Run Dense Case (Single vs Multi-threaded)
100+
new MatrixRollPerf(reps, warmup, new ConstMatrix(denseIn, -1), rows, cols, shift, 1).run();
101+
new MatrixRollPerf(reps, warmup, new ConstMatrix(denseIn, -1), rows, cols, shift, kMulti).run();
102+
103+
// Run Sparse Case (Single vs Multi-threaded)
104+
new MatrixRollPerf(reps, warmup, new ConstMatrix(sparseIn, -1), rows, cols, shift, 1).run();
105+
new MatrixRollPerf(reps, warmup, new ConstMatrix(sparseIn, -1), rows, cols, shift, kMulti).run();
106+
}
107+
}
108+
}

src/test/java/org/apache/sysds/test/component/matrix/libMatrixReorg/RollOperationThreadSafetyTest.java

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.apache.sysds.runtime.matrix.data.MatrixBlock;
2929
import org.apache.sysds.runtime.matrix.operators.ReorgOperator;
3030
import org.apache.sysds.test.TestUtils;
31-
import org.apache.sysds.utils.stats.Timing;
3231
import org.junit.Test;
3332
import org.junit.runner.RunWith;
3433
import org.junit.runners.Parameterized;
@@ -89,17 +88,9 @@ public static Collection<Object[]> data() {
8988
public void denseRollOperationSingleAndMultiThreadedShouldReturnSameResult() {
9089
int numThreads = getNumThreads();
9190

92-
// Single-threaded timing
93-
Timing tSingle = new Timing(true);
9491
MatrixBlock outSingle = rollOperation(inputDense, 1);
95-
double timeSingle = tSingle.stop();
9692

97-
// Multithreaded timing
98-
Timing tMulti = new Timing(true);
9993
MatrixBlock outMulti = rollOperation(inputDense, numThreads);
100-
double timeMulti = tMulti.stop();
101-
102-
logTiming("Dense", numThreads, timeSingle, timeMulti);
10394

10495
TestUtils.compareMatrices(outSingle, outMulti, 1e-12,
10596
"Dense Mismatch (numThreads=1 vs numThreads>1) for Size=" + rows + "x" + cols + " Shift=" + shift);
@@ -109,17 +100,9 @@ public void denseRollOperationSingleAndMultiThreadedShouldReturnSameResult() {
109100
public void sparseRollOperationSingleAndMultiThreadedShouldReturnSameResult() {
110101
int numThreads = getNumThreads();
111102

112-
// Single-threaded timing
113-
Timing tSingle = new Timing(true);
114103
MatrixBlock outSingle = rollOperation(inputSparse, 1);
115-
double timeSingle = tSingle.stop();
116104

117-
// Multithreaded timing
118-
Timing tMulti = new Timing(true);
119105
MatrixBlock outMulti = rollOperation(inputSparse, numThreads);
120-
double timeMulti = tMulti.stop();
121-
122-
logTiming("Sparse", numThreads, timeSingle, timeMulti);
123106

124107
TestUtils.compareMatrices(outSingle, outMulti, 1e-12,
125108
"Sparse Mismatch (numThreads=1 vs numThreads>1) for Size=" + rows + "x" + cols + " Shift=" + shift);
@@ -139,14 +122,4 @@ private static int getNumThreads() {
139122
int cores = Runtime.getRuntime().availableProcessors();
140123
return Math.max(2, cores);
141124
}
142-
143-
private void logTiming(String type, int numThreads, double timeSingle, double timeMulti) {
144-
double speedup = timeSingle / timeMulti;
145-
146-
System.out.println("\n--- " + type + " Roll Operation Timing for " + rows + "x" + cols + ", Shift=" + shift + " ---");
147-
System.out.printf("Single-threaded (1 core) took: %.3f ms\n", timeSingle);
148-
System.out.printf("Multithreaded (%d cores) took: %.3f ms\n", numThreads, timeMulti);
149-
System.out.printf("Speedup: %.2f\n", speedup);
150-
System.out.println("--------------------------------------------------------------------------------");
151-
}
152125
}

0 commit comments

Comments
 (0)