27static void SimpleBlocking(
29 int **b_cind,
int **b_rptr,
int **block,
32 *block = utils::SafeMalloc<int>(N);
33 for(
int i=0; i<N; i++) { (*block)[i] = i; }
35 *b_rptr = utils::SafeMalloc<int>(N/bsize+1);
36 *b_cind = utils::SafeMalloc<int>(rptr[N]);
39 int *ptr = utils::SafeMalloc<int>(bsize);
40 for(
int i=0; i<N; i+=bsize) {
42 for(
int j=0; j<bsize; j++) { ptr[j] = rptr[(*block)[i+j]]; }
46 for(
int j=0; j<bsize; j++) {
47 if(ptr[j] != -1 && cind[ptr[j]] < min) {
52 (*b_cind)[cnt] = min/bsize;
53 for(
int j=0; j<bsize; j++) {
54 if(ptr[j] == -1)
continue;
55 while(cind[ptr[j]]/bsize == min/bsize) {
57 if(ptr[j] >= rptr[(*block)[i+j]+1]) {
64 (*b_rptr)[i/bsize+1] = cnt;
77static void ConnectedBlocking(
79 int **b_cind,
int **b_rptr,
int **block,
82 *block = utils::SafeCalloc<int>(N);
83 int *inv_block = utils::SafeCalloc<int>(N);
84 int *visited = utils::SafeCalloc<int>(N);
85 int *queue = utils::SafeCalloc<int>(bsize+1);
87 int count = 0, tcnt = 0;
88 for(
int i=0; i<N; i++) {
89 if(visited[i])
continue;
91 (*block)[count] = i; count++; tcnt++;
92 inv_block[i] = (count-1) / bsize;
94 if(tcnt == bsize) { tcnt = 0;
continue; }
98 int q = queue[qs]; qs++;
99 for(
int j=rptr[q]; j<rptr[q+1]; j++) {
100 if(visited[cind[j]])
continue;
101 (*block)[count] = cind[j]; count++; tcnt++;
102 inv_block[cind[j]] = (count-1) / bsize;
103 visited[cind[j]] = 1;
104 if(tcnt == bsize) { tcnt = 0; isFull=
true;
break; }
105 queue[qe] = cind[j]; qe++;
107 if(qs > qe) { exit(1); }
108 if(qs == qe) {
break; }
111 for(
int i=0; i<N; i+=bsize) senk::helper::QuickSort<int>(*block, i, i+bsize-1);
113 *b_rptr = utils::SafeMalloc<int>(N/bsize+1);
114 *b_cind = utils::SafeMalloc<int>(rptr[N]);
115 int *temp = utils::SafeMalloc<int>(rptr[N]);
118 for(
int i=0; i<N; i+=bsize) {
120 for(
int j=0; j<bsize; j++) {
121 for(
int k=rptr[(*block)[i+j]]; k<rptr[(*block)[i+j]+1]; k++) {
122 temp[len] = inv_block[cind[k]]; len++;
125 helper::QuickSort<int>(temp, 0, len-1);
126 (*b_cind)[cnt] = temp[0]; cnt++;
128 for(
int j=1; j<len; j++) {
129 if(temp[j] == prev)
continue;
130 (*b_cind)[cnt] = temp[j]; cnt++;
133 (*b_rptr)[i/bsize+1] = cnt;
150static void GetAdjacency(
151 int *cind,
int *rptr,
152 int **am_cind,
int **am_rptr,
156 *am_cind = utils::SafeMalloc<int>(rptr[N]);
157 *am_rptr = utils::SafeMalloc<int>(N+1);
158 utils::Copy<int>(cind, *am_cind, rptr[N]);
159 utils::Copy<int>(rptr, *am_rptr, N+1);
161 int *rind = utils::SafeMalloc<int>(rptr[N]);
162 int *cptr = utils::SafeMalloc<int>(N+1);
163 int *len = utils::SafeCalloc<int>(N);
164 for(
int i=0; i<N; i++) {
165 for(
int j=rptr[i]; j<rptr[i+1]; j++) {
170 for(
int i=0; i<N; i++) {
171 cptr[i+1] = cptr[i] + len[i];
174 for(
int i=0; i<N; i++) {
175 for(
int j=rptr[i]; j<rptr[i+1]; j++) {
176 rind[cptr[cind[j]]+len[cind[j]]] = i;
180 *am_cind = utils::SafeMalloc<int>(rptr[N]*2);
181 *am_rptr = utils::SafeMalloc<int>(N+1);
184 for(
int i=0; i<N; i++) {
185 int csr_ptr = rptr[i];
186 int csc_ptr = cptr[i];
187 while(csr_ptr < rptr[i+1] || csc_ptr < cptr[i+1]) {
188 int csr_idx = (csr_ptr < rptr[i+1])? cind[csr_ptr] : N;
189 int csc_idx = (csc_ptr < cptr[i+1])? rind[csc_ptr] : N;
190 if(csr_idx < csc_idx) {
191 (*am_cind)[cnt] = csr_idx;
193 }
else if(csr_idx == csc_idx){
194 (*am_cind)[cnt] = csr_idx;
198 (*am_cind)[cnt] = csc_idx;
203 (*am_rptr)[i+1] = cnt;
219 int *cind,
int *rptr,
int **color,
int *num_color,
int N)
221 *color = utils::SafeCalloc<int>(N);
222 int *visit = utils::SafeCalloc<int>(N);
226 for(
int i=0; i<N; i++) {
227 if(visit[i] == now || (*color)[i] != 0)
continue;
230 for(
int j=rptr[i]; j<rptr[i+1]; j++) {
231 visit[cind[j]] = now;
236 *num_color = now - 1;
251 int *cind,
int *rptr,
252 int *num_color,
int **size_color,
int **LP,
int **RP,
257 GetAdjacency(cind, rptr, &am_cind, &am_rptr, N, isSym);
260 Coloring(am_cind, am_rptr, &color, num_color, N);
261 *LP = utils::SafeMalloc<int>(N);
262 *size_color = utils::SafeMalloc<int>(*num_color+1);
263 (*size_color)[0] = 0;
265 for(
int i=0; i<*num_color; i++) {
267 for(
int j=0; j<N; j++) {
268 if(color[j]-1 != i)
continue;
273 (*size_color)[i+1] = (*size_color)[i] + temp_cnt;
275 *RP = utils::SafeMalloc<int>(N);
276 for(
int i=0; i<N; i++) {(*RP)[(*LP)[i]] = i;}
292 int *cind,
int *rptr,
293 int *num_color,
int **size_color,
int **LP,
int **RP,
294 int N,
int bsize,
bool isSym,
const char *bmethod)
297 printf(
"Error: GetABMCPermutation\n");
303 if(std::strcmp(bmethod,
"simple") == 0) {
304 SimpleBlocking(cind, rptr, &b_cind, &b_rptr, &block, N, bsize);
305 }
else if(std::strcmp(bmethod,
"connect") == 0) {
306 ConnectedBlocking(cind, rptr, &b_cind, &b_rptr, &block, N, bsize);
308 printf(
"Error: GetABMCPermutation\n");
309 printf(
"The blocking method is invalid\n");
314 GetAdjacency(b_cind, b_rptr, &am_cind, &am_rptr, N/bsize, isSym);
317 Coloring(am_cind, am_rptr, &color, num_color, N/bsize);
318 *LP = utils::SafeMalloc<int>(N);
319 *size_color = utils::SafeMalloc<int>(*num_color+1);
320 (*size_color)[0] = 0;
322 for(
int i=0; i<*num_color; i++) {
323 for(
int j=0; j<N/bsize; j++) {
324 if(color[j]-1 != i)
continue;
325 for(
int k=0; k<bsize; k++) {
326 (*LP)[cnt] = block[j*bsize+k];
330 (*size_color)[i+1] = cnt/bsize;
332 *RP = utils::SafeMalloc<int>(N);
333 for(
int i=0; i<N; i++) {(*RP)[(*LP)[i]] = i;}
void GetAMCPermutation(int *cind, int *rptr, int *num_color, int **size_color, int **LP, int **RP, int N, bool isSym)
Create an permutation matrix based on the AMC ordering technique.
void GetABMCPermutation(int *cind, int *rptr, int *num_color, int **size_color, int **LP, int **RP, int N, int bsize, bool isSym, const char *bmethod)
Create an permutation matrix based on the ABMC ordering technique, .
The top-level namespace of SenK.
Utility functions are defined.