text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

_RDFT_CONST := 2.5;

#F TRDFT(<n>, <k>) - RDFT Nonterminal
Class(TRDFT, TaggedNonTerminal, rec(
    abbrevs := [ (n) -> Checked(IsPosIntSym(n),  [n, 1]),
                 (n,k) -> Checked(IsPosIntSym(n), IsIntSym(k),
                             Cond( IsSymbolic(n) or IsSymbolic(k), [n, k],
                                    Checked(Gcd(n,k)=1, [n, k mod n]))) ],
    dims := self >> [self.params[1], self.params[1]],
    isReal := True,
    terminate := self >> let(
	mat := PkRDFT1(self.params[1], self.params[2]).terminate(),
	When(self.transposed, mat.transpose(), mat)),

    SmallRandom := () -> Random([2,4,6,8,10,12,16,18,24,30,32]),
    normalizedArithCost := (self) >> let(n := self.params[1], floor(_RDFT_CONST * n * log(n) / log(2.0)))
));

_conjEven := (N, rot) -> let(
    m := Mat([[1,0],[0,-1]]),
    d1 := Diag(diagDirsum(fConst(TReal, 2, 1.0), fConst(TReal, N-2, 1/2))),
    m1 := DirectSum(   m, _SUM(I(N-2), Tensor(J((N-2)/2), m))),
    m2 := DirectSum(J(2), _SUM(I(N-2), Tensor(J((N-2)/2), -m))),
    i := I(N),
    d2 := RC(Diag(fPrecompute(diagDirsum(
		    fConst(TReal, 1, 1.0),
		    diagMul(fConst(TComplex, N/2-1, omegapi(-1/2)),
			    fCompose(dOmega(N, rot), fAdd(N/2, N/2-1, 1))))))),
    d1 * _HStack(m1, m2) * VStack(i, d2)
);

#F TConjEven(<n>) - extract conjugate even from RC(DFT) of half the size
Class(TConjEven, TaggedNonTerminal, rec(
    abbrevs := [ (n)      -> Checked(IsPosIntSym(n), [n, 1]),
                 (n, rot) -> Checked(IsPosIntSym(n), IsIntSym(rot), [n, rot]) ],

    dims := self >> [self.params[1], self.params[1]],
    isReal := True,

    terminate := self >> let(mat := _conjEven(self.params[1], self.params[2]),
	Cond(self.transposed, mat.transpose(), mat)),

    conjTranspose := self >> self.transpose(),
    SmallRandom := () -> [Random([2,4,6,8,10,12,16,18,24,30,32]), 1],
    doNotMeasure := true
));

#F  "FFT of Single Real Function"
#F  Numerical Recipes in C, Chapter 12, pp 512--514
NewRulesFor(TRDFT, rec(
    TRDFT_DFT_NR_tSPL_New := rec(
        switch := true,
	forTransposition := true,
        applicable := (self, t) >> IsEvenInt(t.params[1]), # and t.hasTags(),
        children := (self, t) >> let(N := t.params[1], rot := t.params[2],
            [[
                TConjEven(N, rot).withTags(t.getTags()),
                TRC(DFT(N/2, t.params[2])).withTags(t.getTags())
            ]]),
        apply := (self, t, C, Nonterms) >> C[1] * C[2]
    ),

    TRDFT_DFT_NR_tSPL := rec(
        switch := true,
	forTransposition := true,
        useComplexCh := false,
        applicable := (self, t) >> IsEvenInt(t.params[1]), # and t.hasTags(),
        children := (self, t) >> let(N := t.params[1], rot := t.params[2],
            cmpxtags := t.getTags(),
            realtags := List(cmpxtags, e -> Cond(e.kind()=spiral.paradigms.vector.AVecRegCx, spiral.paradigms.vector.AVecReg(e.params[1]), e)),
            [[
                TConjEven(N, rot).withTags(realtags),
                TRC(DFT(N/2, t.params[2])).withTags(Cond(self.useComplexCh, cmpxtags, realtags))
            ]]),
        apply := (self, t, C, Nonterms) >> C[1] * C[2]
    ),

    TRDFT_DFT_NR_tSPL_Cplx := CopyFields(~.TRDFT_DFT_NR_tSPL, rec(
        useComplexCh := true,
        applicable   := (self, t) >> IsEvenInt(t.params[1]) and t.hasTag(spiral.paradigms.vector.AVecRegCx),
    )),

   TRDFT_CT_tSPL_New := rec(
        applicable := t -> let(n:=t.params[1],  t.hasTags() and
            not IsPrime(n) and not (IsEvenInt(n) and IsPrime(n/2))),

        freedoms := t -> let(N := t.params[1], v2 := t.firstTag().params[1].v,
            # TRC(TDiag(f)) needs 2*v | f.domain(), not to mention TConj
            [ Filtered(DivisorsIntNonTriv(N), x->x>2 and N/x mod v2=0) ]),

        child := (self, t, fr) >> let(
            N := t.params[1],  k := t.params[2],
            n := fr[1],        m := N/n,         j := Ind(Int((n+1)/2)-1),
	    tags := t.getTags(),

            [ When(IsEvenInt(n), TRDFT(2*m, k).withTags(tags),
                                 TRDFT(m,   k).withTags(tags)),
              When(IsEvenInt(n), TTensorI(URDFT(n, k), m, AVec, AVec).withTags(tags),
                                 TTensorI(PkRDFT1(n, k), m, AVec, AVec).withTags(tags)),
              InfoNt(j),
              TConj(TRC(DFT(m, k) * TDiag(fPrecompute(Twid(N,m,k,0,0,j+1)))),
		    fId(2*m), L(2*m, m)).withTags(tags)
	    ]
        ),

	apply := (self, t, C, Nonterms) >> let(
            N  := t.params[1],           m  := Nonterms[2].params[2],  n  := N/m,
            Nf := Int(N/2),              mf := Int(m/2),               nf := Int(n/2),
            Nc := Int((N+1)/2),          mc := Int((m+1)/2),           nc := Int((n+1)/2),
            j  := Nonterms[3].params[1], k  := t.params[2],            tags := t.getTags(),

            RC(Tensor(I(m/2), DirectSum(I(n/2+1), J(n/2-1)))) *
            RC(L(N/2, m)) *
            DirectSum(
                C[1],
                IDirSum(j, RC(LIJ(m)) * Diag(BHD(m,1,-1)) * C[4])
            ) *
            C[2]
        )
    ),

    TRDFT_CT_tSPL := rec(
#        requiredFirstTag := [AVecReg, AVecRegCx],

        # rule TRDFT_CT_tSPL_Cplx sets useComplexCh to <true> and overrides some methods
        useComplexCh := false,

        applicable := t -> let(n:=t.params[1],  t.hasTags() and
            not IsPrime(n) and not (IsEvenInt(n) and IsPrime(n/2))),

        freedoms := t -> let( N := t.params[1], v2 := 2*t.firstTag().params[1].v,
            # TRC(TDiag(f)) needs 2*v | f.domain(), not to mention TConj
            [ Filtered(DivisorsIntNonTriv(N), x->x>2 and N/x mod v2=0) ]),

        child := (self, t, fr) >> let(
            N := t.params[1],  k := t.params[2],
            n := fr[1],        m := N/n,         j := Ind(Int((n+1)/2)-1),

            cmpxtags := t.getTags(),
            realtags := List(cmpxtags, e -> Cond(e.kind()=spiral.paradigms.vector.AVecRegCx, spiral.paradigms.vector.AVecReg(e.params[1]), e)),

            [ When(IsEvenInt(n), TRDFT(2*m, k).withTags(cmpxtags),
                                 TRDFT(m,   k).withTags(cmpxtags)),
              When(IsEvenInt(n), TTensorI(URDFT(n, k), m, AVec, AVec).withTags(realtags),
                                 TTensorI(PkRDFT1(n, k), m, AVec, AVec).withTags(realtags)),
              InfoNt(j)
            ] ::
            Cond( self.useComplexCh,
              [ TRC(DFT(m, k)).withTags(cmpxtags),
                TRC(TDiag(fPrecompute(Twid(N,m,k,0,0,j+1)))).withTags(cmpxtags),
                TL(2*m, m, 1, 1).withTags(realtags) ],
              [ TConj(TRC(DFT(m, k)), fId(2*m), L(2*m, m)).withTags(realtags),
                TConj(TRC(TDiag(fPrecompute(Twid(N,m,k,0,0,j+1)))), L(2*m, 2), L(2*m, m)).withTags(realtags)] )
        ),

	apply := (self, t, C, Nonterms) >> let(
            N  := t.params[1],           m  := Nonterms[2].params[2],  n  := N/m,
            Nf := Int(N/2),              mf := Int(m/2),               nf := Int(n/2),
            Nc := Int((N+1)/2),          mc := Int((m+1)/2),           nc := Int((n+1)/2),
            j  := Nonterms[3].params[1], k  := t.params[2],            tags := t.getTags(),

            dft:= Cond(self.useComplexCh, C[4]*C[5]*C[6], C[4]*C[5]),

            RC(Tensor(I(m/2), DirectSum(I(n/2+1), J(n/2-1)))) *
            RC(L(N/2, m)) *
            DirectSum(
                C[1],
                IDirSum(j, RC(LIJ(m)) * Diag(BHD(m,1,-1)) * dft )
            ) *
            C[2]
        )
    ),

    TRDFT_CT_tSPL_Cplx := CopyFields(~.TRDFT_CT_tSPL, rec(
        useComplexCh := true,
        applicable := t -> let(n:=t.params[1],  t.hasTag(spiral.paradigms.vector.AVecRegCx) and
            not IsPrime(n) and not (IsEvenInt(n) and IsPrime(n/2))),

        freedoms := t -> let( N := t.params[1], v := t.firstTag().v,
            # TRC(TDiag(f)) needs v/2 | f.domain()
            [ Filtered(DivisorsIntNonTriv(N), x->x>2 and N/x mod v=0) ]),
    )),

    TRDFT_By_Def := rec(
         forTransposition := false,
         applicable := (self, t) >> (t.firstTagIs(spiral.paradigms.vector.AVecReg) or
                                     t.firstTagIs(spiral.paradigms.vector.AVecRegCx)) and
                                     t.params[1]<=t.firstTag().isa.v,
         apply := (self, t, C, Nonterms) >> spiral.paradigms.vector.breakdown.VectorizedMatSPL(t.firstTag().isa, t),
    ),

    TRDFT_By_Def_tr := rec(
         forTransposition := false,
	 transposed := true,
         applicable := (self, t) >> (t.firstTagIs(spiral.paradigms.vector.AVecReg) or
                                     t.firstTagIs(spiral.paradigms.vector.AVecRegCx)) and
                                     t.params[1]<=t.firstTag().isa.v,
         apply := (self, t, C, Nonterms) >> spiral.paradigms.vector.breakdown.VectorizedMatSPL(t.firstTag().isa, t),
    ),

));

