Conversation
src/main/scala/lms/core/types.scala
Outdated
| val Unit: TypeExp = Const(TypeNames.Unit) | ||
| val Boolean: TypeExp = Const(TypeNames.Boolean) | ||
| val Char: TypeExp = Const(TypeNames.Char) | ||
| val Short: TypeExp = Const(TypeNames.Short) | ||
| val Int: TypeExp = Const(TypeNames.Int) | ||
| val Float: TypeExp = Const(TypeNames.Float) | ||
| val Double: TypeExp = Const(TypeNames.Double) |
There was a problem hiding this comment.
would these names conflict with the types of Scala?
There was a problem hiding this comment.
Having the same name helps in identifying what corresponds to what but I am open to changes. See cd0a859 on a possible way to ensure that they don't conflict but I am open to different names
src/main/scala/lms/core/types.scala
Outdated
| } | ||
|
|
||
| object ArrayType { | ||
| val name = "Array" |
There was a problem hiding this comment.
this is building type with type parameters. I am slightly concerned if the name of the node op should follow some specific rules, such that we don't accidentally use the same node op name for terms and types.
For instance, maybe for types, the name is always T-Array with a T-?
This is probably a bad suggestion. Hopefully you guys have better ideas. :)
There was a problem hiding this comment.
Indeed I was also thinking to prefix such names. T- sounds reasonable
|
Thanks for having a go at this! This looks like a good start. Couple questions/remarks:
Happy to meet and discuss, or for you to do another iteration first, whichever you prefer. |
| } | ||
|
|
||
| } | ||
|
|
There was a problem hiding this comment.
Interesting model -- I was thinking more along the lines of putting the HashMap into the GraphBuilder class. What are pros and cons?
There was a problem hiding this comment.
The current typeMap is part of the global state in Adapter. The new version of TypeMap probably won't have a GraphBuilder and will use the one that is used for reflecting terms Adapter.g.
There was a problem hiding this comment.
A GraphBuilder object is not long-living. After a Graph is constructed, the GraphBuilder object is used to generate a Graph object, and then discarded. If we have a HashMap in the GraphBuilder, we might also need to save it to the Graph object. It might not be a bad idea.
So far we have been using Metadata to track additional information for Graph. When doing transformation, the handling of Metadata gets hacky (using Adapter.oldTypeMap, for instance). If this Metadata is part of the Graph, then that looks cleaner imo.
src/main/scala/lms/core/types.scala
Outdated
| object Reflect { | ||
| def unapply(x: Any)(implicit tm: TypeMap): Option[(String, List[Exp])] = x match { | ||
| case s@Sym(_) => | ||
| tm.g.findDefinition(s).map(n => (n.op, n.rhs.filter(_.isInstanceOf[Exp]).map(_.asInstanceOf[Exp]))) | ||
| case _ => None | ||
| } | ||
| } |
There was a problem hiding this comment.
Why is this extractor needed? Can't we use Def from GraphBuilder?
Currently working on this |
| } | ||
|
|
||
| object TypeNames extends Enumeration { | ||
| val InferredT, UnitT, BooleanT, CharT, ShortT, IntT, FloatT, DoubleT = Value |
This PR introduces a
Typetypeclass based representation of types in LMS.This implementation is based on the one present on the previous version of LMS and the one presented in
"Reflections on LMS: exploring front-end alternatives".
Rationale
LMS relies on
Manifests inAdapter.typeMapfor keeping track of types of nodes in the graph. Although manifests are in general only used in the backend for code generation, there are cases where we would like to provide additional information in the types of the nodes.This has so far been overcome in ad-hoc ways adding this information at the
Nodelevel outside of thetypeMap(example1, example2). Although convenient, this is not uniform and requires additional code to keep the information in sync between thetypeMapand the nodes.Design
typeMapis updated from aMap[Exp, Manifest[_]]toMap[Exp, TypeExp].WrapTypeinstance must be providedTypetype class provides tworeifymethods: one for simple types and one for typesthat might need to inspect the
Expression before reflecting a type (in the case of the tensors example2 above,this allows to promote the shape to the type level). I am not sure about the latter design decision and if there are
alternatives.
Open questions
Tasks
manifest[]etc.)Adapter.typeMapandAdapter.oldTypeMap:HashMap[Exp, Manifest[_]]->HashMap[Exp, TypeExp]Wrap[T:Manifest]->Wrap[T:Type]ManifesttoTypeUtilOpswhich would have allowed using refactoring tools.