|
If A[i][j] = a , then
for some index x:
|
0 1 2 3 4 5 6 7 0 [ 11 12 14 ] 1 [ 22 23 25 ] 2 [ 31 33 34 ] 3 [ 42 45 46 ] 4 [ 55 ] 5 [ 65 66 67 ] 6 [ 75 77 78 ] 7 [ 87 88 ] |
Representation using Coordinate-wise method:
Index 0 1 2 3 4 5 6 7 8 9 10 ----------------------------------------------------------- Val 11 12 14 22 23 25 31 33 34 42 45 Row 0 0 0 1 1 1 2 2 2 3 3 Col 0 1 3 1 2 4 0 2 3 1 4 Index 11 12 13 14 15 16 17 18 19 20 21 ------------------------------------------------------------ Val 46 55 65 66 67 75 77 78 87 88 - Row 3 4 5 5 5 6 6 6 7 7 - Col 5 4 4 5 6 4 6 7 6 7 - |
|
0 1 2 3 4 5 6 7 0 [ 11 12 14 ] [ 3 ] --> [11*3 + 12*5 + 14*1] 1 [ 22 23 25 ] [ 5 ] --> [22*5 + 23*2 + 25*0] 2 [ 31 33 34 ] [ 2 ] 3 [ 42 45 46 ] [ 1 ] 4 [ 55 ] x [ 0 ] = ??? 5 [ 65 66 67 ] [ 1 ] 6 [ 75 77 78 ] [ 2 ] 7 [ 87 88 ] [ 4 ] A[8][8] d[8] |
Index 0 1 2 3 4 5 6 7 8 9 10 ----------------------------------------------------------- Val 11 12 14 22 23 25 31 33 34 42 45 Row 0 0 0 1 1 1 2 2 2 3 3 Col 0 1 3 1 2 4 0 2 3 1 4 Index 11 12 13 14 15 16 17 18 19 20 21 ------------------------------------------------------------ Val 46 55 65 66 67 75 77 78 87 88 - Row 3 4 5 5 5 6 6 6 7 7 - Col 5 4 4 5 6 4 6 7 6 7 - |
How is the result obtained: out[0] is computed as: [11*3 + 12*5 + 14*1] = A[0][0]*d[0] + A[0][1]*d[1] + A[0][3]*d[3] ^ ^ ^ | | | Val[0] Val[1] Val[2] = Val[0]*d[??] + Val[1]*d[??] + Val[2]*d[??] Look carefully at: Col[0], Col[1] and Col[2], you will see that: = Val[0]*d[Col[0]] + Val[1]*d[Col[1]] + Val[2]*d[Col[2]] |
// Val[] = value array // Row[] = row index array // Col[] = column index array // nnz = # non-zero elements // m = # rows int k; // Clear out result for (k = 0; k < m; k = k + 1) { out[k] = 0.0; } // Matrix-vetor Multiply for (k = 0; k < nnz; k = k + 1) { out[Row[k]] = out[Row[k]] + Val[k]*in[Col[k]]; } |
|
|
void MatrixVectorMult(double out[], double Val[], int Row[], int Col[], double d[], int m, int nnz) { int k; for (k = 0; k < m; k = k + 1) { out[k] = 0.0; } for (k = 0; k < nnz; k = k + 1) { out[Row[k]] = out[Row[k]] + Val[k]*d[Col[k]]; } } |
int main(int argc, char ** argv) { double Val[] = {11, 12, 14, 22, 23, 25, 31, 33, 34, 42, 45, 46, 55, 65, 66, 67, 75, 77, 78, 87, 88}; int Row[] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 6, 6, 6, 7, 7}; int Col[] = {0, 1, 3, 1, 2, 4, 0, 2, 3, 1, 4, 5, 4, 4, 5, 6, 4, 6, 7, 6, 7}; double u[8], v[8]; int i, j; u[0] = 3; u[1] = 5; u[2] = 2; u[3] = 1; u[4] = 0; u[5] = 1; u[6] = 2; u[7] = 4; MatrixVectorMult(v, Val, Row, Col, u, 8, 21); } |
[ 11 12 14 ] [ 22 23 25 ] [ 31 33 34 ] [ 42 45 46 ] [ 55 ] [ 65 66 67 ] [ 75 77 78 ] [ 87 88 ] |
Representation using Compressed Sparse Row method:
[0, 3) +-----------+ | | Index 0 1 2 3 4 5 6 7 8 9 10 ----------------------------------------------------------- Val 11 12 14 22 23 25 31 33 34 42 45 RowPtr 0 3 6 9 12 13 16 19 21 - - Col 0 1 3 1 2 4 0 2 3 1 4 Index 11 12 13 14 15 16 17 18 19 20 21 ------------------------------------------------------------ Val 46 55 65 66 67 75 77 78 87 88 - RowPtr - - - - - - - - - - - Col 5 4 4 5 6 4 6 7 6 7 - |
|
0 1 2 3 4 5 6 7 0 [ 11 12 14 ] [ 3 ] --> [11*3 + 12*5 + 14*1] 1 [ 22 23 25 ] [ 5 ] --> [22*5 + 23*2 + 25*0] 2 [ 31 33 34 ] [ 2 ] 3 [ 42 45 46 ] [ 1 ] 4 [ 55 ] x [ 0 ] = ??? 5 [ 65 66 67 ] [ 1 ] 6 [ 75 77 78 ] [ 2 ] 7 [ 87 88 ] [ 4 ] A[8][8] d[8] |
[0, 3) +-----------+ | | Index 0 1 2 3 4 5 6 7 8 9 10 ----------------------------------------------------------- Val 11 12 14 22 23 25 31 33 34 42 45 RowPtr 0 3 6 9 12 13 16 19 21 - - Col 0 1 3 1 2 4 0 2 3 1 4 Index 11 12 13 14 15 16 17 18 19 20 21 ------------------------------------------------------------ Val 46 55 65 66 67 75 77 78 87 88 - RowPtr - - - - - - - - - - - Col 5 4 4 5 6 4 6 7 6 7 - |
How is out[0] obtained: out[0] is computed as: [11*3 + 12*5 + 14*1] = A[0][0]*d[0] + A[0][1]*d[1] + A[0][3]*d[3] ^ ^ ^ | | | Val[0] Val[1] Val[2] = Val[0]*d[??] + Val[1]*d[??] + Val[2]*d[??] Look carefully at: Col[0], Col[1] and Col[2], you will see that: = Val[0]*d[Col[0]] + Val[1]*d[Col[1]] + Val[2]*d[Col[2]] How can we tell which number should be added to out[0] ??? ColPtr[0] = 0 ColPtr[1] = 3 |
[3, 6) +-----------+ | | Index 0 1 2 3 4 5 6 7 8 9 10 ----------------------------------------------------------- Val 11 12 14 22 23 25 31 33 34 42 45 RowPtr 0 3 6 9 12 13 16 19 21 - - Col 0 1 3 1 2 4 0 2 3 1 4 Index 11 12 13 14 15 16 17 18 19 20 21 ------------------------------------------------------------ Val 46 55 65 66 67 75 77 78 87 88 - RowPtr - - - - - - - - - - - Col 5 4 4 5 6 4 6 7 6 7 - |
How is out[1] obtained: out[1] is computed as: [22*5 + 23*2 + 25*0] = A[1][1]*d[1] + A[1][2]*d[2] + A[1][4]*d[4] ^ ^ ^ | | | Val[3] Val[4] Val[5] = Val[0]*d[1] + Val[1]*d[2] + Val[2]*d[4] Look carefully at: Col[3], Col[4] and Col[5], you will see that: = Val[3]*d[Col[3]] + Val[4]*d[Col[4]] + Val[5]*d[Col[5]] How can we tell which number should be added to out[1] ??? ColPtr[1] = 3 ColPtr[2] = 6 |
// Val[] = value array // RowPtr[] = row index RANGE array // Col[] = column index array // m = # rows int i, k; // Clear out result for (k = 0; k < m; k = k + 1) { out[k] = 0.0; } // Matrix-vetor Multiply for (i = 0; i < m; i = i + 1) { for (k = RowPtr[i]; k < RowPtr[i+1]; k = k + 1) { result[i] = result[i] + Val[k]*d[Col[k]]; } } |
|
|
void MatrixVectorMult(double out[], double Val[], int RowPtr[], int Col[], double in[], int m) { int i, k; for (k = 0; k < m; k = k + 1) { out[k] = 0.0; } for (i = 0; i < m; i = i + 1) { for (k = RowPtr[i]; k < RowPtr[i+1]; k = k + 1) { out[i] = out[i] + Val[k]*in[Col[k]]; } } } |
int main(int argc, char ** argv) { double Val[] = {11, 12, 14, 22, 23, 25, 31, 33, 34, 42, 45, 46, 55, 65, 66, 67, 75, 77, 78, 87, 88}; int RowPtr[] = {0, 3, 6, 9, 12, 13, 16, 19, 21}; int Col[] = {0, 1, 3, 1, 2, 4, 0, 2, 3, 1, 4, 5, 4, 4, 5, 6, 4, 6, 7, 6, 7}; double u[8], v[8]; int i, j; u[0] = 3; u[1] = 5; u[2] = 2; u[3] = 1; u[4] = 0; u[5] = 1; u[6] = 2; u[7] = 4; MatrixVectorMult(v, Val, RowPtr, Col, u, 8); } |
result[ Row[k] ] = result[ Row[k] ] + Val[ k ]*d[ Col[ k ] ]; |
Executing this statement requires the computer to obtain the following values from the main memory:
|
result[ i ] = result[ i ] + Val[ k ]*d[ Col[k] ]; |
Executing this statement requires the computer to obtain the following values from the main memory:
|
Main memory access time is the bottle neck of computer systems...