From e234989a81e3cfc36ebb79b6c522203d416a0c92 Mon Sep 17 00:00:00 2001 From: Steve Linton Date: Mon, 1 Feb 2016 16:53:01 +0000 Subject: [PATCH] Added Kernel functions for eager permutation accumulators. --- lib/eagerpermacc.gi | 7 ++ lib/genacc.gi | 3 + lib/lazypermacc.gi | 3 +- lib/read1.g | 1 + lib/read5.g | 2 + src/permutat.c | 222 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 lib/eagerpermacc.gi diff --git a/lib/eagerpermacc.gi b/lib/eagerpermacc.gi new file mode 100644 index 00000000000..375b407db40 --- /dev/null +++ b/lib/eagerpermacc.gi @@ -0,0 +1,7 @@ + +DeclareRepresentation("IsEagerPermutationAccumulatorRep", + IsDataObjectRep and IsPermutationAccumulator, 2); + +BindGlobal("DefaultTypeEagerPermAccumulator", + NewType(AccumulatorsFamily, IsMutable and IsEagerPermutationAccumulatorRep)); + diff --git a/lib/genacc.gi b/lib/genacc.gi index 22065e4794d..b3aa7ac50eb 100644 --- a/lib/genacc.gi +++ b/lib/genacc.gi @@ -1,3 +1,6 @@ +BindGlobal("AccumulatorsFamily", NewFamily(IsAccumulator)); + + InstallMethod(Conjugate, [IsAccumulator and IsMutable, IsMultiplicativeElementWithInverse], function(acc, x) acc := LeftDivide(acc, x); diff --git a/lib/lazypermacc.gi b/lib/lazypermacc.gi index 3b7b55c8b75..68867fd09df 100644 --- a/lib/lazypermacc.gi +++ b/lib/lazypermacc.gi @@ -1,6 +1,5 @@ DeclareRepresentation("IsLazyPermutationAccumulatorRep", IsPositionalObjectRep and IsPermutationAccumulator, 2); -BindGlobal("AccumulatorsFamily", NewFamily(IsAccumulator)); BindGlobal("LazyPermutationAccumulatorDefaultType", NewType(AccumulatorsFamily, IsMutable and IsLazyPermutationAccumulatorRep)); @@ -141,4 +140,4 @@ end); - +#T View/Print diff --git a/lib/read1.g b/lib/read1.g index 5a54ff31fc0..713bc15bfc1 100644 --- a/lib/read1.g +++ b/lib/read1.g @@ -85,3 +85,4 @@ ReadLib( "session.g" ); ReadLib( "float.gd" ); ReadLib( "macfloat.g" ); + diff --git a/lib/read5.g b/lib/read5.g index abb0c0666e0..6057798ffa1 100644 --- a/lib/read5.g +++ b/lib/read5.g @@ -264,3 +264,5 @@ ReadLib( "ieee754.g" ); ReadLib("genacc.gi"); ReadLib("permacc.gi"); ReadLib("lazypermacc.gi"); +ReadLib("eagerpermacc.gi"); + diff --git a/src/permutat.c b/src/permutat.c index d0904d064e6..51ef0da0e0c 100644 --- a/src/permutat.c +++ b/src/permutat.c @@ -96,6 +96,9 @@ #define ADDR_PERM4(perm) ((UInt4*)ADDR_OBJ(perm)) */ +#define IS_PERM2(perm) (TNUM_OBJ((perm)) == T_PERM2) +#define IS_PERM4(perm) (TNUM_OBJ((perm)) == T_PERM4) + /**************************************************************************** ** @@ -4718,7 +4721,198 @@ Obj FuncMappingPermListList(Obj self, Obj src, Obj dst) /**************************************************************************** ** +*F * * * * * * * * * * * * * permutation accumulators * * * * * * * * * * * * * * +*/ + +static Obj DefaultTypeEagerPermAccumulator; + +#define ADDR_PERMACC(b) ((UInt4*)(ADDR_OBJ((b))+1)) +#define DEG_PERMACC(b) ((SIZE_BAG((b))-sizeof(Obj))/sizeof(UInt4)) + +Obj FuncNEW_PERMACC(Obj self, Obj perm) { + UInt deg; + Obj accumulator; + int i; + if (IS_PERM2(perm)) + deg = DEG_PERM2(perm); + else + deg = DEG_PERM4(perm); + accumulator= NewBag(T_DATOBJ, sizeof(Obj) + 4*deg); + SetTypeDatObj(accumulator,DefaultTypeEagerPermAccumulator); + if (IS_PERM2(perm)) { + UInt2 *ptP = ADDR_PERM2(perm); + UInt4 *ptB = ADDR_PERMACC(accumulator); + for (i = 0; i < deg; i++) + ptB[i] = (UInt4)ptP[i]; + } else { + memmove(ADDR_PERMACC(accumulator), ADDR_PERM4(perm), 4*deg); + } + return accumulator; +} + +static void GrowPermAcc(Obj acc, UInt deg) { + UInt odeg = DEG_PERMACC(acc); + UInt i; + if (odeg < deg) { + ResizeBag(acc, 4*deg+sizeof(Obj)); + UInt4* ptA = ADDR_PERMACC(acc); + for (i = odeg; i < deg; i++) + ptA[i] = i; + } +} + +Obj FuncRIGHT_MULTIPLY_PERMACC(Obj self, Obj acc, Obj perm) { + UInt deg; + UInt i; + if (IS_PERM2(perm)) + deg = DEG_PERM2(perm); + else + deg = DEG_PERM4(perm); + GrowPermAcc(acc, deg); + UInt adeg = DEG_PERMACC(acc); + UInt4 *ptA = ADDR_PERMACC(acc); + if (IS_PERM2(perm)) { + UInt2 *ptP = ADDR_PERM2(perm); + if (adeg <= deg) { + for (i = 0; i < adeg; i++) + ptA[i] = ptP[ptA[i]]; + } else { + for (i = 0; i < adeg; i++) + ptA[i] = IMAGE(ptA[i], ptP, deg); + } + } else { + UInt4 *ptP = ADDR_PERM4(perm); + if (adeg <= deg) { + for (i = 0; i < adeg; i++) + ptA[i] = ptP[ptA[i]]; + } else { + for (i = 0; i < adeg; i++) + ptA[i] = IMAGE(ptA[i], ptP, deg); + } + } + return acc; +} + +Obj FuncLEFT_MULTIPLY_PERMACC(Obj self, Obj acc, Obj perm) { + UInt deg; + UInt i; + if (IS_PERM2(perm)) + deg = DEG_PERM2(perm); + else + deg = DEG_PERM4(perm); + GrowPermAcc(acc, deg); + UInt adeg = DEG_PERMACC(acc); + UseTmpPerm(4*adeg); + UInt4 *ptA = ADDR_PERMACC(acc); + UInt4 *ptT = ADDR_PERM4(TmpPerm); + if (IS_PERM2(perm)) { + UInt2 *ptP = ADDR_PERM2(perm); + for (i = 0; i < deg; i++) + ptT[i] = ptA[ptP[i]]; + } else { + UInt4 *ptP = ADDR_PERM4(perm); + for (i = 0; i < deg; i++) + ptT[i] = ptA[ptP[i]]; + } + memmove(ptA,ptT,4*deg); + return acc; +} +Obj FuncRIGHT_DIVIDE_PERMACC(Obj self, Obj acc, Obj perm) { + UInt deg; + UInt i; + UInt4 * ptT; + if (IS_PERM2(perm)) + deg = DEG_PERM2(perm); + else + deg = DEG_PERM4(perm); + UseTmpPerm(4*deg); + ptT = ADDR_PERM4(TmpPerm); + if (IS_PERM2(perm)) { + UInt2 *ptP = ADDR_PERM2(perm); + for (i = 0; i < deg; i++) + ptT[ptP[i]] = i; + } else { + UInt4 *ptP = ADDR_PERM4(perm); + for (i = 0; i < deg; i++) + ptT[ptP[i]] = i; + } + return FuncRIGHT_MULTIPLY_PERMACC(self,acc,TmpPerm); +} + +Obj FuncLEFT_DIVIDE_PERMACC(Obj self, Obj acc, Obj perm) { + UInt deg; + UInt i; + if (IS_PERM2(perm)) + deg = DEG_PERM2(perm); + else + deg = DEG_PERM4(perm); + GrowPermAcc(acc, deg); + UInt adeg = DEG_PERMACC(acc); + UseTmpPerm(4*adeg); + UInt4 *ptA = ADDR_PERMACC(acc); + UInt4 *ptT = ADDR_PERM4(TmpPerm); + if (IS_PERM2(perm)) { + UInt2 *ptP = ADDR_PERM2(perm); + for (i = 0; i < adeg; i++) + ptT[ptP[i]] = ptA[i]; + } else { + UInt4 *ptP = ADDR_PERM4(perm); + for (i = 0; i < adeg; i++) + ptT[ptP[i]] = ptA[i]; + } + memmove(ptA,ptT,4*adeg); + return acc; +} + +Obj FuncINVERT_PERMACC(Obj self, Obj acc) { + UInt i; + UInt adeg = DEG_PERMACC(acc); + UseTmpPerm(4*adeg); + UInt4 *ptA = ADDR_PERMACC(acc); + UInt4 *ptT = ADDR_PERM4(TmpPerm); + for (i = 0; i < adeg; i++) + ptT[ptA[i]] = i; + memmove(ptA,ptT,4*adeg); + return acc; +} + +Obj FuncSHALLOWCOPY_PERMACC(Obj self, Obj acc) { + Obj newacc = NewBag(T_DATOBJ, SIZE_BAG(acc)); + SetTypeDatObj(newacc, ADDR_OBJ(acc)[0]); + memmove(ADDR_PERMACC(newacc), ADDR_PERMACC(acc), DEG_PERMACC(acc)*4); + return newacc; +} + +Obj FuncVALUE_PERMACC(Obj self, Obj acc) { + UInt deg = DEG_PERMACC(acc); + UInt i; + Obj val; + if (deg < 65536) { + val = NEW_PERM2(deg); + UInt4 *ptA = ADDR_PERMACC(acc); + UInt2 *ptV = ADDR_PERM2(val); + for (i = 0; i < deg; i++) + ptV[i] = ptA[i]; + } else { + val = NEW_PERM4(deg); + memmove(ADDR_PERM4(val), ADDR_PERMACC(acc), 4*deg); + } + return val; +} + +Obj FuncONPOINTS_PERMACC(Obj self, Obj pt, Obj acc) { + UInt deg = DEG_PERMACC(acc); + UInt x = INT_INTOBJ(pt)-1; + UInt4 *ptA = ADDR_PERMACC(acc); + return INTOBJ_INT(IMAGE(x, ptA , deg)+1); +} + + + + +/**************************************************************************** +** *F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * * */ @@ -4805,7 +4999,33 @@ static StructGVarFunc GVarFuncs [] = { { "MappingPermListList", 2, "src, dst", FuncMappingPermListList, "src/permutat.c:MappingPermListList" }, + + {"NEW_PERMACC", 1, "perm", + FuncNEW_PERMACC, "src/permutat.c:NEW_PERMACC" }, + + {"RIGHT_MULTIPLY_PERMACC", 2, "acc, perm", + FuncRIGHT_MULTIPLY_PERMACC, "src/permutat.c:RIGHT_MULTIPLY_PERMACC" }, + + {"LEFT_MULTIPLY_PERMACC", 2, "acc, perm", + FuncLEFT_MULTIPLY_PERMACC, "src/permutat.c:LEFT_MULTIPLY_PERMACC" }, + + {"RIGHT_DIVIDE_PERMACC", 2, "acc, perm", + FuncRIGHT_DIVIDE_PERMACC, "src/permutat.c:RIGHT_DIVIDE_PERMACC" }, + + {"LEFT_DIVIDE_PERMACC", 2, "acc, perm", + FuncLEFT_DIVIDE_PERMACC, "src/permutat.c:LEFT_DIVIDE_PERMACC" }, + {"INVERT_PERMACC", 1, "acc", + FuncINVERT_PERMACC, "src/permutat.c:INVERT_PERMACC" }, + + {"SHALLOWCOPY_PERMACC", 1, "acc", + FuncSHALLOWCOPY_PERMACC, "src/permutat.c:SHALLOWCOPY_PERMACC" }, + + {"VALUE_PERMACC", 1, "acc", + FuncVALUE_PERMACC, "src/permutat.c:VALUE_PERMACC" }, + + {"ONPOINTS_PERMACC", 2, "pt, acc", + FuncONPOINTS_PERMACC, "src/permutat.c:ONPOINTS_PERMACC" }, { 0 } @@ -4834,6 +5054,7 @@ static Int InitKernel ( /* install the type functions */ ImportGVarFromLibrary( "TYPE_PERM2", &TYPE_PERM2 ); ImportGVarFromLibrary( "TYPE_PERM4", &TYPE_PERM4 ); + InitCopyGVar("DefaultTypeEagerPermAccumulator", &DefaultTypeEagerPermAccumulator ); TypeObjFuncs[ T_PERM2 ] = TypePerm2; TypeObjFuncs[ T_PERM4 ] = TypePerm4; @@ -4936,6 +5157,7 @@ static Int InitLibrary ( /* make the buffer bag */ TmpPerm = 0; + /* make the identity permutation */ IdentityPerm = NEW_PERM2(0);