138
138
} \
139
139
}
140
140
141
- typedef struct {
141
+ typedef struct Matrix {
142
142
GrB_Matrix base ;
143
143
GrB_Matrix base_row ;
144
144
GrB_Matrix base_col ;
145
+ struct Matrix * base_matrices ;
146
+ size_t base_matrices_count ;
145
147
GrB_Index nvals ;
146
148
GrB_Index size ;
147
149
int32_t format ;
148
150
bool is_both ;
151
+ bool is_lazy ;
149
152
} Matrix ;
150
153
151
154
void matrix_update (Matrix * matrix ) {
@@ -159,6 +162,8 @@ Matrix matrix_from_base(GrB_Matrix matrix) {
159
162
result .base = matrix ;
160
163
result .base_row = matrix ;
161
164
result .base_col = NULL ;
165
+ result .base_matrices = NULL ;
166
+ result .base_matrices_count = 0 ;
162
167
result .nvals = 0 ;
163
168
result .size = 0 ;
164
169
result .format = GrB_ROWMAJOR ;
@@ -312,32 +317,38 @@ GrB_Info matrix_mxm_empty(Matrix *output, Matrix *first, Matrix *second, bool ac
312
317
return matrix_mxm_format (output , first , second , accum , swap );
313
318
}
314
319
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
+ }
319
327
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
+ }
322
331
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 ]);
327
337
}
328
338
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
+ }
335
342
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 ) ;
339
346
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 );
341
352
}
342
353
343
354
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
405
416
return matrix_wise_format (output , first , second , accum );
406
417
}
407
418
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
+
409
456
GrB_Info matrix_rsub (Matrix * output , Matrix * mask ) {
410
457
GrB_Info result = GrB_eWiseAdd (output -> base , mask -> base , GrB_NULL , GxB_ANY_BOOL ,
411
458
output -> base , output -> base , GrB_DESC_RSC );
@@ -444,6 +491,18 @@ GrB_Info matrix_rsub_empty(Matrix *output, Matrix *mask) {
444
491
return matrix_rsub_format (output , mask );
445
492
}
446
493
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
+
447
506
// LAGraph_CFL_reachability: Context-Free Language Reachability Matrix-Based Algorithm
448
507
//
449
508
// This function determines the set of vertex pairs (u, v) in a graph (represented by
0 commit comments