NewRulesFor(TConjEven, rec(
    TConjEven_base := rec(
        switch := true,
        applicable := (self, t) >> IsEvenInt(t.params[1]),
        apply := (self, t, C, Nonterms) >> _conjEven(t.params[1], t.params[2])
    )
));


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

SIMD_ISA_DB.hashAdd(TL(4, 2, 1, 2).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 2,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 1, 4).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := IxLxI_vtensor( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := IxLxI_vtensor( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 8, 1, 1).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_4x64f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
          IxLxI_vtensor( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_4x64f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_4x64f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
          IxLxI_vtensor( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_4x64f) ]) ) ),
      measured := 12.4,
      globalUnrolling := 10000 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 1, 1).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 4, 1, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 4, 1, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 6.2000000000000002,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 1, 2).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases2( TL(8, 4, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases2( TL(8, 4, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 2, 1).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 12.4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 1, 2).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases2( TL(8, 2, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases2( TL(8, 2, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 2, 1).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 2, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 2, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 12.4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 4, 1, 1).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(16, 4, 1, 1).withTags([ AVecReg(AVX_4x64f) ]),
          SIMD_ISA_Bases2( TL(8, 4, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
          SIMD_ISA_Bases1( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(16, 4, 1, 1).withTags([ AVecReg(AVX_4x64f) ]),
          SIMD_ISA_Bases2( TL(8, 4, 1, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
          SIMD_ISA_Bases1( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ) ),
      measured := 16.399999999999999,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 2, 2).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 2, 1, 1).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(16, 2, 1, 1).withTags([ AVecReg(AVX_4x64f) ]),
          IxLxI_vtensor( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_4x64f) ]) ),
          SIMD_ISA_Bases1( TL(8, 2, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(16, 2, 1, 1).withTags([ AVecReg(AVX_4x64f) ]),
          IxLxI_vtensor( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_4x64f) ]) ),
          SIMD_ISA_Bases1( TL(8, 2, 2, 1).withTags([ AVecReg(AVX_4x64f) ]) ) ),
      measured := 12.4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 1, 1).withTags([ AVecReg(AVX_4x64f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 2, 1, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 2, 1, 1).withTags([ AVecReg(AVX_4x64f) ]) ),
      measured := 6.2000000000000002,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(16, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(16, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 12.4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(64, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(64, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_n( TL(32, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases2( TL(16, 8, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
              SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
              IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(64, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_n( TL(32, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases2( TL(16, 8, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
              SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
              IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 57.599999999999994,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 4.5,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 8,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 2, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(8, 2, 2, 4).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(8, 2, 2, 4).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 8,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 8, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 8, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 8, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 36.0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 12.4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(64, 32, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(64, 32, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      origtree := IxLxI_kmn_km( TL(64, 32, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 10000 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 2,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 1.8,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 6.2000000000000002,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(64, 4, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(64, 4, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          IxLxI_kmn_km( TL(32, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_kmn_n( TL(16, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
              IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
              SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ) ) ),
      origtree := IxLxI_kmn_n( TL(64, 4, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          IxLxI_kmn_km( TL(32, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_kmn_n( TL(16, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
              IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
              SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ) ) ),
      measured := 49.600000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(32, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases2( TL(16, 8, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      origtree := IxLxI_kmn_n( TL(32, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases2( TL(16, 8, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      measured := 32.799999999999997,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 8, 2, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(32, 8, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(32, 8, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(16, 8, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 49.600000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(64, 2, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(64, 2, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_n( TL(8, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(64, 2, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_n( TL(8, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(16, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(16, 8, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 12.4,
      globalUnrolling := 10000 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 8, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(8, 4, 8, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 16, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 8, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(8, 4, 8, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 16, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 8, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 43.200000000000003,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(32, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_n( TL(8, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(32, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_n( TL(8, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 2, 2, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(32, 2, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(32, 2, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(8, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(8, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 8, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(8, 2, 8, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 8, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 16, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(8, 2, 8, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 8, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 16, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 43.200000000000003,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 6.2000000000000002,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(8, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 10.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_vtensor( TL(4, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := IxLxI_vtensor( TL(4, 2, 1, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases2( TL(8, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases2( TL(8, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 2, 1, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 6.2000000000000002,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 2, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(8, 2, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(8, 2, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(4, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 10.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases2( TL(16, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases2( TL(16, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 8,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 4, 4, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_IxLxI_up( TL(16, 4, 4, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_IxLxI_up( TL(16, 4, 4, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 49.600000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 16, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(32, 16, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      origtree := IxLxI_kmn_km( TL(32, 16, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 10000 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 16, 2, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(32, 16, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(32, 16, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 10000 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 4, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_IxLxI_down( TL(16, 4, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_IxLxI_down( TL(16, 4, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(16, 8, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 12.399999999999999,
      globalUnrolling := 10000 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 2, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(8, 4, 2, 4).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_km( TL(8, 4, 2, 4).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 8,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(16, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(16, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 8, 1, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases2( TL(16, 8, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases2( TL(16, 8, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 8,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(8, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(8, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 12.4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 9.0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(32, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases2( TL(16, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(32, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases2( TL(16, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 32.799999999999997,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(32, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_km( TL(32, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_n( TL(16, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      origtree := IxLxI_kmn_km( TL(32, 4, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
          IxLxI_kmn_n( TL(16, 2, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
            SIMD_ISA_Bases1( TL(8, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      measured := 49.600000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 2, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(16, 2, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(16, 2, 1, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 6.2000000000000002,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(8, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases2( TL(8, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases2( TL(8, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(64, 16, 1, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(64, 16, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(32, 16, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
              IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
              IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
          IxLxI_kmn_km( TL(32, 16, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      origtree := IxLxI_kmn_n( TL(64, 16, 1, 1).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(32, 16, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_kmn_km( TL(8, 4, 1, 8).withTags([ AVecReg(AVX_8x32f) ]),
              IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ),
              IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
          IxLxI_kmn_km( TL(32, 16, 2, 1).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(16, 8, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ) ),
      measured := 49.600000000000001,
      globalUnrolling := 10000 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(16, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(8, 4, 2, 4).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(16, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]),
          IxLxI_kmn_km( TL(8, 4, 2, 4).withTags([ AVecReg(AVX_8x32f) ]),
            SIMD_ISA_Bases1( TL(4, 2, 4, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
            IxLxI_vtensor( TL(4, 2, 2, 8).withTags([ AVecReg(AVX_8x32f) ]) ) ),
          SIMD_ISA_Bases1( TL(8, 4, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 32.799999999999997,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 2, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 2, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 2, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 4,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 4, 2).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 18.0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := IxLxI_vtensor( TL(4, 2, 1, 16).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 0,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases2( TL(16, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases2( TL(16, 2, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 8,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(4, 2, 16, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(4, 2, 16, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(4, 2, 16, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 7.2000000000000002,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      origtree := SIMD_ISA_Bases1( TL(16, 2, 4, 1).withTags([ AVecReg(AVX_8x32f) ]) ),
      measured := 24.800000000000001,
      globalUnrolling := 8 ) ]);
SIMD_ISA_DB.hashAdd(TL(16, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]), [ rec(
      ruletree := IxLxI_kmn_n( TL(16, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases2( TL(8, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      origtree := IxLxI_kmn_n( TL(16, 4, 1, 2).withTags([ AVecReg(AVX_8x32f) ]),
          SIMD_ISA_Bases2( TL(8, 4, 1, 4).withTags([ AVecReg(AVX_8x32f) ]) ),
          SIMD_ISA_Bases1( TL(8, 4, 2, 2).withTags([ AVecReg(AVX_8x32f) ]) ) ),
      measured := 16.399999999999999,
      globalUnrolling := 8 ) ]);

ext: gi


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

CompareCodeMat := (sums, opts) ->
    let(me := Try(CMatrix(CodeSums(Copy(sums), opts), opts)),
        them := MatSPL(sums),
        When(me[1] = false, false,
             InfinityNormMat(me[2]-them) < 1e-5));

_RecursiveFindBug := function(ind, spl, opts, verify_func)
    local c, ch, res, bugspl, origspl, seg, i, len;
    Print(Blanks(ind), ObjId(spl), " - ");
    res := verify_func(spl, opts);
    Print(res, "\n");

    # no bug, verification succeeded
    if res = true then return true;

    # bug, verification failed, now we will recurse and verify the children
    else
        origspl := spl;
        # loops need to be unrolled to get rid of index variables
        if IsBound(spl.unroll) then spl := spl.unroll(); fi;
        for c in spl.children() do
            bugspl := _RecursiveFindBug(ind+3, c, opts, verify_func);
            if bugspl <> true then return bugspl; fi; # bug is in the child
        od;

        # verification succeeded for all of the children, but we will still try to
        # narrow down the problem if the current node is Compose
        if ObjId(spl)=Compose and spl.numChildren() > 2 then
            ind := ind+3;
            PrintLine(Blanks(ind), "Problematic multifactor Compose. Narrowing down the problem");
            ch := spl.children();
            while Length(ch) > 2 do
                len := Length(ch)-1;
                i:=1;
                res := true;
                # the loop terminates when res = false (verif failed) OR everything succeeded (ie no smaller bug)
                while res and i <= Length(ch)-len+1 do
                   seg := ch{[i..i+len-1]};
                   res := verify_func(Compose(seg), opts);
                   PrintLine(Blanks(ind), "len=", len, " i=", i, " ", res);
                   i := i+1;
                od;
                if res=true then return Compose(ch);
                else ch := seg;
                fi;
            od;
            return Compose(ch);
        else
            return origspl; # bug is here and not in the children, and we could not narrow it down further
        fi;
    fi;
end;

# verify_func(spl, opts)
#
RecursiveFindBug := (spl, opts, verify_func) -> _RecursiveFindBug(0, spl, opts, verify_func);

_RecursiveFindBugExp := function(ind, spl, opts, verify_func)
    local c, ch, res, bugspl, origspl, seg, i, len;
    Print(Blanks(ind), ObjId(spl), " - ");
    res := verify_func(spl, opts);
    Print(res, "\n");

    # no bug, verification succeeded
    if res = true then return true;

    # bug, verification failed, now we will recurse and verify the children
    else
        origspl := spl;
        # loops need to be unrolled to get rid of index variables
        if IsBound(spl.unroll) then spl := spl.unroll(); fi;
        for c in spiral.rewrite._children(spl) do
            bugspl := _RecursiveFindBugExp(ind+3, c, opts, verify_func);
            if bugspl <> true then return bugspl; fi; # bug is in the child
        od;

        return origspl; # bug is here and not in the children
    fi;
end;

RecursiveFindBugExp := (spl, opts, verify_func) -> _RecursiveFindBugExp(0, spl, opts, verify_func);

RecursiveFindBugRT := function (rt, opts)
    local chk, s;

    chk := (spl, opts) -> InfinityNormMat(CMatrix(CodeSumsOpts(spl, opts), opts) - MatSPL(spl)) < 1e-4;
    s := SumsRuleTreeOpts(rt, opts);

    return RecursiveFindBug(s, opts, chk);
end;


text:
#############################################################################
##
#W  example.gd
##
##  This file contains a sample of a GAP implementation file.
##

#############################################################################
##
#M  SomeOperation( <val> )
##
##  performs some operation on <val>
##
InstallMethod( SomeProperty,
    "for left modules",
    [ IsLeftModule ], 0,
    function( M )
    if IsFreeLeftModule( M ) and not IsTrivial( M ) then
      return true;
    fi;
    TryNextMethod();
    end );

#############################################################################
##
#F  SomeGlobalFunction( )
##
##  A global variadic funfion.
##
InstallGlobalFunction( SomeGlobalFunction, function( arg )
    if Length( arg ) = 3 then
      return arg[1] + arg[2] * arg[3];
    elif Length( arg ) = 2 then
      return arg[1] - arg[2]
    else
      Error( "usage: SomeGlobalFunction( <x>, <y>[, <z>] )" );
    fi;
    end );

#
# A plain function.
#
SomeFunc := function(x, y)
    local z, func, tmp, j;
    z := x * 1.0;
    y := 17^17 - y;
    func := a -> a mod 5;
    tmp := List( [1..50], func );
    while y > 0 do
        for j in tmp do
            Print(j, "\n");
        od;
        repeat
            y := y - 1;
        until 0 < 1;
        y := y -1;
    od;
    return z;
end;

max_stars_repo_name: oslab-swrc/juxta

max_issues_repo_name: oslab-swrc/juxta

max_forks_repo_name: oslab-swrc/juxta


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

TempArrayType := (child, y, x, index) ->
    When( IsBound(child.a.t_in), child.a.t_in[index], let(
          X := Flat([x])[1], # without type unification everything has same type
          When(X.t.t=TComplex or Flat([y])[1].t.t=TComplex, TComplex, X.t.t)
));

TempArray := (y, x, child) -> let(
    cols := Flat([Cols(child)]),
    StripList( List( [1..Length(cols)], i ->
        TempVec( TArray( TempArrayType(child, y, x, i), cols[i]))
)));

# HACKed in. This should just be rolled into TempArray or otherwise be handled cleanly.
TempArraySeq := function(y, x, child)
    local dims, P;
    if ObjId(child)=BB then
      dims := child.child(1).dims();
      P    := child.child(1).P;
    else
      dims := child.dims();
      P    := child.P;
    fi;

    return(
        StripList(List(
          Flat([ dims[2]/P ]), z ->
            TempVec(
                #TArray(TempArrayType(child, Flat([y])[1], Flat([x])[1]), z))
                TArray(TempArrayType(child, y, x, 1), z))
            )));
end;

#F _CodeSums(<sums-spl>, <y-output-var>, <x-input-var>)
#F
#F Generates unoptimize loop code for <sums-spl>
#F
_CodeSums := function(sums, y, x)
    local code;
    code := sums.code(y,x);
    code.dimensions := sums.dimensions;
    code.root := sums;
    return code;
end;

#CodeSums := _CodeSums;

_CodeSumsAcc := function(sums, y, x)
    local code;
    code := _CodeSums(sums, y, x);
    code := SubstTopDownNR(code, [assign, [@(0,nth), @(1, var, e->Same(e,y)), ...], @(3)],
                     e -> assign_acc(@(0).val, @(3).val));
    return code;
end;

# =======================================================================================
# Code generation templates
# [ Data, Blk, Blk1, Prm, R, W, SUM, ISum, Compose ]
# =======================================================================================
Formula.code := (self,y,x) >> self.child(1).code(y, x);

BB.code := (self,y,x) >> MarkForUnrolling(_CodeSums(self.child(1), y, x));

Buf.code := (self,y,x) >> _CodeSums(self.child(1), y, x);

COND.code := (self,y,x) >>
    IF(self.cond,
    _CodeSums(self.child(1), y, x),
    _CodeSums(self.child(2), y, x));

Data.code := meth(self, y, x)
    local val, t;
    if self.inline then
    # we set live_out to prevent copy propagation
    # self.var.setAttr("live_out")
    return decl(self.var, chain(
        assign(self.var, self.value.tolist()),
        _CodeSums(self.child(1), y, x)));
    else
    val := self.value;
    if IsBound(val.tolist) then
        if IsBound(val.range) and val.range() <> false then
        t := TArray(val.range(), val.domain());
        val := t.value(val.tolist());
        else
        val := V(val.tolist());
        fi;
    else val := Cond(IsSPL(val), V(MatSPL(val)), val);
    fi;
    return data(self.var, val, _CodeSums(self.child(1), y, x));
    fi;
end;

Diag.code := meth(self, y, x)
    local i, elt;
    i := Ind();
    elt := self.element.lambda().at(i);
    return loop(i, self.element.domain(), assign(nth(y,i), elt * nth(x,i)));
end;

RCDiag.code := meth(self, y, x)
    local i, elt, re, im;
    i := Ind();
    elt := self.element.lambda();
    re := elt.at(2*i);
    im := elt.at(2*i+1);
    return loop(i, self.element.domain()/2, chain(
	    assign(nth(y,2*i),   re * nth(x,2*i) - im * nth(x,2*i+1)),
	    assign(nth(y,2*i+1), im * nth(x,2*i) + re * nth(x,2*i+1))));
end;

ColVec.code := meth(self, y, x)
    local i, datavar, diag, func;
    i := Ind();
    func := self.element;
    if IsBound(self.inline) and self.inline then
    return loop(i, Rows(self), assign(nth(y,i), mul(func.lambda().at(i), nth(x,0))));
    else
    diag := V(func.lambda().tolist());
    datavar := Dat(diag.t);
    return
    data(datavar, diag,
        loop(i, Rows(self), assign(nth(y,i), mul(nth(datavar,i), nth(x,0)))));
    fi;
end;

RowVec.code := meth(self, y, x)
    local i, datavar, diag, func, t;
    i := Ind();
    t := TempVar(x.t.t);
    func := self.element;
    if IsBound(self.inline) and self.inline then
    return chain(
        assign(t,0),
        loop(i, Cols(self), assign(t, add(t, mul(func.lambda().at(i), nth(x,i))))),
        assign(nth(y,0), t));
    else
    diag := V(func.lambda().tolist());
    datavar := Dat(diag.t);
    return
    data(datavar, diag,
        chain(
        assign(t,0),
        loop(i, Cols(self), assign(t, add(t, mul(nth(datavar,i), nth(x,i))))),
        assign(nth(y,0), t)));
    fi;
end;

Scale.code := (self, y, x) >> let(i := Ind(),
    chain(
	_CodeSums(self.child(1), y, x),
	loop(i, Rows(self),
	    assign(nth(y,i), mul(self.scalar, nth(y,i))))));

I.code := (self, y, x) >> let(i := Ind(),
    loop(i, Rows(self), assign(nth(y,i), nth(x,i))));

Blk2code := (blk, y, x) -> let(b := V(blk.element).v,
    t0 := TempVar(x.t.t), t1 := TempVar(x.t.t),
    decl([t0, t1], chain(
	    assign(t0, mul(b[1].v[1], nth(x,0)) + mul(b[1].v[2], nth(x,1))),
	    assign(t1, mul(b[2].v[1], nth(x,0)) + mul(b[2].v[2], nth(x,1))),
	    assign(nth(y,0), t0),
	    assign(nth(y,1), t1)
	)));

Blk4code := (blk, y, x) -> let(b := V(blk.element).v,
    t0 := TempVar(x.t.t), t1 := TempVar(x.t.t),
    t2 := TempVar(x.t.t), t3 := TempVar(x.t.t),

    x0 := TempVar(x.t.t), x1 := TempVar(x.t.t),
    x2 := TempVar(x.t.t), x3 := TempVar(x.t.t),
    decl([x0,x1,x2,x3, t0, t1, t2, t3], chain(
	    assign(x0, nth(x,0)),
	    assign(x1, nth(x,1)),
	    assign(x2, nth(x,2)),
	    assign(x3, nth(x,3)),

	    assign(t0, mul(b[1].v[1], x0) + mul(b[1].v[2], x1) +
		       mul(b[1].v[3], x2) + mul(b[1].v[4], x3)),
	    assign(t1, mul(b[2].v[1], x0) + mul(b[2].v[2], x1) +
		       mul(b[2].v[3], x2) + mul(b[2].v[4], x3)),
	    assign(t2, mul(b[3].v[1], x0) + mul(b[3].v[2], x1) +
		       mul(b[3].v[3], x2) + mul(b[3].v[4], x3)),
	    assign(t3, mul(b[4].v[1], x0) + mul(b[4].v[2], x1) +
		       mul(b[4].v[3], x2) + mul(b[4].v[4], x3)),
	    assign(nth(y,0), t0),
	    assign(nth(y,1), t1),
	    assign(nth(y,2), t2),
	    assign(nth(y,3), t3)
    )));

Blk.code := meth(self, y, x)
    local i, j, t, datavar, matval;
    if Rows(self)=2 and Cols(self)=2 then return Blk2code(self, y, x); fi;
    if Rows(self)=4 and Cols(self)=4 then return Blk4code(self, y, x); fi;
    j := Ind();
    i := Ind();
    t := TempVar(x.t.t);
    matval := V(self.element);
    datavar := Dat(matval.t);
    return
    data(datavar, matval,
    loop(j, Rows(self),
        decl(t,
        chain(
            assign(t, 0),
            loop(i, Cols(self),
            assign(t, add(t, mul(nth(nth(datavar, j), i), nth(x, i))))),
            assign(nth(y,j), t)))));
end;

toeplitz.code := meth(self, y, x)
    local i, j, t, datavar, matval, dataload;
    j := Ind();
    i := Ind();
    t := TempVar(x.t.t);
    matval := V(self.obj.element);
    datavar := Dat(matval.t);
    dataload := TempVec(TArray(TDouble, Rows(self)*Cols(self)));
    return
    data(datavar, matval, decl(dataload, chain(
    loop(j, Rows(self),
        loop(i, Cols(self),
        assign(nth(dataload, j*Cols(self)+i), nth(nth(datavar,j),i)))),

    loop(j, Rows(self),
        decl(t,
        chain(
            assign(t, 0),
            loop(i, Cols(self),
            assign(t, add(t, mul(nth(dataload, j*Cols(self)+i), nth(x, i))))),
            assign(nth(y,j), t)))))));
end;

Blk1.code := (self, y, x) >>
   assign(nth(y,0), mul(toExpArg(self.element), nth(x,0)));

BlkConj.code := (self, y, x) >>
   assign(nth(y,0), conj(nth(x,0)));

Prm.code := (self, y, x) >> let(i := Ind(), func := self.func.lambda(),
    loop(i, Rows(self),
    assign(nth(y, i),
           nth(x, func.at(i)))));

Z.code := (self, y, x) >> let(i := Ind(), ii := Ind(), z := self.params[2],
    chain(
    loop(i, Rows(self)-z,
        assign(nth(y, i), nth(x, i+z))),
    loop(i, z,
        assign(nth(y, i+(Rows(self)-z)), nth(x, i)))));

O.code := (self, y, x) >> let(i := Ind(),
    loop(i, self.params[1],
        assign(nth(y, i), V(0))));

Gath.code := meth(self, y, x)
    local i, func, rfunc, ix;
    i := Ind(); func := self.func.lambda();

    if IsBound(self.func.rlambda) then
	rfunc := self.func.rlambda();
	ix := var.fresh_t("ix", TInt);
	return chain(
	    assign(ix, func.at(0)),
	    assign(nth(y, 0), nth(x, ix)),
	    loop(i, self.func.domain()-1,
		chain(assign(ix, rfunc.at(ix)),
		      assign(nth(y, i+1), nth(x, ix)))));
    else
	return loop(i, self.func.domain(), assign(nth(y,i), nth(x, func.at(i))));
    fi;
end;

Scat.code := meth(self, y, x)
    local i, func, rfunc, ix;
    i := Ind(); func := self.func.lambda();
    if IsBound(self.func.rlambda) then
	rfunc := self.func.rlambda();
	ix := var.fresh_t("ix", TInt);
	return chain(
	    assign(ix, func.at(0)),
	    assign(nth(y, ix), nth(x, 0)),
	    loop(i, self.func.domain()-1,
		chain(assign(ix, rfunc.at(ix)),
		      assign(nth(y, ix), nth(x, i+1)))));
    else
	return loop(i, self.func.domain(), assign(nth(y,func.at(i)), nth(x, i)));
    fi;
end;

SUM.code := (self, y, x) >>
       chain(List(self.children(), c -> _CodeSums(c, y, x)));

SUMAcc.code := (self, y, x) >>
   let(ii := Ind(),
       When(not Same(ObjId(self.child(1)), Gath),  # NOTE: come up with a general condition
       chain(
           loop(ii, Rows(self), assign(nth(y, ii), V(0))),
           List(self.children(), c -> _CodeSumsAcc(c, y, x))),
       chain(
           _CodeSums(self.child(1), y, x),
           List(Drop(self.children(), 1), c -> _CodeSumsAcc(c, y, x)))));

ISum.code := (self, y, x) >> let(myloop := When(IsSymbolic(self.domain), loopn, loop),
   myloop(self.var, self.domain,
        _CodeSums(self.child(1), y, x)));

ISumAcc.code := (self, y, x) >>
   let(ii := Ind(),
       chain(
       loop(ii, Rows(self),
           assign(nth(y, ii), V(0))),
       loop(self.var,
            self.domain,
        _CodeSumsAcc(self.child(1), y, x))));

Compose.code := meth(self,y,x)
    local ch, numch, vecs, allow, i;
#VIENNA filtering DMPGath, DMPScat out here because they do not generate code
#    ch := self.children();
    ch := Filtered(self.children(), i-> not i.name in ["DMPGath","DMPScat"]);
    numch := Length(ch);
    vecs := [y];
    allow := (x<>y);
    for i in [1..numch-1] do
        if allow and ObjId(ch[i])=Inplace then vecs[i+1] := vecs[i];
	else vecs[i+1] := TempVec(TArray(TempArrayType(y, x), Cols(ch[i])));
	fi;
    od;
    vecs[numch+1] := x;
    for i in Reversed([1..numch]) do
        if allow and ObjId(ch[i])=Inplace then vecs[i] := vecs[i+1];
	fi;
    od;

#Print(vecs, "\n");
    if vecs[1] = vecs[numch+1] then # everything was inplace
	vecs[1] := y;
    fi;
    if vecs[1] = vecs[numch+1] then # everything was inplace
	vecs[numch+1] := x;
    fi;
#Print(vecs, "\n");
    vecs := Reversed(vecs);
    ch := Reversed(ch);
    return decl( Difference(vecs{[2..Length(vecs)-1]}, [x,y]),
	chain( List([1..numch], i -> When(vecs[i+1]=vecs[i],
		    compiler._IPCodeSums(ch[i], vecs[i]),
		    _CodeSums(ch[i], vecs[i+1], vecs[i])))));
end;

ICompose.code := (self, y, x) >>

#DoneSpiralHelp - How to make this work for any datatype (var t)
#Look into Compose.code for tempvec

  chain([let(
    t :=  Dat1d(x.t.t, Rows(self)),
    newind := Ind(self.domain),
    decl([t], chain(
       When(IsOddInt(self.domain),
       SubstVars(Copy(_CodeSums(self.child(1), y, x)), tab((self.var.id) := (V(0)))),
          skip()
       ),
       When(IsEvenInt(self.domain),
          chain(
          SubstVars(Copy(_CodeSums(self.child(1), t, x)), tab((self.var.id) := (V(0)))),
          SubstVars(Copy(_CodeSums(self.child(1), y, t)), tab((self.var.id) := (V(1))))
          ),
          skip()
       ),
      loop(newind, (self.domain/2),
        chain([
        SubstVars(Copy(_CodeSums(self.child(1), x, y)), tab((self.var.id) := (2*newind)+2)),
        SubstVars(Copy(_CodeSums(self.child(1), y, x)), tab((self.var.id) := (2*newind)+3))
        ])
      )
    ))
  )]);


text:
#############################################################################
####
##
#A  anusp.gi                    ANUPQ package                  Eamonn O'Brien
#A                                                             Alice Niemeyer
##
#Y  Copyright 1993-2001,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
#Y  Copyright 1993-2001,  School of Mathematical Sciences, ANU,     Australia
##

#############################################################################
##
#F  ANUPQSPerror( <param> )  . . . . . . . . . . . . report illegal parameter
##
InstallGlobalFunction( ANUPQSPerror, function( param )
    Error(
    "Valid Options:\n",
    "    \"ClassBound\", <bound>\n",
    "    \"PcgsAutomorphisms\"\n",
    "    \"Exponent\", <exponent>\n",
    "    \"Metabelian\"\n",
    "    \"OutputLevel\", <level>\n",
    "    \"SetupFile\", <file>\n",
    "Illegal Parameter: \"", param, "\"" );
end );

#############################################################################
##
#F  ANUPQSPextractArgs( <args> )  . . . . . . . . . . . . parse argument list
##
InstallGlobalFunction( ANUPQSPextractArgs, function( args )
    local   CR,  i,  act,  G,  match;

    # allow to give only a prefix
    match := function( g, w )
    	return 1 < Length(g) and
            Length(g) <= Length(w) and
            w{[1..Length(g)]} = g;
    end;

    # extract arguments
    G  := args[2];
    CR := rec( group := G );
    i  := 3;
    while i <= Length(args)  do
        act := args[i];

        # "ClassBound", <class>
        if match( act, "ClassBound" )  then
            i := i + 1;
            CR.ClassBound := args[i];
            if CR.ClassBound <= PClassPGroup(G)  then
                Error( "\"ClassBound\" must be at least ", PClassPGroup(G)+1 );
            fi;

        # "PcgsAutomorphisms"
        elif match( act, "PcgsAutomorphisms" )  then
            CR.PcgsAutomorphisms := true;

        #this may be available later
        # "SpaceEfficient"
        #elif match( act, "SpaceEfficient" ) then
        #    CR.SpaceEfficient := true;

        # "Exponent", <exp>
        elif match( act, "Exponent" )  then
            i := i + 1;
            CR.Exponent := args[i];

        # "Metabelian"
        elif match( act, "Metabelian" ) then
            CR.Metabelian := true;

        # "Verbose"
        elif match( act, "Verbose" )  then
            CR.Verbose := true;

        # "SetupFile", <file>
        elif match( act, "SetupFile" )  then
            i := i + 1;
            CR.SetupFile := args[i];

    	# "TmpDir", <dir>
    	elif match( act, "TmpDir" )  then
    	    i := i + 1;
    	    CR.TmpDir := args[i];

        # "Output", <level>
        elif match( act, "OutputLevel" )  then
            i := i + 1;
            CR.OutputLevel := args[i];
            CR.Verbose     := true;

        # signal an error
        else
            ANUPQSPerror(act);
        fi;
        i := i + 1;
    od;
    return CR;

end );

#############################################################################
##
#F  PqFpGroupPcGroup( <G> ) . . . . . .  corresponding fp group of a pc group
##
InstallGlobalFunction( PqFpGroupPcGroup,
    G -> Image( IsomorphismFpGroup( G ) )
);

#############################################################################
##
#M  FpGroupPcGroup( <G> ) . . . . . . .  corresponding fp group of a pc group
##
InstallMethod( FpGroupPcGroup, "pc group", [IsPcGroup], 0, PqFpGroupPcGroup );

#############################################################################
##
#F  PQ_EPIMORPHISM_STANDARD_PRESENTATION( <args> ) . (epi. onto) SP for group
##
InstallGlobalFunction( PQ_EPIMORPHISM_STANDARD_PRESENTATION,
function( args )
    local   datarec, rank, Q, Qclass, automorphisms, generators, x,
            images, i, r, j, aut, result, desc, k;

    datarec := ANUPQ_ARG_CHK("StandardPresentation", args);

    if datarec.calltype = "interactive" and IsBound(datarec.SPepi) then
       # Note: the `pq' binary seg-faults if called twice to
       # calculate the standard presentation of a group
      return datarec.SPepi;
    fi;

    if VALUE_PQ_OPTION("pQuotient") = fail and
       VALUE_PQ_OPTION("Prime", datarec) <> fail then
       # Ensure a saved value of `Prime' has precedence
       # over a saved value of `pQuotient'.
        Unbind(datarec.pQuotient);
    fi;

    if VALUE_PQ_OPTION("pQuotient", datarec) <> fail then
        PQ_AUT_GROUP( datarec.pQuotient );
        datarec.Prime := PrimePGroup( datarec.pQuotient );
    elif VALUE_PQ_OPTION("Prime", datarec) <> fail then
        rank := Number( List( AbelianInvariants(datarec.group),
                              x -> Gcd(x, datarec.Prime) ),
                        y -> y = datarec.Prime );

        # construct free group with <rank> generators
        Q := FreeGroup( IsSyllableWordsFamily, rank, "q" );

        # construct power-relation
        Q := Q / List( GeneratorsOfGroup(Q), x -> x^datarec.Prime );

        # construct pc group
        Q := PcGroupFpGroup(Q);

        # construct automorphism
        automorphisms := [];
        generators := GeneratorsOfGroup(Q);
        for x in GeneratorsOfGroup( GL(rank, datarec.Prime) ) do
            images := [];
            for i  in [ 1 .. rank ]  do
                r := One(Q);
                for j  in [ 1 .. rank ]  do
                    r := r * generators[j]^Int(x[i][j]);
                od;
                images[i] := r;
            od;
            aut := GroupHomomorphismByImages( Q, Q, generators, images );
            SetIsBijective( aut, true );
            Add( automorphisms, aut );
        od;
        SetAutomorphismGroup( Q, GroupByGenerators( automorphisms ) );
        datarec.pQuotient := Q;
    fi;

    #PushOptions(rec(nonuser := true));
    Qclass := PClassPGroup( datarec.pQuotient );
    if VALUE_PQ_OPTION("ClassBound", 63) <= Qclass then
        Error( "option `ClassBound' must be greater than `pQuotient' class (",
               Qclass, ")\n" );
    fi;
    PQ_PC_PRESENTATION(datarec, "SP" : ClassBound := Qclass);

    PQ_SP_STANDARD_PRESENTATION(datarec);

    PQ_SP_ISOMORPHISM(datarec);

    if datarec.calltype = "non-interactive" then
        PQ_COMPLETE_NONINTERACTIVE_FUNC_CALL(datarec);
        if IsBound( datarec.setupfile ) then
            #PopOptions();
            return true;
        fi;
    fi;

    # try to read output
    result := ANUPQReadOutput( ANUPQData.SPimages );

    if not IsBound(result.ANUPQmagic)  then
        Error("something wrong with `pq' binary. Please check installation\n");
    fi;

    desc := rec();
    result.ANUPQgroups[Length(result.ANUPQgroups)](desc);
#    if result.ANUPQautos <> fail and
#       Length( result.ANUPQautos ) = Length( result.ANUPQgroups ) then
#    	result.ANUPQautos[ Length(result.ANUPQgroups) ]( desc.group );
#    fi;

    # revise images to correspond to images of user-supplied generators
    datarec.SP := desc.group;
    x  := Length( desc.map );
    k  := Length( GeneratorsOfGroup( datarec.group ) );
    # images of user supplied generators are last k entries in .pqImages

    datarec.SPepi := GroupHomomorphismByImagesNC(
                         datarec.group,
                         datarec.SP,
                         GeneratorsOfGroup(datarec.group),
                         desc.map{[x - k + 1..x]} );
    #PopOptions();
    return datarec.SPepi;
end );

#############################################################################
##
#F  EpimorphismPqStandardPresentation( <arg> ) . . . epi. onto SP for p-group
##
InstallGlobalFunction( EpimorphismPqStandardPresentation, function( arg )
    return PQ_EPIMORPHISM_STANDARD_PRESENTATION( arg );
end );

#############################################################################
##
#F  PqStandardPresentation( <arg> : <options> ) . . . . . . .  SP for p-group
##
InstallGlobalFunction( PqStandardPresentation, function( arg )
    local SPepi;

    SPepi := PQ_EPIMORPHISM_STANDARD_PRESENTATION( arg );
    if SPepi = true then
      return true; # the SetupFile case
    fi;
    return Range( SPepi );
end );

#############################################################################
##
#M  EpimorphismStandardPresentation( <F> ) . . . . . epi. onto SP for p-group
#M  EpimorphismStandardPresentation( [<i>] )
##
InstallMethod( EpimorphismStandardPresentation,
               "fp group", [IsFpGroup], 0,
               EpimorphismPqStandardPresentation );

InstallMethod( EpimorphismStandardPresentation,
               "pc group", [IsPcGroup], 0,
               EpimorphismPqStandardPresentation );

InstallMethod( EpimorphismStandardPresentation,
               "positive integer", [IsPosInt], 0,
               EpimorphismPqStandardPresentation );

InstallOtherMethod( EpimorphismStandardPresentation,
                    "", [], 0,
                    EpimorphismPqStandardPresentation );

#############################################################################
##
#M  StandardPresentation( <F> ) . . . . . . . . . . . . . . .  SP for p-group
#M  StandardPresentation( [<i>] )
##
InstallMethod( StandardPresentation,
               "fp group", [IsFpGroup], 0,
               PqStandardPresentation );

InstallMethod( StandardPresentation,
               "pc group", [IsPcGroup], 0,
               PqStandardPresentation );

InstallMethod( StandardPresentation,
               "positive integer", [IsPosInt], 0,
               PqStandardPresentation );

InstallOtherMethod( StandardPresentation,
                    "", [], 0,
                    PqStandardPresentation );

#############################################################################
##
#F  IsPqIsomorphicPGroup( <G>, <H> )  . . . . . . . . . . .  isomorphism test
##
InstallGlobalFunction( IsPqIsomorphicPGroup, function( G, H )
    local   p,  class,  SG,  SH,  Ggens,  Hgens;

    # <G> and <H> must both be pc groups and p-groups
    if not IsPcGroup(G)  then
        Error( "<G> must be a pc group" );
    fi;
    if not IsPcGroup(H)  then
        Error( "<H> must be a pc group" );
    fi;
    if Size(G) <> Size(H)  then
        return false;
    fi;
    p := SmallestRootInt(Size(G));
    if not IsPrimeInt(p)  then
        Error( "<G> must be a p-group" );
    fi;

    # check the Frattini factor
    if RankPGroup(G) <> RankPGroup(H)  then
        return false;
    fi;

    # check the exponent-p length and the sizes of the groups in the
    # p-central series of both groups
    if List(PCentralSeries(G,p), Size) <> List(PCentralSeries(H,p), Size) then
        return false;
    fi;

    # if the groups are elementary abelian they are isomorphic
    class := PClassPGroup(G);
    if class = 1  then
        return true;
    fi;

    # compute a standard presentation for both
    SG := PqStandardPresentation(PqFpGroupPcGroup(G)
                                 : Prime := p, ClassBound := class);
    SH := PqStandardPresentation(PqFpGroupPcGroup(H)
                                 : Prime := p, ClassBound := class);

    # the groups are equal if the presentation are equal
    Ggens := GeneratorsOfGroup( FreeGroupOfFpGroup( SG ) );
    Hgens := GeneratorsOfGroup( FreeGroupOfFpGroup( SH ) );
    return RelatorsOfFpGroup(SG)
           = List( RelatorsOfFpGroup(SH),
                   x -> MappedWord( x, Hgens, Ggens ) );

end );

#############################################################################
##
#M  IsIsomorphicPGroup( <F>, <G> )
##
InstallMethod( IsIsomorphicPGroup, "pc group, pc group",
               [IsPcGroup, IsPcGroup], 0,
               IsPqIsomorphicPGroup );

#E  anusp.gi  . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here

max_stars_repo_name: gap-system/anupq

max_issues_repo_name: gap-system/anupq

max_forks_repo_name: gap-system/anupq


text:
Find := function(v, x)
  local low, high, mid;
  low := 1;
  high := Length(v);
  while low <= high do
    mid := QuoInt(low + high, 2);
    if v[mid] > x then
      high := mid - 1;
    elif v[mid] < x then
      low := mid + 1;
    else
      return mid;
    fi;
  od;
  return fail;
end;

u := [1..10]*7;
# [ 7, 14, 21, 28, 35, 42, 49, 56, 63, 70 ]
Find(u, 34);
# fail
Find(u, 35);
# 5

ext: gap

max_issues_repo_name: seanwallawalla-forks/RosettaCodeData

max_forks_repo_name: seanwallawalla-forks/RosettaCodeData


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

# These options should be used for compiling PRDFT
#
PRDFTDefaults := CopyFields(SpiralDefaults, rec(
	formulaStrategies  := rec(
               sigmaSpl    := [ sigma.StandardSumsRules, sigma.HfuncSumsRules ],
	       rc          := [ sigma.StandardSumsRules, sigma.HfuncSumsRules ],
	       preRC       := [],
               postProcess := []
	),

	compileStrategy := compiler.SimpleCS,
));

# BBDefaults := unr -> CopyFields(SpiralDefaults, rec(
# 	formulaStrategies  := rec(
#                sigmaSpl    := libgen.LibStrategy,
# 	       rc          := sigma.RCStrategy,
# 	       preRC       := [],
#                postProcess := [
# 		   (opts, s) -> BlockSums(unr, s),
# 		   sigma.BBLocalize
# 	       ]
# 	),

# 	# NOTE: memo variables were breaking with other compile strategies
# 	compileStrategy := compiler.NoCSE,
# 	generateInitFunc := true,

# 	codegen := DefaultCodegen,
# 	unparser := CUnparserProg
# ));


text:
# Copyright (c) 2018-2020, Carnegie Mellon University
# See LICENSE for details
#
# Top-level qCirc object and associated helpers
#

##
#F CircTerm( <ops>, <n>, <arch> )
##
#F given a list of operations to perform on  target qubits, the number of qubits, and the hardware architecture,
#F expand out the qCircuit object as a matrix product of qEmbed objects
##
CircTerm := function(ops, n, arch)
    local mat, h, oper;
    mat := I(2^(n));
    for oper in ops do
        # oper is [[1,2,3], qHT], for example
        h := qEmbed(oper[1], n, arch, oper[2]).terminate();
        mat := mat * h;
    od;
    return mat;
end;

##
#F ArchUpdate( <oplist>, <arch> )
##
#F updates all operations in oplist to use the new architecture
##
ArchUpdate := function(oplist, arch)
    local newlist, ops, qubits, T;
    newlist := [];
    for ops in oplist do
        # op is [[qubits], Transform]
        qubits := ops[1];
        T := ops[2].recursive_def(arch);
        Add(newlist, [qubits, T]);
    od;
    return newlist;
end;

##
#F qCirc( <arch>, <n>, <ops>) Object
##
#F Given architecture arch and number of qubits n, embed each operation in ops
#F an operation is a [[qubit list], <Non-Terminal>] list
#F ops in an operation list
Class(qCirc, TaggedNonTerminal, rec(
  abbrevs   := [ (arch, n, ops) -> Checked(IsPosInt(n), [arch, n, ops]) ],
  dims      := self >> let(size := 2^self.params[2], [size, size]),
  terminate := self >> CircTerm(self.params[3], self.params[2], self.params[1]),
  isReal    := self >> false,
  recursive_def := (self, arch) >> self.__bases__[1](arch, self.params[2], ArchUpdate(self.params[3], arch) ),
  rChildren := self >> self.params,
  from_rChildren := (self, rch) >> self.__bases__[1](rch[1], rch[2], rch[3]),
  SmallRandom := () -> Random([2..5]),
  LargeRandom := () -> Random([6..15]),
  normalizedArithCost := self >> Error("ArithCost not implemented"),
  TType := T_Complex(64)
));

##
#F GenCircChildren( <arch>, <n>, <ops> )
##
#F given a list of operations to perform on target qubits, the number of qubits, and the hardware architecture,
#F expand out the qCircuit object as a matrix product of qEmbed objects
##
GenCircChildren := function(arch, n, ops)
    local current_op, ops, h1, h, rest;
    current_op := ops[1];
    h1 := qEmbed(current_op[1], n, arch, current_op[2]);
    h := h1;
    if Length(ops) > 1 then
        rest := [2..Length(ops)];
        rest := Map(rest, i -> ops[i]);
        h := h * qCirc(arch, n, rest);
    fi;
    return [h];
end;

##
#F qCirc Breakdown Rules
##
NewRulesFor(qCirc, rec(

    # qCirc_Expand rule
    # qCirc_Expand qCirc(arch, n, ops) -> qEmbed(qubits, n, arch, <Non-Terminal>) * ...
    qCirc_Expand := rec (
        forTransposition := false,
        minSize          := 2,
        applicable       := (self, nt) >> (nt.params[3] <> []),
        children         := nt -> List([GenCircChildren(nt.params[1], nt.params[2], nt.params[3])]),
        apply            := (nt, c, cnt) -> c[1],
        switch := true,
    ),

    # qCirc_Base rule
    # QCirc_Base qCirc(arch, n, []) -> I(2^n)
    qCirc_Base := rec(
        info             := "qCirc -> Identity",
        forTransposition := false,
        applicable       := (self, nt) >> (nt.params[3] = []),
        apply            := (nt, c, cnt) -> I(2^(nt.params[2])),
    )

));

max_stars_repo_name: spiral-software/spiral-package-quantum

max_issues_repo_name: spiral-software/spiral-package-quantum

max_forks_repo_name: spiral-software/spiral-package-quantum


text:
.data
firebase.json
node_modules
.DS_Store
.env
package-lock.json
build

max_stars_repo_name: ans-group/basebot

max_issues_repo_name: ans-group/basebot

max_forks_repo_name: ans-group/basebot


text:
local reps,tori,labels,I,II,ords,blocks;

reps:=[[[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1]],#E_8
[[1,1],[2,1],[10,1],[11,1],[5,1],[6,1],[7,1],[8,1]],#E_8(a_1)
[[1,1],[2,1],[3,1],[10,1],[12,1],[13,1],[14,1],[8,1]],#E_8(a_2)
[[7,1],[8,1],[9,1],[10,1],[11,1],[12,1],[13,1],[19,1]],#E_8(a_3)
[[9,1],[10,1],[11,1],[12,1],[13,1],[14,1],[15,1],[19,1]],#E_8(a_4)
[[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1]],#E_7
[[7,1],[8,1],[9,1],[17,1],[18,1],[19,1],[20,1],[21,1]],#E_8(b_4)
[[9,1],[14,1],[15,1],[17,1],[18,1],[19,1],[20,1],[26,1]],#E_8(a_5)
[[1,1],[3,1],[10,1],[11,1],[5,1],[6,1],[7,1]],#E_7(a_1)
[[8,1],[16,1],[17,1],[18,1],[20,1],[21,1],[24,1],[33,1]],#E_8(b_5)
[[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1]],#D_7
[[4,1],[10,1],[12,1],[14,1],[15,1],[26,1],[27,1],[30,1]],#E_8(a_6)
[[1,1],[2,1],[3,1],[10,1],[12,1],[13,1],[14,1]],#E_7(a_2)
[[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[8,1]],#E_6+A_1
#[[2,1],[3,1],[10,1],[12,1],[6,1],[7,1],[8,1],[83,1]],#(D_7(a_1))^{(2)}
[[2,1],[3,1],[10,1],[12,1],[6,1],[7,1],[8,1]],#D_7(a_1)
[[15,1],[22,1],[23,1],[24,1],[25,1],[26,1],[27,1],[28,1]],#E_8(b_6)
[[1,1],[4,1],[7,1],[12,1],[13,1],[17,1],[19,1]],#E_7(a_3)
[[1,1],[2,1],[11,1],[12,1],[5,1],[6,1],[8,1]],#E_6(a_1)+A_1
[[1,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[67,1]],#(A_7)^{(3)}
[[1,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1]],#A_7
[[2,1],[3,1],[10,1],[12,1],[13,1],[14,1],[8,1]],#D_7(a_2)
[[1,1],[2,1],[3,1],[4,1],[5,1],[6,1]],#E_6
[[2,1],[3,1],[4,1],[5,1],[6,1],[7,1]],#D_6
#[[1,1],[2,1],[3,1],[4,1],[5,1],[7,1],[8,1],[51,1]],#(D_5+A_2)^{(2)}
[[1,1],[2,1],[3,1],[4,1],[5,1],[7,1],[8,1]],#D_5+A_2
[[1,1],[2,1],[11,1],[12,1],[5,1],[6,1]],#E_6(a_1)
[[1,1],[4,1],[7,1],[11,1],[25,1],[26,1],[27,1]],#E_7(a_4)
[[1,1],[2,1],[4,1],[5,1],[6,1],[7,1],[8,1]],#A_6+A_1
[[2,1],[3,1],[10,1],[12,1],[6,1],[7,1]],#D_6(a_1)
[[1,1],[3,1],[4,1],[5,1],[6,1],[7,1]],#A_6
[[30,1],[33,1],[35,1],[36,1],[40,1],[45,1],[53,1],[58,1]],#E_8(a_7)
[[1,1],[2,1],[3,1],[4,1],[5,1],[7,1]],#D_5+A_1
[[4,1],[11,1],[14,1],[16,1],[24,1],[25,1],[26,1]],#E_7(a_5)
[[4,1],[6,1],[9,1],[11,1],[18,1],[19,1],[8,1]],#E_6(a_3)+A_1
[[2,1],[3,1],[10,1],[12,1],[13,1],[14,1]],#D_6(a_2)
[[1,1],[10,1],[11,1],[2,1],[5,1],[7,1],[8,1]],#D_5(a_1)+A_2
[[1,1],[3,1],[4,1],[5,1],[6,1],[8,1]],#A_5+A_1
[[1,1],[3,1],[4,1],[2,1],[6,1],[7,1],[8,1]],#A_4+A_3
[[1,1],[2,1],[3,1],[4,1],[5,1]],#D_5
[[4,1],[6,1],[9,1],[11,1],[18,1],[19,1]],#E_6(a_3)
#[[2,1],[3,1],[4,1],[5,1],[7,1],[8,1],[63,1]],#(D_4+A_2)^{(2)}
[[2,1],[3,1],[4,1],[5,1],[7,1],[8,1]],#D_4+A_2
[[1,1],[3,1],[2,1],[5,1],[6,1],[7,1],[8,1]],#A_4+A_2+A_1
[[1,1],[10,1],[11,1],[2,1],[5,1],[7,1]],#D_5(a_1)+A_1
[[1,1],[3,1],[4,1],[5,1],[6,1]],#A_5
[[1,1],[3,1],[4,1],[2,1],[6,1],[7,1]],#A_4+A_2
[[1,1],[3,1],[4,1],[2,1],[6,1],[8,1]],#A_4+2A_1
[[1,1],[10,1],[11,1],[2,1],[5,1]],#D_5(a_1)
[[1,1],[3,1],[4,1],[6,1],[7,1],[8,1]],#2A_3
[[1,1],[3,1],[4,1],[5,1],[7,1]],#A_4+A_1
[[2,1],[3,1],[10,1],[12,1],[7,1],[8,1]],#D_4(a_1)+A_2
[[2,1],[3,1],[4,1],[5,1],[7,1]],#D_4+A_1
[[1,1],[3,1],[2,1],[5,1],[6,1],[7,1]],#A_3+A_2+A_1
[[1,1],[3,1],[4,1],[5,1]],#A_4
#[[1,1],[3,1],[4,1],[6,1],[7,1],[44,1]],#(A_3+A_2)^{(2)}
[[1,1],[3,1],[4,1],[6,1],[7,1]],#A_3+A_2
[[2,1],[3,1],[10,1],[12,1],[7,1]],#D_4(a_1)+A_1
[[1,1],[3,1],[4,1],[6,1],[8,1]],#A_3+2A_1
[[1,1],[3,1],[2,1],[5,1],[6,1],[8,1]],#2A_2+2A_1
[[2,1],[3,1],[4,1],[5,1]],#D_4
[[2,1],[3,1],[10,1],[12,1]],#D_4(a_1)
[[1,1],[3,1],[4,1],[6,1]],#A_3+A_1
[[1,1],[3,1],[2,1],[5,1],[6,1]],#2A_2+A_1
[[1,1],[3,1],[5,1],[6,1]],#2A_2
[[1,1],[3,1],[2,1],[5,1],[7,1]],#A_2+3A_1
[[1,1],[3,1],[4,1]],#A_3
[[1,1],[3,1],[5,1],[7,1]],#A_2+2A_1
[[1,1],[3,1],[5,1]],#A_2+A_1
[[1,1],[2,1],[5,1],[7,1]],#4A_1
[[1,1],[3,1]],#A_2
[[1,1],[2,1],[5,1]],#3A_1
[[1,1],[2,1]],#2A_1
[[1,1]]#A_1
];

labels:=["E_8",
"E_8(a_1)",
"E_8(a_2)",
"E_8(a_3)",
"E_8(a_4)",
"E_7",
"E_8(b_4)",
"E_8(a_5)",
"E_7(a_1)",
"E_8(b_5)",
"D_7",
"E_8(a_6)",
"E_7(a_2)",
"E_6+A_1",
#"(D_7(a_1))^{(2)}",
"D_7(a_1)",
"E_8(b_6)",
"E_7(a_3)",
"E_6(a_1)+A_1",
"(A_7)^{(3)}",
"A_7",
"D_7(a_2)",
"E_6",
"D_6",
#"(D_5+A_2)^{(2)}",
"D_5+A_2",
"E_6(a_1)",
"E_7(a_4)",
"A_6+A_1",
"D_6(a_1)",
"A_6",
"E_8(a_7)",
"D_5+A_1",
"E_7(a_5)",
"E_6(a_3)+A_1",
"D_6(a_2)",
"D_5(a_1)+A_2",
"A_5+A_1",
"A_4+A_3",
"D_5",
"E_6(a_3)",
#"(D_4+A_2)^{(2)}",
"D_4+A_2",
"A_4+A_2+A_1",
"D_5(a_1)+A_1",
"A_5",
"A_4+A_2",
"A_4+2A_1",
"D_5(a_1)",
"2A_3",
"A_4+A_1",
"D_4(a_1)+A_2",
"D_4+A_1",
"A_3+A_2+A_1",
"A_4",
#"(A_3+A_2)^{(2)}",
"A_3+A_2",
"D_4(a_1)+A_1",
"A_3+2A_1",
"2A_2+2A_1",
"D_4",
"D_4(a_1)",
"A_3+A_1",
"2A_2+A_1",
"2A_2",
"A_2+3A_1",
"A_3",
"A_2+2A_1",
"A_2+A_1",
"4A_1",
"A_2",
"3A_1",
"2A_1",
"A_1"
];

I:=[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]];#,[]];

II:=[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]];#,[]];

tori:=[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]];#,[]];

blocks:=[];
blocks:=[[[55, 1], [45, 1], [39, 1], [27, 3], [19, 1], [9, 1]], [[27, 8], [25, 1], [7, 1]], [[27, 6], [25, 1], [21, 1], [19, 1], [9, 2], [3, 1]], [[27, 4], [25, 1], [19, 1], [18, 2], [15, 1], [12, 2], [9, 2], [3, 1]], [[27, 2], [25, 1], [21, 2], [18, 2], [15, 2], [12, 2], [9, 3], [7, 1], [3, 1]], [[27, 3], [26, 2], [19, 1], [18, 2], [15, 1], [12, 2], [9, 2], [1, 3]], [[27, 1], [21, 1], [19, 2], [18, 4], [15, 1], [9, 8], [3, 1]], [[23, 2], [21, 1], [19, 1], [17, 1], [15, 3], [12, 4], [11, 2], [9, 1], [7, 1], [5, 1], [3, 3]], [[27, 1], [20, 2], [19, 1], [18, 4], [15, 1], [9, 8], [1, 3]], [[19, 1], [18, 4], [15, 1], [12, 2], [9, 12], [7, 1], [3, 1]], [[23, 1], [22, 2], [19, 1], [16, 2], [15, 1], [13, 3], [12, 2], [11, 1], [10, 2], [7, 1], [4, 2], [3, 1], [1, 3]], [[19, 1], [18, 2], [15, 3], [13, 3], [9, 9], [7, 1], [6, 2], [3, 3]], [[19, 1], [18, 4], [15, 1], [12, 2], [9, 11], [8, 2], [1, 3]], [[19, 1], [15, 8], [9, 9], [3, 8], [2, 2]], [[19, 1], [17, 2], [15, 3], [12, 2], [11, 4], [9, 5], [6, 4], [3, 4], [1, 1]], [[9, 25], [8, 2], [2, 2], [1, 3]], [[19, 1], [17, 1], [16, 2], [15, 2], [12, 2], [11, 2], [10, 4], [9, 3], [6, 4], [3, 2], [2, 2], [1, 3]], [[9, 26], [7, 1], [3, 1], [2, 2]], [[9, 25], [8, 2], [3, 1], [2, 2]], [[9, 25], [8, 2], [2, 2], [1, 3]], [[9, 23], [7, 1], [6, 2], [5, 2], [4, 2], [3, 1], [1, 1]], [[19, 1], [15, 8], [9, 9], [3, 7], [1, 7]], [[19, 1], [16, 4], [15, 1], [11, 5], [10, 4], [9, 2], [6, 4], [3, 1], [1, 10]], [[9, 21], [7, 2], [6, 4], [3, 7]], [[9, 26], [7, 1], [1, 7]], [[9, 20], [8, 2], [7, 1], [6, 4], [3, 6], [1, 3]], [[9, 19], [8, 2], [7, 4], [6, 2], [3, 6], [1, 3]], [[9, 19], [8, 4], [6, 4], [3, 5], [1, 6]], [[9, 19], [7, 8], [3, 5], [1, 6]], [[9, 14], [7, 2], [6, 8], [5, 6], [3, 10]], [[9, 19], [8, 2], [7, 4], [6, 2], [3, 1], [2, 6], [1, 6]], [[9, 13], [8, 2], [7, 1], [6, 8], [5, 3], [4, 6], [3, 6], [1, 3]], [[9, 10], [7, 1], [6, 16], [3, 17], [2, 2]], [[9, 13], [7, 5], [6, 4], [5, 5], [4, 8], [3, 3], [1, 6]], [[9, 9], [8, 2], [6, 16], [3, 17], [2, 2]], [[9, 9], [8, 2], [6, 16], [3, 16], [2, 2], [1, 3]], [[9, 7], [8, 2], [7, 6], [6, 6], [5, 6], [4, 6], [3, 10], [2, 2], [1, 3]], [[9, 19], [7, 8], [1, 21]], [[9, 10], [7, 1], [6, 16], [3, 16], [1, 7]], [[9, 8], [7, 7], [6, 12], [3, 16], [1, 7]], [[9, 3], [8, 2], [7, 1], [6, 18], [5, 3], [3, 25]], [[9, 5], [8, 6], [7, 4], [6, 12], [3, 11], [2, 8], [1, 6]], [[9, 9], [8, 2], [6, 16], [3, 15], [1, 10]], [[9, 3], [7, 5], [6, 16], [5, 3], [3, 24], [1, 3]], [[9, 1], [8, 4], [7, 3], [6, 12], [5, 7], [4, 4], [3, 17], [2, 4], [1, 4]], [[9, 3], [8, 8], [7, 6], [6, 10], [3, 8], [2, 8], [1, 15]], [[8, 4], [7, 6], [6, 4], [5, 10], [4, 16], [3, 6], [2, 4], [1, 10]], [[9, 1], [8, 2], [7, 7], [6, 8], [5, 9], [4, 6], [3, 12], [2, 6], [1, 9]], [[7, 1], [6, 14], [5, 6], [3, 42], [1, 1]], [[9, 2], [8, 6], [7, 13], [6, 6], [3, 2], [2, 14], [1, 21]], [[7, 1], [6, 14], [5, 3], [4, 6], [3, 37], [2, 2], [1, 3]], [[9, 1], [7, 11], [5, 21], [3, 11], [1, 24]], [[7, 1], [6, 12], [5, 5], [4, 8], [3, 34], [1, 10]], [[7, 1], [6, 8], [5, 12], [4, 6], [3, 28], [2, 8], [1, 9]], [[7, 1], [6, 6], [5, 11], [4, 14], [3, 19], [2, 12], [1, 13]], [[3, 80], [2, 4]], [[9, 2], [7, 25], [3, 1], [1, 52]], [[7, 1], [6, 2], [5, 24], [3, 27], [1, 28]], [[7, 1], [6, 2], [5, 15], [4, 18], [3, 10], [2, 14], [1, 24]], [[3, 79], [2, 2], [1, 7]], [[3, 78], [1, 14]], [[3, 70], [2, 14], [1, 10]], [[7, 1], [5, 11], [4, 32], [3, 1], [1, 55]], [[3, 65], [2, 16], [1, 21]], [[3, 58], [2, 20], [1, 34]], [[3, 44], [2, 40], [1, 36]], [[3, 57], [1, 77]], [[3, 31], [2, 50], [1, 55]], [[3, 14], [2, 64], [1, 78]], [[3, 1], [2, 56], [1, 133]]];

#ords:=[];
ords:=[ 81, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 9, 9, 9, 9, 27, 27, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 9, 9, 9, 3, 3, 3, 9, 3, 3, 3, 3, 3, 3, 3 ];

return [reps,tori,labels,I,II,ords,blocks];


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

Class(AsmX86Unparser, Unparser, rec(

    asmvolatile := meth(self, o)
        local oo,a,x;

	a := [];
        oo := self.preprocess(o);
	while(ObjId(oo)=data) do
	  oo.var.asmpseudoregister:=Length(a);
	  Append(a,[[oo.var,oo.value]]);
	  Print("static const double ",oo.var.id,"=",oo.value.v,";\n");
	  oo:=oo.cmd;
	 od;
        Print(
	    "asm volatile (\n",
            Unparse(oo, self, 4, 2),
	    ":: ");
	for x in a do
	   Print("\"m\"(",x[1].id,"), ");
	od;
	Print("\"eax\"(X), \"ecx\"(Y));");
    end,

    preprocess := (self, o) >> o,

    # NOTE: dynamically set mul and ofs based on X.t, Y.t
    #        note -- these are in bytes (8 bytes = 64 bits = double fp)
    #switched to double %% for asm volatile
    regmap := rec(
	S := rec(reg:="%%esp",ofs:=-8, mul:=-8),
	X := rec(reg:="%%eax",ofs:=0, mul:=8),
	Y := rec(reg:="%%ecx",ofs:=0, mul:=8),

	A := rec(reg:="%%eax",ofs:=0, mul:=16),
	B := rec(reg:="%%ebx",ofs:=0, mul:=8),
	C := rec(reg:="%%ecx",ofs:=0, mul:=16),

	r0 := rec(reg:="%%xmm0"),
	r1 := rec(reg:="%%xmm1"),
	r2 := rec(reg:="%%xmm2"),
	r3 := rec(reg:="%%xmm3"),
	r4 := rec(reg:="%%xmm4"),
	r5 := rec(reg:="%%xmm5"),
	r6 := rec(reg:="%%xmm6"),
	r7 := rec(reg:="%%xmm7"),
	r8 := rec(reg:="%%xmm8"),
	r9 := rec(reg:="%%xmm9"),
	r10 := rec(reg:="%%xmm10"),
	r11 := rec(reg:="%%xmm11"),
	r12 := rec(reg:="%%xmm12"),
	r13 := rec(reg:="%%xmm13"),
	r14 := rec(reg:="%%xmm14"),
	r15 := rec(reg:="%%xmm15"),

	A0 := rec(reg:="%%xmm8"),
	A1 := rec(reg:="%%xmm9"),
	A2 := rec(reg:="%%xmm10"),
	A3 := rec(reg:="%%xmm11"),
	A4 := rec(reg:="%%xmm12"),
	A5 := rec(reg:="%%xmm13"),
	A6 := rec(reg:="%%xmm14"),
	A7 := rec(reg:="%%xmm15"),
    ),

    startFunc := meth(self, fname, stackofs, loadptrs)
        local v, i;
        PrintLine(".globl ", fname);
#	PrintLine("    .def  _", fname, "; .scl 2; .type 32; .endef");
        PrintLine("    .type  ", fname, ", @function");
	PrintLine("", fname, ":");

	# load arguments into registers
	for i in [1..Length(loadptrs)] do
	    v := loadptrs[i];
	    PrintLine("    movl  ", (stackofs+i-1)*4, "(%esp), ", self.regmap.(v.id).reg);
	od;
    end,

    header_top := meth(self, subname, o)
        local precomputed_data;
	PrintLine("    .data");
	PrintLine("    .align 8");
        precomputed_data := List(Collect(o, data), x->[x.var, x.value]);
	DoForAll(precomputed_data, d -> self.genData(d[1], d[2]));
	PrintLine("");
	PrintLine("    .text");
	PrintLine("    .align 8");
    end,

    header_func := (self, subname, o) >> self.startFunc(subname, 1, [Y, X]),

    header := meth(self, subname, o)
        self.header_top(subname, o);
        self.header_func(subname, o);
    end,

    footer := meth(self, subname, o)
        local init, loopvars;
	PrintLine("    ret");
	PrintLine("");
	self.startFunc(Concat("init_", subname), 0, []);
	PrintLine("    ret");
    end,

    genData := (self, v, val) >> Cond(
	val.t = TDouble, PrintLine(v, ": .double ", val.v),
	val.t = TInt,    PrintLine(v, ": .long ", val.v),
	IsArray(val.t) and val.t.t = TDouble,
	    val.t.t=TDouble, PrintLine(v, ": .double ", PrintCS(val.v)),
	IsArray(val.t) and val.t.t = TInt,
	    val.t.t=TDouble, PrintLine(v, ": .long ", PrintCS(val.v)),
        Error("Can't handle type ", val.t)),

    ###################
    # Helpers
    ###################

#HERE is a HACK to print correct GCC intrincsics
#old code is commented out
    instr2 := (self, mnem, src, dest) >>
#        Print("    ", mnem, "  ", self(src,0,0), ", ", self(dest,0,0), "\n"),
        Print("\"    ", mnem, "  ", self(src,0,0), ", ", self(dest,0,0), "\\n\\t\"\n"),

    isReg := (self, loc) >> IsVar(loc) and IsBound(self.regmap.(loc.id)),

    ####################
    ## General
    ####################
    atomic  := (self,o,i,is) >> Print(o),
    Loc     := (self,o,i,is) >> o.cprint(),

    ####################
    ## Commands
    ####################

    # just sequence them
    #removed the chain label
#    chain := (self,o,i,is) >> Print("chain_", BagAddr(o), ":\n",
#	DoForAll(o.cmds, c -> self(c, i, is))),
    chain := (self,o,i,is) >> Print( DoForAll(o.cmds, c -> self(c, i, is))),

    # all datas are handled in the header, just proceed to children
    data := (self,o,i,is) >> self(o.cmd, i, is),

    # nothing need to be declared in assembly, we just have registers and stack space
    decl := (self,o,i,is) >> self(o.cmd, i, is),

    # on Pentium M using sd seems to be more efficient
    assign     := (self,o,i,is) >> let(
	sfx := When(self.isReg(o.exp) and self.isReg(o.loc), "sd", "sd"), # apd
	self.instr2(Concat("mov", sfx), o.exp, o.loc)),

    assign_add := (self,o,i,is) >> let(
	sfx := When(self.isReg(o.exp) and self.isReg(o.loc), "sd", "sd"),
	self.instr2(Concat("add",sfx), o.exp, o.loc)),

    assign_sub := (self,o,i,is) >> let(
	sfx := When(self.isReg(o.exp) and self.isReg(o.loc), "sd", "sd"),
	self.instr2(Concat("sub", sfx), o.exp, o.loc)),

    assign_mul := (self,o,i,is) >> let(
	sfx := When(self.isReg(o.exp) and self.isReg(o.loc), "sd", "sd"),
	self.instr2(Concat("mul", sfx), o.exp, o.loc)),

    ####################
    ## Expressions
    ####################

    Exp := (self,o,i,is) >> Error("X86 Assembly backend expects 2-operand low-level representation, it must not have expressions, so I can't handle <o>"),

    dup := (self,o,i,is) >>
        Print( "shufpd(", self.regmap.(o.args[1].id).reg, ")"),

    nth := (self,o,i,is) >> Checked(IsValue(o.idx),
	let(d := self.regmap.(o.loc.id),
	    Print( (o.idx.v * d.mul + d.ofs), "(", d.reg, ")"))),

    var := (self,o,i,is) >> When(IsBound(self.regmap.(o.id)),
	Print(self.regmap.(o.id).reg),
	When(IsBound(o.asmpseudoregister),Print("%",o.asmpseudoregister),
	Print(o.id))),

    Value := CUnparser.Value
));