Skip to content

Commit 9564946

Browse files
committed
Feat: add lazy optimization
1 parent 5aeeecb commit 9564946

File tree

1 file changed

+81
-22
lines changed

1 file changed

+81
-22
lines changed

experimental/algorithm/LAGraph_CFL_reachability_advanced.c

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,17 @@
138138
} \
139139
}
140140

141-
typedef struct {
141+
typedef struct Matrix {
142142
GrB_Matrix base;
143143
GrB_Matrix base_row;
144144
GrB_Matrix base_col;
145+
struct Matrix *base_matrices;
146+
size_t base_matrices_count;
145147
GrB_Index nvals;
146148
GrB_Index size;
147149
int32_t format;
148150
bool is_both;
151+
bool is_lazy;
149152
} Matrix;
150153

151154
void matrix_update(Matrix *matrix) {
@@ -159,6 +162,8 @@ Matrix matrix_from_base(GrB_Matrix matrix) {
159162
result.base = matrix;
160163
result.base_row = matrix;
161164
result.base_col = NULL;
165+
result.base_matrices = NULL;
166+
result.base_matrices_count = 0;
162167
result.nvals = 0;
163168
result.size = 0;
164169
result.format = GrB_ROWMAJOR;
@@ -312,32 +317,38 @@ GrB_Info matrix_mxm_empty(Matrix *output, Matrix *first, Matrix *second, bool ac
312317
return matrix_mxm_format(output, first, second, accum, swap);
313318
}
314319

315-
GrB_Info matrix_rmxm_format(Matrix *output, Matrix *first, Matrix *second, bool accum) {
316-
Matrix *temp = first;
317-
first = second;
318-
second = temp;
320+
GrB_Info matrix_mxm_lazy(Matrix *output, Matrix *first, Matrix *second, bool accum,
321+
bool swap) {
322+
if (swap) {
323+
Matrix *temp = first;
324+
first = second;
325+
second = temp;
326+
}
319327

320-
int32_t desired_orientation =
321-
first->nvals > second->nvals ? GrB_ROWMAJOR : GrB_COLMAJOR;
328+
if (first->base_matrices_count == 0) {
329+
return matrix_mxm_empty(output, first, second, accum, swap);
330+
}
322331

323-
if (!first->is_both && first->format != desired_orientation &&
324-
!(first->nvals > second->nvals / 3.0)) {
325-
GrB_Info result = matrix_mxm(output, second, first, accum);
326-
return result;
332+
GrB_Matrix *accs = malloc(sizeof(GrB_Matrix) * first->base_matrices_count);
333+
Matrix *acc_matrices = malloc(sizeof(Matrix) * first->base_matrices_count);
334+
for (size_t i = 0; i < first->base_matrices_count; i++) {
335+
GrB_Matrix_new(&accs[i], GrB_BOOL, output->size, output->size);
336+
acc_matrices[i] = matrix_from_base(accs[i]);
327337
}
328338

329-
matrix_to_format(first, desired_orientation, true);
330-
matrix_to_format(second, desired_orientation, false);
331-
matrix_to_format(output, desired_orientation, false);
332-
GrB_Info result = matrix_mxm(output, second, first, accum);
333-
return result;
334-
}
339+
for (size_t i = 0; i < first->base_matrices_count; i++) {
340+
matrix_mxm_empty(&acc_matrices[i], &first->base_matrices[i], second, accum, swap);
341+
}
335342

336-
GrB_Info matrix_rmxm_empty(Matrix *output, Matrix *first, Matrix *second, bool accum) {
337-
if (first->nvals == 0 || second->nvals == 0)
338-
return GrB_SUCCESS;
343+
GrB_Matrix acc;
344+
GrB_Matrix_new(&acc, GrB_BOOL, first->size, first->size);
345+
Matrix acc_matrix = matrix_from_base(acc);
339346

340-
return matrix_rmxm_format(output, first, second, accum);
347+
for (size_t i = 0; i < first->base_matrices_count; i++) {
348+
matrix_wise_empty(&acc_matrix, &acc_matrix, &acc_matrices[i], false);
349+
}
350+
351+
return matrix_dup_empty(output, &acc_matrix);
341352
}
342353

343354
GrB_Info matrix_wise(Matrix *output, Matrix *first, Matrix *second, bool accum) {
@@ -405,7 +416,43 @@ GrB_Info matrix_wise_empty(Matrix *output, Matrix *first, Matrix *second, bool a
405416
return matrix_wise_format(output, first, second, accum);
406417
}
407418

408-
printf("");
419+
GrB_Info matrix_wise_lazy(Matrix *output, Matrix *first, Matrix *second, bool accum) {
420+
if (first->base_matrices_count == 0) {
421+
return matrix_wise_empty(output, first, second, accum);
422+
}
423+
424+
GrB_Matrix _other;
425+
GrB_Matrix_new(&_other, GrB_BOOL, output->size, output->size);
426+
Matrix other = matrix_from_base(_other);
427+
matrix_dup_empty(&other, second);
428+
429+
while (true) {
430+
bool found = false;
431+
432+
for (size_t i = 0; i < first->base_matrices_count; i++) {
433+
if (other.nvals / 10 < first->base_matrices[i].nvals &&
434+
first->base_matrices[i].nvals < other.nvals * 10) {
435+
matrix_wise_empty(&other, &other, &first->base_matrices[i], false);
436+
for (size_t j = i + 1; j < first->base_matrices_count; j++) {
437+
first->base_matrices[j - 1] = first->base_matrices[j];
438+
}
439+
first->base_matrices_count--;
440+
found = true;
441+
break;
442+
}
443+
}
444+
445+
if (found) {
446+
continue;
447+
}
448+
449+
first->base_matrices[first->base_matrices_count++] = other;
450+
break;
451+
}
452+
453+
return GrB_SUCCESS;
454+
}
455+
409456
GrB_Info matrix_rsub(Matrix *output, Matrix *mask) {
410457
GrB_Info result = GrB_eWiseAdd(output->base, mask->base, GrB_NULL, GxB_ANY_BOOL,
411458
output->base, output->base, GrB_DESC_RSC);
@@ -444,6 +491,18 @@ GrB_Info matrix_rsub_empty(Matrix *output, Matrix *mask) {
444491
return matrix_rsub_format(output, mask);
445492
}
446493

494+
GrB_Info matrix_rsub_lazy(Matrix *output, Matrix *mask) {
495+
if (mask->base_matrices_count == 0) {
496+
return matrix_rsub_empty(output, mask);
497+
}
498+
499+
for (size_t i = 0; i < mask->base_matrices_count; i++) {
500+
matrix_rsub_empty(output, &mask->base_matrices[i]);
501+
}
502+
503+
return GrB_SUCCESS;
504+
}
505+
447506
// LAGraph_CFL_reachability: Context-Free Language Reachability Matrix-Based Algorithm
448507
//
449508
// This function determines the set of vertex pairs (u, v) in a graph (represented by

0 commit comments

Comments
 (0)