/* */ #include "Algebras/Distributed2/DArray.h" #include "Algebras/Distributed2/fsrel.h" #include #include #include "Stream.h" #include "DmapPdmapTypeMapper.h" namespace distributed3 { DmapPdmapTypeMapper::DmapPdmapTypeMapper(ListExpr& _args) { args = _args; array = nl->First(args); // array name = nl->Second(args); // name of the result dmap1 = nl->Third(args); // function partitionfunction = nl->Fourth(args); // redistribution function numberOfSlots = nl->Fifth(args); // size of the result dmap2 = nl->Sixth(args); } std::string DmapPdmapTypeMapper::err() { return "expected: d[f]array(rel(tuple(X))) x string x " "([fs]rel(tuple(X)) -> stream(tuple(Y))) x " "(tuple(Y)->int) x int x" "(stream(tuple(Y)) -> Z)"; } int DmapPdmapTypeMapper::numberOfArgs() { return 6; } bool DmapPdmapTypeMapper::checkArgs() { if ( !checkArrayType() || !checkNameType() || !checkDmap1Type() || !checkPartitionType() || !checkNumberOfSlotsType() || !checkDmap2Type()) { return false; } return true; } bool DmapPdmapTypeMapper::checkDmap1Type() { ListExpr dmap1Type = nl->First(dmap1); if(!listutils::isMap<1>(dmap1Type) ){ msg = "third arg is not a function"; return false; } if(!Relation::checkType(getLastArgumentOf(dmap1Type))){ msg = "argument of the dmap1 function is not a relation"; return false; } if(!Stream::checkType(getResultType(dmap1Type))){ msg = "function result is not a tuple stream"; return false; } // if dmap1Type is defined to have two arguments, we ensure that the // second argument is unused // within the whole function definition if(listutils::isMap<2>(dmap1Type)){ std::string arg2Name = nl->SymbolValue( nl->First(nl->Third(nl->Second(dmap1)))); if(listutils::containsSymbol(nl->Fourth(nl->Second(dmap1)), arg2Name)){ msg = "Usage of the second argument in function is not allowed"; return false; } } return true; } bool DmapPdmapTypeMapper::checkInterdependencies() { ListExpr arrayType = nl->First(array); ListExpr partitionfunctionType = nl->First(partitionfunction); ListExpr dmap2Type = nl->First(dmap2); ListExpr dmap1Type = nl->First(dmap1); // (map ...) if (!arraySubtypeEqualsFunctionArgument(arrayType, dmap1Type)) { msg = "argument of function does not fit the array type."; return false; } if(!nl->Equal(nl->Second(getResultType(dmap1Type)), getLastArgumentOf(partitionfunctionType))){ msg = "type mismatch between result of the function " "and the argument of the distribution function"; return false; } if(!nl->Equal(getResultType(dmap1Type), nl->Second(dmap2Type))){ msg = "argument of third function does not " "fit the result type of the first function."; return false; } return true; } ListExpr DmapPdmapTypeMapper::append() { return nl->FiveElemList( nl->TextAtom(nl->ToString(appendDmap1())), // dmap1 nl->TextAtom(nl->ToString(appendPartition())), // partition nl->TextAtom(nl->ToString(appendDmap2())), // dmap2 nl->BoolAtom(isRel()), // dmap2 nl->BoolAtom(isStream())); } ListExpr DmapPdmapTypeMapper::appendDmap1() { ListExpr arrayType = nl->First(array); ListExpr relation = nl->Second(arrayType); ListExpr expFunArg = distributed2::DArray::checkType(arrayType) ?relation : nl->TwoElemList( listutils::basicSymbol(), nl->Second(relation)); return replaceTypeOperator(nl->Second(dmap1), expFunArg); } ListExpr DmapPdmapTypeMapper::appendPartition() { return replaceTypeOperator(nl->Second(partitionfunction), nl->Second(getResultType(nl->First(dmap1)))); } } // namespace