Files
secondo/Algebras/Distributed3/DmapPdmapTypeMapper.cpp
2026-01-23 17:03:45 +08:00

123 lines
4.0 KiB
C++

/*
*/
#include "Algebras/Distributed2/DArray.h"
#include "Algebras/Distributed2/fsrel.h"
#include <ListUtils.h>
#include <StandardTypes.h>
#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<Tuple>::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<distributed2::fsrel>(),
nl->Second(relation));
return replaceTypeOperator(nl->Second(dmap1), expFunArg);
}
ListExpr DmapPdmapTypeMapper::appendPartition() {
return replaceTypeOperator(nl->Second(partitionfunction),
nl->Second(getResultType(nl->First(dmap1))));
}
} // namespace