-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpack.cpp
149 lines (135 loc) · 4.16 KB
/
pack.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <cassert>
#include <algorithm>
#include <iostream>
#include "pack.h"
using namespace std;
void pack_helper(
double* in_mat,
double* out_mat,
int coordX,
int coordY,
int dimR,
int dimC,
tile_spec_t* tile_specs,
int max_tiling_levels,
int level,
int m,
int n, // This deals specifically with the output matrix
int unpack
) {
assert(! ((tile_specs[level].r == -1) && (tile_specs[level].c == -1)));
int M = tile_specs[level].r;
int N = tile_specs[level].c;
if(tile_specs[level].r == -1) {
M = dimR;
}
if(tile_specs[level].c == -1) {
N = dimC;
}
if (level == max_tiling_levels - 1) {
for(int i = 0; i < dimR; i++) {
for(int j = 0; j < dimC; j++) {
// Lowest level of unpacking
if(tile_specs[level].colMajor) {
if(unpack) {
in_mat[coordX + i + (coordY + j) * m] = out_mat[j * dimR + i];
}
else {
out_mat[j * dimR + i] = in_mat[coordX + i + (coordY + j) * m]; // Toggle from m to n to switch from row to column major input
}
}
else {
if(unpack) {
in_mat[coordX + i + (coordY + j) * m] = out_mat[i * dimC + j];
}
else {
out_mat[i * dimC + j] = in_mat[coordX + i + (coordY + j) * m];
}
}
// End lowest level of unpacking
}
}
}
else {
assert(M > 0);
assert(N > 0);
if(tile_specs[level].colMajor == 1) {
for(int j = 0; j < dimC; j+= N) {
for(int i = 0; i < dimR; i+= M) {
int rWidth = min(M, dimR - i);
int cWidth = min(N, dimC - j);
pack_helper(in_mat,
out_mat,
coordX + i,
coordY + j,
rWidth,
cWidth,
tile_specs,
max_tiling_levels,
level + 1,
m,
n,
unpack);
out_mat += rWidth * cWidth;
}
}
}
else {
for(int i = 0; i < dimR; i+= M) {
for(int j = 0; j < dimC; j+= N) {
int rWidth = min(M, dimR - i);
int cWidth = min(N, dimC - j);
pack_helper(in_mat,
out_mat,
coordX + i,
coordY + j,
rWidth,
cWidth,
tile_specs,
max_tiling_levels,
level + 1,
m,
n,
unpack);
out_mat += rWidth * cWidth;
}
}
}
}
}
// TODO: Should really rename these from in_mat, out_mat
void pack( double* in_mat,
double* out_mat,
tile_spec_t* tile_specs,
int max_tiling_levels,
int m,
int n
) {
pack_helper(in_mat,
out_mat,
0, 0,
m, n,
tile_specs,
max_tiling_levels,
0,
m, n,
0);
}
// TODO: Should really rename these from in_mat, out_mat
void unpack(double* in_mat,
double* out_mat,
tile_spec_t* tile_specs,
int max_tiling_levels,
int m,
int n
) {
pack_helper(in_mat,
out_mat,
0, 0,
m, n,
tile_specs,
max_tiling_levels,
0,
m, n,
1);
}