@@ -702,6 +702,61 @@ TEST(workspaces, loopfuse) {
702702 ASSERT_TENSOR_EQ (expected, A);
703703}
704704
705+
706+
707+ TEST (workspaces, loopcontractfuse) {
708+ int N = 16 ;
709+ Tensor<double > A (" A" , {N, N, N}, Format{Dense, Dense, Dense});
710+ Tensor<double > B (" B" , {N, N, N}, Format{Dense, Sparse, Sparse});
711+ Tensor<double > C (" C" , {N, N}, Format{Dense, Dense});
712+ Tensor<double > D (" D" , {N, N}, Format{Dense, Dense});
713+ Tensor<double > E (" E" , {N, N}, Format{Dense, Dense});
714+
715+ for (int i = 0 ; i < N; i++) {
716+ for (int j = 0 ; j < N; j++) {
717+ for (int k = 0 ; k < N; k++) {
718+ B.insert ({i, j, k}, (double ) i);
719+ }
720+ C.insert ({i, j}, (double ) j);
721+ E.insert ({i, j}, (double ) i*j);
722+ D.insert ({i, j}, (double ) i*j);
723+ }
724+ }
725+
726+ IndexVar i (" i" ), j (" j" ), k (" k" ), l (" l" ), m (" m" ), n (" n" );
727+ A (l,m,n) = B (i,j,k) * C (i,l) * D (j,m) * E (k,n);
728+
729+ IndexStmt stmt = A.getAssignment ().concretize ();
730+
731+ std::cout << stmt << endl;
732+ vector<int > path1;
733+ vector<int > path2 = {1 };
734+ stmt = stmt
735+ .reorder ({l,i,m, j, k, n})
736+ .loopfuse (2 , true , path1)
737+ .loopfuse (2 , true , path2)
738+ ;
739+ stmt = stmt
740+ .parallelize (l, ParallelUnit::CPUThread, OutputRaceStrategy::NoRaces)
741+ ;
742+
743+
744+ stmt = stmt.concretize ();
745+ cout << " final stmt: " << stmt << endl;
746+ printCodeToFile (" loopcontractfuse" , stmt);
747+
748+ A.compile (stmt.concretize ());
749+ A.assemble ();
750+ A.compute ();
751+
752+ Tensor<double > expected (" expected" , {N, N, N}, Format{Dense, Dense, Dense});
753+ expected (l,m,n) = B (i,j,k) * C (i,l) * D (j,m) * E (k,n);
754+ expected.compile ();
755+ expected.assemble ();
756+ expected.compute ();
757+ ASSERT_TENSOR_EQ (expected, A);
758+ }
759+
705760TEST (workspaces, precompute2D_mul) {
706761 int N = 16 ;
707762 Tensor<double > A (" A" , {N, N}, Format{Dense, Dense});
0 commit comments