Skip to content

Commit

Permalink
Resolve rectangular domain module code in Dyno (chapel-lang#25684)
Browse files Browse the repository at this point in the history
Implement resolution of basic rectangular domain type expressions and
literals using `ChapelDomain` module code, replacing the stub compiler
implementation.

Includes:
- Get `new _domain` resolving
- Rewrite `new dmap` as `new _distribution`
- Resolve domain type expressions as receiver type of `new _domain`
- Emit useful error messages for invalid `domain` type expressions
- Resolve domain literals with
`chpl__buildDomainExpr`/`chpl__ensureDomainExpr`
- Get testing working against real `_domain` type from modules for
rectangular domains

Resolves Cray/chapel-private#6163.

Future domains work:
- use associative and sparse domains module code as well
- set up `dmapped` keyword to resolve a call to `chpl_distributed`

[reviewed by @DanilaFe , thanks!]

Testing:
- [x] dyno tests
- [x] paratest
  • Loading branch information
riftEmber authored Oct 7, 2024
2 parents 35661b3 + f8b3d77 commit 9d2a19d
Show file tree
Hide file tree
Showing 26 changed files with 677 additions and 409 deletions.
2 changes: 2 additions & 0 deletions frontend/include/chpl/framework/all-global-strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ X(c_ptr , "c_ptr")
X(c_ptrConst , "c_ptrConst")
X(c_char , "c_char")
X(class_ , "class")
X(defaultDist , "defaultDist")
X(deinit , "deinit")
X(deserialize , "deserialize")
X(dmapped , "dmapped")
Expand All @@ -66,6 +67,7 @@ X(index , "index")
X(init , "init")
X(initequals , "init=")
X(int_ , "int")
X(instance_ , "_instance")
X(isCoercible , "isCoercible")
X(leader , "leader")
X(locale , "locale")
Expand Down
28 changes: 21 additions & 7 deletions frontend/include/chpl/parsing/parsing-queries.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,15 +454,29 @@ std::string getExistingFileInModuleSearchPath(Context* context,
*/
const uast::Module* getToplevelModule(Context* context, UniqueString name);

struct IdAndName {
ID id;
UniqueString name;
};


/**
Given a particular (presumably standard) module, return the ID of a
symbol with the given name in that module. Beyond creating the ID, this also
ensures that the standard module is parsed, and thus, that 'idToAst' on the
returned ID will return a non-null value.
*/
ID getSymbolIdFromTopLevelModule(Context* context,
const char* modName,
const char* symName);

/**
Given a particular (presumably standard) module, return the ID of a symbol
with the given name in that module. Beyond creating the ID, this also ensures
that the standard module is parsed, and thus, that 'idToAst' on the returned
ID will return a non-null value.
Like getSymbolId..., but return also contains the name of the given symbol for
convenience.
*/
ID getSymbolFromTopLevelModule(Context* context,
const char* modName,
const char* symName);
IdAndName getSymbolFromTopLevelModule(Context* context,
const char* modName,
const char* symName);

/**
This query parses a submodule for 'include submodule'.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ ERROR_CLASS(IncompatibleKinds, types::QualifiedType::Kind, const uast::AstNode*,
ERROR_CLASS(IncompatibleRangeBounds, const uast::Range*, types::QualifiedType, types::QualifiedType)
ERROR_CLASS(IncompatibleTypeAndInit, const uast::AstNode*, const uast::AstNode*, const uast::AstNode*, const types::Type*, const types::Type*)
ERROR_CLASS(InvalidClassCast, const uast::PrimCall*, types::QualifiedType)
ERROR_CLASS(InvalidDomainCall, const uast::FnCall*, std::vector<types::QualifiedType>)
ERROR_CLASS(InvalidIndexCall, const uast::FnCall*, types::QualifiedType)
ERROR_CLASS(InvalidNewTarget, const uast::New*, types::QualifiedType)
ERROR_CLASS(InvalidParamCast, const uast::AstNode*, types::QualifiedType, types::QualifiedType)
Expand Down
1 change: 1 addition & 0 deletions frontend/include/chpl/resolution/resolution-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,7 @@ class AssociatedAction {
REDUCE_SCAN, // resolution of "generate" for a reduce/scan operation.
INFER_TYPE,
COMPARE, // == , e.g., for select-statements
RUNTIME_TYPE, // create runtime type
};

private:
Expand Down
3 changes: 3 additions & 0 deletions frontend/include/chpl/types/CompositeType.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ class CompositeType : public Type {
/** Get the chpl_localeID_t type */
static const RecordType* getLocaleIDType(Context* context);

/** Get the _distribution type */
static const RecordType* getDistributionType(Context* context);

/** Get the record _owned implementing owned */
static const RecordType* getOwnedRecordType(Context* context, const BasicClassType* bct);

Expand Down
10 changes: 7 additions & 3 deletions frontend/include/chpl/types/DomainType.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DomainType final : public CompositeType {
// TODO: distributions
Kind kind_;

// Will compute idxType, rank, and stridable from 'subs'
// Will compute idxType, rank, and strides from 'subs'
DomainType(ID id, UniqueString name,
const DomainType* instantiatedFrom,
SubstitutionsMap subs,
Expand Down Expand Up @@ -91,15 +91,19 @@ class DomainType final : public CompositeType {

/** Return a rectangular domain type */
static const DomainType* getRectangularType(Context* context,
const QualifiedType& instance,
const QualifiedType& rank,
const QualifiedType& idxType,
const QualifiedType& stridable);
const QualifiedType& strides);

/** Return an associative domain type */
static const DomainType* getAssociativeType(Context* context,
const QualifiedType& idxType,
const QualifiedType& parSafe);

/** Get the default distribution type */
static const QualifiedType& getDefaultDistType(Context* context);

Kind kind() const {
return kind_;
}
Expand All @@ -123,7 +127,7 @@ class DomainType final : public CompositeType {
}
}

const QualifiedType& stridable() const {
const QualifiedType& strides() const {
CHPL_ASSERT(kind_ == Kind::Rectangular);
return subs_.at(ID(UniqueString(), 2, 0));
}
Expand Down
13 changes: 10 additions & 3 deletions frontend/lib/parsing/parsing-queries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,9 @@ const Module* getToplevelModule(Context* context, UniqueString name) {
return getToplevelModuleQuery(context, name);
}

ID getSymbolFromTopLevelModule(Context* context,
const char* modName,
const char* symName) {
ID getSymbolIdFromTopLevelModule(Context* context,
const char* modName,
const char* symName) {
std::ignore = getToplevelModule(context, UniqueString::get(context, modName));

// Performance: this has to concatenate the two strings at runtime.
Expand All @@ -1127,6 +1127,13 @@ ID getSymbolFromTopLevelModule(Context* context,
return ID(UniqueString::get(context, fullPath));
}

IdAndName getSymbolFromTopLevelModule(Context* context,
const char* modName,
const char* symName) {
return {getSymbolIdFromTopLevelModule(context, modName, symName),
UniqueString::get(context, symName)};
}

static const Module* const&
getIncludedSubmoduleQuery(Context* context, ID includeModuleId) {
QUERY_BEGIN(getIncludedSubmoduleQuery, context, includeModuleId);
Expand Down
60 changes: 58 additions & 2 deletions frontend/lib/resolution/InitResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,57 @@ bool InitResolver::isFinalReceiverStateValid(void) {
return ret;
}

// Extract domain type information from _instance substitution
static const DomainType* domainTypeFromSubsHelper(
Context* context, const CompositeType::SubstitutionsMap& subs) {
auto genericDomain = DomainType::getGenericDomainType(context);

// Expect one substitution for _instance
if (subs.size() != 1) return genericDomain;

const QualifiedType instanceQt = subs.begin()->second;

if (auto instance = instanceQt.type()) {
if (auto instanceCt = instance->toClassType()) {
if (auto instanceBct = instanceCt->basicClassType()) {
// Get BaseRectangularDom parent subs for rectangular domain info
if (auto baseDom = instanceBct->parentClassType()) {
auto& rf = fieldsForTypeDecl(context, baseDom,
DefaultsPolicy::IGNORE_DEFAULTS);
if (baseDom->id().symbolPath() == "ChapelDistribution.BaseRectangularDom") {
CHPL_ASSERT(rf.numFields() == 3);
QualifiedType rank;
QualifiedType idxType;
QualifiedType strides;
for (int i = 0; i < rf.numFields(); i++) {
if (rf.fieldName(i) == "rank") {
rank = rf.fieldType(i);
} else if (rf.fieldName(i) == "idxType") {
idxType = rf.fieldType(i);
} else if (rf.fieldName(i) == "strides") {
strides = rf.fieldType(i);
}
}

return DomainType::getRectangularType(context, instanceQt, rank,
idxType, strides);
} else if (baseDom->id().symbolPath() == "ChapelDistribution.BaseAssociativeDom") {
// TODO: support associative domains
} else if (baseDom->id().symbolPath() == "ChapelDistribution.BaseSparseDom") {
// TODO: support sparse domains
} else {
// not a recognized domain type
return genericDomain;
}
}
}
}
}

// If we reach here, we weren't able to resolve the domain type
return genericDomain;
}

static const Type* ctFromSubs(Context* context,
const Type* receiverType,
const BasicClassType* superType,
Expand Down Expand Up @@ -313,6 +364,8 @@ static const Type* ctFromSubs(Context* context,
auto manager = AnyOwnedType::get(context);
auto dec = ClassTypeDecorator(ClassTypeDecorator::BORROWED_NONNIL);
ret = ClassType::get(context, basic, manager, dec);
} else if (receiverType->isDomainType()) {
ret = domainTypeFromSubsHelper(context, subs);
} else {
CHPL_ASSERT(false && "Not handled!");
}
Expand Down Expand Up @@ -400,9 +453,12 @@ const Type* InitResolver::computeReceiverTypeConsideringState(void) {
QualifiedType::Kind InitResolver::determineReceiverIntent(void) {
if (initialRecvType_->isClassType()) {
return QualifiedType::CONST_IN;
} else {
CHPL_ASSERT(initialRecvType_->isRecordType());
} else if (initialRecvType_->isRecordType() ||
initialRecvType_->isDomainType()) {
return QualifiedType::REF;
} else {
CHPL_ASSERT(false && "Not handled");
return QualifiedType::UNKNOWN;
}
}

Expand Down
Loading

0 comments on commit 9d2a19d

Please sign in to comment.