Skip to content

Commit b3bb1ac

Browse files
[wip] unify Apply and ApplySpecial nodes
1 parent 9432b61 commit b3bb1ac

24 files changed

Lines changed: 358 additions & 546 deletions

hail/hail/ir-gen/src/Main.scala

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ trait IRDSL {
7676
val BaseRef: Trait
7777
def TypedIR(t: String): Trait
7878
val NDArrayIR: Trait
79-
// AbstractApplyNodeUnseededMissingness{Aware, Oblivious}JVMFunction
80-
def ApplyNode(missingnessAware: Boolean = false): Trait
79+
val ApplyNode: Trait
8180

8281
// Implicits for common names
8382

@@ -121,12 +120,7 @@ object IRDSL_Impl extends IRDSL {
121120
override val BaseRef: Trait = Trait("BaseRef")
122121
override def TypedIR(typ: String): Trait = Trait(s"TypedIR[$typ]")
123122
override val NDArrayIR: Trait = Trait("NDArrayIR")
124-
125-
override def ApplyNode(missingnessAware: Boolean = false): Trait = {
126-
val t =
127-
s"AbstractApplyNode[UnseededMissingness${if (missingnessAware) "Aware" else "Oblivious"}JVMFunction]"
128-
Trait(t)
129-
}
123+
override val ApplyNode: Trait = Trait("AbstractApplyNode")
130124

131125
trait Repr[+T] {
132126
def typ: Type[T]
@@ -1109,7 +1103,7 @@ object Main {
11091103
in("args", child.*),
11101104
in("returnType", att("Type")),
11111105
errorID,
1112-
).withTraits(ApplyNode())
1106+
).withTraits(ApplyNode)
11131107

11141108
r += node(
11151109
"ApplySeeded",
@@ -1118,19 +1112,10 @@ object Main {
11181112
in("rngState", child),
11191113
in("staticUID", att("Long")),
11201114
in("returnType", att("Type")),
1121-
).withTraits(ApplyNode())
1115+
).withTraits(ApplyNode)
11221116
.withPreamble("val args = rngState +: _args")
11231117
.withPreamble("val typeArgs: Seq[Type] = Seq.empty[Type]")
11241118

1125-
r += node(
1126-
"ApplySpecial",
1127-
in("function", att("String")),
1128-
in("typeArgs", att("Seq[Type]")),
1129-
in("args", child.*),
1130-
in("returnType", att("Type")),
1131-
errorID,
1132-
).withTraits(ApplyNode(missingnessAware = true))
1133-
11341119
r += node("LiftMeOut", in("child", child))
11351120

11361121
r += node("TableCount", tableChild)
@@ -1222,8 +1207,8 @@ object Main {
12221207
"BlockMatrixMultiWriter, ValueReader, ValueWriter}",
12231208
"is.hail.expr.ir.lowering.TableStageDependency",
12241209
"is.hail.expr.ir.agg.{PhysicalAggSig, AggStateSig}",
1225-
"is.hail.expr.ir.functions.{UnseededMissingnessAwareJVMFunction, " +
1226-
"UnseededMissingnessObliviousJVMFunction, TableToValueFunction, MatrixToValueFunction, " +
1210+
"is.hail.expr.ir.functions.{MissingnessAwareJVMFunction, " +
1211+
"MissingnessObliviousJVMFunction, TableToValueFunction, MatrixToValueFunction, " +
12271212
"BlockMatrixToValueFunction}",
12281213
"is.hail.expr.ir.defs.exts._",
12291214
"scala.collection.compat._",

hail/hail/src/is/hail/expr/ir/BlockMatrixIR.scala

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,7 @@ class BlockMatrixNativeReader(
163163
val reader = ETypeValueReader(spec)
164164

165165
def blockIR(ctx: IR): IR = {
166-
val path = Apply(
167-
"concat",
168-
FastSeq(),
169-
FastSeq(Str(s"${params.path}/parts/"), ctx),
170-
TString,
171-
ErrorIDs.NO_ERROR,
172-
)
173-
166+
val path = invoke("concat", TString, Str(s"${params.path}/parts/"), ctx)
174167
ReadValue(path, reader, vType)
175168
}
176169

hail/hail/src/is/hail/expr/ir/Emit.scala

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import is.hail.expr.ir.analyses.{
99
}
1010
import is.hail.expr.ir.compile.Compile
1111
import is.hail.expr.ir.defs._
12+
import is.hail.expr.ir.functions.{MissingnessAwareJVMFunction, MissingnessObliviousJVMFunction}
1213
import is.hail.expr.ir.lowering.TableStageDependency
1314
import is.hail.expr.ir.ndarrays.EmitNDArray
1415
import is.hail.expr.ir.streams.{EmitStream, StreamProducer, StreamUtils}
@@ -2771,14 +2772,53 @@ class Emit[C](val ctx: EmitContext, val cb: EmitClassBuilder[C]) {
27712772
val rvAgg = agg.Extract.getAgg(sig)
27722773
rvAgg.result(cb, sc.states(idx), region)
27732774

2775+
case ir @ Apply(fn, typeArgs, args, rt, errorID) =>
2776+
ir.implementation match {
2777+
case impl: MissingnessObliviousJVMFunction =>
2778+
val unified = impl.unify(typeArgs, args.map(_.typ), rt)
2779+
assert(unified)
2780+
2781+
IEmitCode.multiMap(
2782+
cb,
2783+
args.map(arg => (cb: EmitCodeBuilder) => emitInNewBuilder(cb, arg)),
2784+
) { codeArgs =>
2785+
val argSTypes = codeArgs.map(_.st)
2786+
val retType = impl.computeStrictReturnEmitType(ir.typ, argSTypes)
2787+
val k = (fn, typeArgs, argSTypes, retType)
2788+
val meth =
2789+
methods.get(k) match {
2790+
case Some(funcMB) =>
2791+
funcMB
2792+
case None =>
2793+
val funcMB = impl.getAsMethod(mb.ecb, retType, typeArgs, argSTypes: _*)
2794+
methods.update(k, funcMB)
2795+
funcMB
2796+
}
2797+
cb.invokeSCode(
2798+
meth,
2799+
FastSeq[Param](cb.this_, CodeParam(region), CodeParam(errorID)) ++ codeArgs.map(
2800+
pc =>
2801+
pc: Param
2802+
): _*
2803+
)
2804+
}
2805+
2806+
case impl: MissingnessAwareJVMFunction =>
2807+
val codeArgs = args.map(a => EmitCode.fromI(cb.emb)(emitInNewBuilder(_, a)))
2808+
val unified = impl.unify(typeArgs, args.map(_.typ), rt)
2809+
assert(unified)
2810+
val retType = impl.computeReturnEmitType(ir.typ, codeArgs.map(_.emitType))
2811+
impl.apply(cb, region, retType.st, typeArgs, errorID, codeArgs: _*)
2812+
}
2813+
27742814
case x @ ApplySeeded(_, args, rngState, staticUID, rt) =>
27752815
val codeArgs = args.map(a => EmitCode.fromI(cb.emb)(emitInNewBuilder(_, a)))
27762816
val codeArgsMem = codeArgs.map(_.memoize(cb, "ApplySeeded_arg"))
27772817
val state = emitI(rngState).getOrAssert(cb)
27782818
val impl = x.implementation
27792819
assert(impl.unify(Array.empty[Type], x.argTypes, rt))
27802820
val newState = EmitCode.present(mb, state.asRNGState.splitStatic(cb, staticUID))
2781-
impl.applyI(
2821+
impl.asInstanceOf[MissingnessObliviousJVMFunction].applyI(
27822822
region,
27832823
cb,
27842824
impl.computeReturnEmitType(x.typ, newState.emitType +: codeArgs.map(_.emitType)).st,
@@ -3497,45 +3537,6 @@ class Emit[C](val ctx: EmitContext, val cb: EmitClassBuilder[C]) {
34973537
)
34983538
ev.load
34993539

3500-
case ir @ Apply(fn, typeArgs, args, rt, errorID) =>
3501-
val impl = ir.implementation
3502-
val unified = impl.unify(typeArgs, args.map(_.typ), rt)
3503-
assert(unified)
3504-
3505-
val emitArgs = args.map(a => EmitCode.fromI(mb)(emitI(a, _))).toFastSeq
3506-
3507-
val argSTypes = emitArgs.map(_.st)
3508-
val retType = impl.computeStrictReturnEmitType(ir.typ, argSTypes)
3509-
val k = (fn, typeArgs, argSTypes, retType)
3510-
val meth =
3511-
methods.get(k) match {
3512-
case Some(funcMB) =>
3513-
funcMB
3514-
case None =>
3515-
val funcMB = impl.getAsMethod(mb.ecb, retType, typeArgs, argSTypes: _*)
3516-
methods.update(k, funcMB)
3517-
funcMB
3518-
}
3519-
EmitCode.fromI(mb) { cb =>
3520-
val emitArgs = args.map(a => EmitCode.fromI(cb.emb)(emitI(a, _))).toFastSeq
3521-
IEmitCode.multiMapEmitCodes(cb, emitArgs) { codeArgs =>
3522-
cb.invokeSCode(
3523-
meth,
3524-
FastSeq[Param](cb.this_, CodeParam(region), CodeParam(errorID)) ++ codeArgs.map(pc =>
3525-
pc: Param
3526-
): _*
3527-
)
3528-
}
3529-
}
3530-
3531-
case x @ ApplySpecial(_, typeArgs, args, rt, errorID) =>
3532-
val codeArgs = args.map(a => emit(a))
3533-
val impl = x.implementation
3534-
val unified = impl.unify(typeArgs, args.map(_.typ), rt)
3535-
assert(unified)
3536-
val retType = impl.computeReturnEmitType(x.typ, codeArgs.map(_.emitType))
3537-
impl.apply(mb, region, retType.st, typeArgs, errorID, codeArgs: _*)
3538-
35393540
case WritePartition(stream, pctx, writer) =>
35403541
val ctxCode = emit(pctx)
35413542
val streamCode = emitStream(stream, region)

hail/hail/src/is/hail/expr/ir/ExtractIntervalFilters.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -809,12 +809,12 @@ class ExtractIntervalFilters(ctx: ExecuteContext, keyType: TStruct) extends Logg
809809
},
810810
x.typ,
811811
)
812-
case ApplySpecial("lor", _, _, _, _) => children match {
812+
case Apply("lor", _, _, _, _) => children match {
813813
case Seq(ConstantValue(l: Boolean), ConstantValue(r: Boolean)) =>
814814
ConstantValue(l || r, TBoolean)
815815
case _ => AbstractLattice.top
816816
}
817-
case ApplySpecial("land", _, _, _, _) => children match {
817+
case Apply("land", _, _, _, _) => children match {
818818
case Seq(ConstantValue(l: Boolean), ConstantValue(r: Boolean)) =>
819819
ConstantValue(l && r, TBoolean)
820820
case _ => AbstractLattice.top
@@ -842,7 +842,7 @@ class ExtractIntervalFilters(ctx: ExecuteContext, keyType: TStruct) extends Logg
842842
.restrict(keySet)
843843
case (IsNA(_), Seq(b: BoolValue)) => b.isNA.restrict(keySet)
844844
// collection contains
845-
case (ApplySpecial("contains", _, _, _, _), Seq(ConstantValue(intervalVal), queryVal)) =>
845+
case (Apply("contains", _, _, _, _), Seq(ConstantValue(intervalVal), queryVal)) =>
846846
(intervalVal: @unchecked) match {
847847
case null => BoolValue.allNA(keySet)
848848
case i: Interval => queryVal match {
@@ -891,9 +891,9 @@ class ExtractIntervalFilters(ctx: ExecuteContext, keyType: TStruct) extends Logg
891891
}
892892
case (ApplyComparisonOp(op, _, _), Seq(l, r)) =>
893893
AbstractLattice.compare(l, r, op, keySet)
894-
case (ApplySpecial("lor", _, _, _, _), Seq(l: BoolValue, r: BoolValue)) =>
894+
case (Apply("lor", _, _, _, _), Seq(l: BoolValue, r: BoolValue)) =>
895895
BoolValue.or(l, r)
896-
case (ApplySpecial("land", _, _, _, _), Seq(l: BoolValue, r: BoolValue)) =>
896+
case (Apply("land", _, _, _, _), Seq(l: BoolValue, r: BoolValue)) =>
897897
BoolValue.and(l, r)
898898
case (ApplyUnaryPrimOp(Bang, _), Seq(x: BoolValue)) =>
899899
BoolValue.not(x)

hail/hail/src/is/hail/expr/ir/IR.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ package defs {
220220
}
221221
}
222222

223-
trait AbstractApplyNode[F <: JVMFunction] extends IR {
223+
trait AbstractApplyNode extends IR {
224224
def function: String
225225

226226
def args: Seq[IR]
@@ -231,9 +231,10 @@ package defs {
231231

232232
def argTypes: Seq[Type] = args.map(_.typ)
233233

234-
lazy val implementation: F =
234+
lazy val implementation: JVMFunction =
235235
IRFunctionRegistry.lookupFunctionOrFail(function, returnType, typeArgs, argTypes)
236-
.asInstanceOf[F]
236+
237+
def strictArgs: Boolean = implementation.isInstanceOf[MissingnessObliviousJVMFunction]
237238
}
238239

239240
object PartitionReader {
@@ -779,15 +780,15 @@ package defs {
779780

780781
def all(element: IR): IR =
781782
aggFoldIR(True()) { accum =>
782-
ApplySpecial(
783+
Apply(
783784
"land",
784785
Seq.empty[Type],
785786
FastSeq(accum, element),
786787
TBoolean,
787788
ErrorIDs.NO_ERROR,
788789
)
789790
} { (accum1, accum2) =>
790-
ApplySpecial(
791+
Apply(
791792
"land",
792793
Seq.empty[Type],
793794
FastSeq(accum1, accum2),

hail/hail/src/is/hail/expr/ir/InferType.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ object InferType {
7979
case _ => TBoolean
8080
}
8181
case a: ApplyIR => a.returnType
82-
case a: AbstractApplyNode[_] =>
82+
case a: AbstractApplyNode =>
8383
val typeArgs = a.typeArgs
8484
val argTypes = a.args.map(_.typ)
8585
assert(a.implementation.unify(typeArgs, argTypes, a.returnType))

hail/hail/src/is/hail/expr/ir/Interpret.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ object Interpret extends Logging {
838838
interpret(result)
839839
case ir @ ApplyIR(_, _, _, _, _) =>
840840
interpret(ir.explicitNode, env, args)
841-
case ApplySpecial("lor", _, Seq(left_, right_), _, _) =>
841+
case Apply("lor", _, Seq(left_, right_), _, _) =>
842842
val left = interpret(left_)
843843
if (left == true)
844844
true
@@ -850,7 +850,7 @@ object Interpret extends Logging {
850850
null
851851
else false
852852
}
853-
case ApplySpecial("land", _, Seq(left_, right_), _, _) =>
853+
case Apply("land", _, Seq(left_, right_), _, _) =>
854854
val left = interpret(left_)
855855
if (left == false)
856856
false
@@ -862,7 +862,7 @@ object Interpret extends Logging {
862862
null
863863
else true
864864
}
865-
case ir: AbstractApplyNode[_] =>
865+
case ir: AbstractApplyNode =>
866866
val argTuple =
867867
PType.canonical(TTuple(ir.args.map(_.typ): _*)).setRequired(true).asInstanceOf[PTuple]
868868
ctx.r.pool.scopedRegion { region =>

hail/hail/src/is/hail/expr/ir/Parser.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,8 +1384,6 @@ object IRParser {
13841384
} yield ApplySeeded(function, args, rngState, staticUID, rt)
13851385
case "ApplyIR" =>
13861386
apply_like(ctx, ApplyIR.apply)(it)
1387-
case "ApplySpecial" =>
1388-
apply_like(ctx, ApplySpecial)(it)
13891387
case "Apply" =>
13901388
apply_like(ctx, Apply)(it)
13911389
case "MatrixCount" =>

hail/hail/src/is/hail/expr/ir/Pretty.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,6 @@ class Pretty(
429429
FastSeq(s"$errorID", prettyIdentifier(function), prettyTypes(typeArgs), t.parsableString())
430430
case ApplySeeded(function, _, _, staticUID, t) =>
431431
FastSeq(prettyIdentifier(function), staticUID.toString, t.parsableString())
432-
case ApplySpecial(function, typeArgs, _, t, errorID) =>
433-
FastSeq(s"$errorID", prettyIdentifier(function), prettyTypes(typeArgs), t.parsableString())
434432
case SelectFields(_, fields) =>
435433
single(fillList(fields.view.map(f => text(prettyIdentifier(f)))))
436434
case LowerBoundOnOrderedCollection(_, _, onKey) => single(Pretty.prettyBooleanLiteral(onKey))

hail/hail/src/is/hail/expr/ir/Requiredness.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ class Requiredness(val usesAndDefs: UsesAndDefs, ctx: ExecuteContext) {
822822
requiredness.union(oldReq.required)
823823
requiredness.unionFrom(oldReq.field(idx))
824824
case x: ApplyIR => requiredness.unionFrom(lookup(x.body))
825-
case x: AbstractApplyNode[_] => // FIXME: round-tripping via PTypes.
825+
case x: AbstractApplyNode => // FIXME: round-tripping via PTypes.
826826
val argP = x.args.map { a =>
827827
val pt = lookup(a).canonicalPType(a.typ)
828828
EmitType(pt.sType, pt.required)

0 commit comments

Comments
 (0)