From 07d7cabbdb9b3235e128628fb8b0160832f6d90d Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 23 Jul 2021 23:32:30 +0200 Subject: [PATCH 01/86] Added convolution imperative primitives for GAP8 --- .../GAP8/primitives/imperative/Conv3x3.scala | 20 +++++++++++ .../GAP8/primitives/imperative/Conv5x5.scala | 20 +++++++++++ .../GAP8/primitives/imperative/Conv7x4.scala | 20 +++++++++++ .../GAP8/primitives/imperative/Conv7x7.scala | 20 +++++++++++ .../primitives/imperative/primitives.dpia | 35 ++++++++++++++++++- 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala new file mode 100644 index 000000000..ef45f610d --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types.DataType._ +import shine.DPIA.Types._ +import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Conv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { + assert { + in :: expT(ArrayType(w, ArrayType(h, dt)), read) + filter :: expT(ArrayType(10, dt), read) + out :: accT(ArrayType(w - 2, ArrayType(h - 2, dt))) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv3x3 = new Conv3x3(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala new file mode 100644 index 000000000..0c65f6b63 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types.DataType._ +import shine.DPIA.Types._ +import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Conv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { + assert { + in :: expT(ArrayType(w, ArrayType(h, dt)), read) + filter :: expT(ArrayType(26, dt), read) + out :: accT(ArrayType(w - 4, ArrayType(h - 4, dt))) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv5x5 = new Conv5x5(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala new file mode 100644 index 000000000..789df548a --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types.DataType._ +import shine.DPIA.Types._ +import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { + assert { + in :: expT(ArrayType(w, ArrayType(h, dt)), read) + filter :: expT(ArrayType(28, dt), read) + out :: accT(ArrayType(w - 6, ArrayType(h - 3, dt))) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv7x4 = new Conv7x4(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala new file mode 100644 index 000000000..d73384581 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types.DataType._ +import shine.DPIA.Types._ +import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Conv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { + assert { + in :: expT(ArrayType(w, ArrayType(h, dt)), read) + filter :: expT(ArrayType(56, dt), read) + out :: accT(ArrayType(w - 6, ArrayType(h - 6, dt))) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv7x7 = new Conv7x7(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index 24aa5ec19..ffc15bbd5 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -1 +1,34 @@ -def kernelCallCmd{name: String, cores: Int, n: Int}(inTs: n*data, dt: data, args: n*exp[*inTs, read], output: acc[dt]): comm +def kernelCallCmd{name: String, cores: Int, n: Int} + (inTs: n*data, dt: data, args: n*exp[*inTs, read], output: acc[dt]): comm + +def conv3x3(w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[w.h.dt, read], + filter: exp[10.dt, read], + out: acc[(w-2).(h-2).dt]): comm + +def conv5x5(w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[w.h.dt, read], + filter: exp[26.dt, read], + out: acc[(w-4).(h-4).dt]): comm + +def conv7x7(w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[w.h.dt, read], + filter: exp[56.dt, read], + out: acc[(w-6).(h-6).dt]): comm + +def conv7x4(w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[w.h.dt, read], + filter: exp[28.dt, read], + out: acc[(w-6).(h-3).dt]): comm From 03ba5fd126f5cb2c4ba90968d99903a252d6e843 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 26 Jul 2021 13:29:13 +0200 Subject: [PATCH 02/86] Swapped dimensions of the input and output arrays --- .../GAP8/primitives/imperative/Conv3x3.scala | 4 ++-- .../GAP8/primitives/imperative/Conv5x5.scala | 4 ++-- .../GAP8/primitives/imperative/Conv7x4.scala | 4 ++-- .../GAP8/primitives/imperative/Conv7x7.scala | 4 ++-- .../GAP8/primitives/imperative/primitives.dpia | 16 ++++++++-------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala index ef45f610d..ac02d61eb 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala @@ -10,9 +10,9 @@ import shine.DPIA.Types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(10, dt), read) - out :: accT(ArrayType(w - 2, ArrayType(h - 2, dt))) + out :: accT(ArrayType(h - 2, ArrayType(w - 2, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala index 0c65f6b63..ccfcce250 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala @@ -10,9 +10,9 @@ import shine.DPIA.Types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(26, dt), read) - out :: accT(ArrayType(w - 4, ArrayType(h - 4, dt))) + out :: accT(ArrayType(h - 4, ArrayType(w - 4, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala index 789df548a..1bf7762b7 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala @@ -10,9 +10,9 @@ import shine.DPIA.Types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(28, dt), read) - out :: accT(ArrayType(w - 6, ArrayType(h - 3, dt))) + out :: accT(ArrayType(h - 6, ArrayType(w - 3, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala index d73384581..9bc7e0d73 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala @@ -10,9 +10,9 @@ import shine.DPIA.Types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(56, dt), read) - out :: accT(ArrayType(w - 6, ArrayType(h - 6, dt))) + out :: accT(ArrayType(h - 6, ArrayType(w - 6, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index ffc15bbd5..c7d644fdc 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -5,30 +5,30 @@ def conv3x3(w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[10.dt, read], - out: acc[(w-2).(h-2).dt]): comm + out: acc[(h-2).(w-2).dt]): comm def conv5x5(w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[26.dt, read], - out: acc[(w-4).(h-4).dt]): comm + out: acc[(h-4).(w-4).dt]): comm def conv7x7(w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[56.dt, read], - out: acc[(w-6).(h-6).dt]): comm + out: acc[(h-6).(w-6).dt]): comm def conv7x4(w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[28.dt, read], - out: acc[(w-6).(h-3).dt]): comm + out: acc[(h-6).(w-3).dt]): comm From b4f75c278b2f0684c3b612384bea4b93903c1df3 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 29 Jul 2021 11:56:54 +0200 Subject: [PATCH 03/86] Added RISE HWCE primitives --- src/main/scala/rise/GAP8/DSL.scala | 1 + .../rise/GAP8/primitives/gap8hwConv.scala | 24 +++++++++++++++++++ .../rise/GAP8/primitives/gap8hwConvv3.scala | 24 +++++++++++++++++++ .../rise/GAP8/primitives/primitives.rise | 13 ++++++++++ 4 files changed, 62 insertions(+) create mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConv.scala create mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala diff --git a/src/main/scala/rise/GAP8/DSL.scala b/src/main/scala/rise/GAP8/DSL.scala index 0c99f6f1f..f72326d16 100644 --- a/src/main/scala/rise/GAP8/DSL.scala +++ b/src/main/scala/rise/GAP8/DSL.scala @@ -6,4 +6,5 @@ import shine.DPIA.Nat object DSL { def gap8Run(cores: Nat): ToBeTyped[Expr] = primitives.gap8RunPrimitive(cores) + def hwce(): ToBeTyped[Expr] = ??? } diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv.scala new file mode 100644 index 000000000..a09b57d77 --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv.scala @@ -0,0 +1,24 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import arithexpr.arithmetic._ +object gap8hwConv extends Builder { + private final case class Primitive()(override val t: Type = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "gap8hwConv" + override def setType(ty: Type): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: Type = impl { (w: Nat) => impl { (h: Nat) => impl { (bias: Nat) => impl { (s: DataType) => ArrayType(h, ArrayType(w, s)) ->: ArrayType(10, s) ->: ArrayType(h - 2, ArrayType(w - 2, s)) } } } } + } + override def toString: String = "gap8hwConv" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala new file mode 100644 index 000000000..3a6234e41 --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala @@ -0,0 +1,24 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import arithexpr.arithmetic._ +object gap8hwConvv3 extends Builder { + private final case class Primitive()(override val t: Type = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "gap8hwConvv3" + override def setType(ty: Type): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: Type = impl { (iw: Nat) => impl { (ih: Nat) => impl { (fw: Nat) => impl { (fh: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (bias: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(fh, ArrayType(fw, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } } + } + override def toString: String = "gap8hwConvv3" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index cc3f8ad30..0190283c9 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -1 +1,14 @@ def gap8RunPrimitive: (cores: nat) -> {t: data} -> t -> t + +def gap8hwConv: {w: nat} -> {h: nat} -> + {bias: nat} -> {s: data} -> + h.w.s -> 10.s -> (h-2).(w-2).s + +//ConvType here as well, encapsulating sizes for each filter type +//def gap8hwConv_v2: (type: ) + +def gap8hwConvv3: {iw: nat} -> {ih: nat} -> + {fw: nat} -> {fh: nat} -> + {ow: nat} -> {oh: nat} -> + {bias: nat} -> {s: data} -> + ih.iw.s -> fh.fw.s -> oh.ow.s From e86e2a4605815fc1303efaf7e2b6528efddbd2fc Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 29 Jul 2021 11:57:21 +0200 Subject: [PATCH 04/86] Added functional primitives for HWCE --- .../GAP8/primitives/functional/Conv.scala | 20 +++++++++++++++++++ .../primitives/functional/primitives.dpia | 9 +++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/main/scala/shine/GAP8/primitives/functional/Conv.scala diff --git a/src/main/scala/shine/GAP8/primitives/functional/Conv.scala b/src/main/scala/shine/GAP8/primitives/functional/Conv.scala new file mode 100644 index 000000000..d3bf462c9 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/Conv.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types.DataType._ +import shine.DPIA.Types._ +import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Conv(fs: shine.GAP8.ConvolutionFilterSize)(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { + assert { + in :: expT(ArrayType(h, ArrayType(w, dt)), read) + filter :: expT(ArrayType(10, dt), read) + true + } + override val t: ExpType = expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv = new Conv(fs)(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) + def unwrap: (Nat, Nat, Nat, DataType, Phrase[ExpType], Phrase[ExpType]) = (w, h, bias, dt, in, filter) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index 02d24e1c5..9ac106308 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -1,3 +1,12 @@ def kernelCall{name: String, cores: Int, n:Int}(inTs: n*data, outT: data, args: n*exp[*inTs, read]): exp[outT, write] def run{cores: Nat}(dt: data, input: exp[dt, write]): exp[dt, write] + +def conv{fs: shine.GAP8.ConvolutionFilterSize}( + w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[h.w.dt, read], + filter: exp[10.dt, read] +): exp[(h-2).(w-2).dt, write] From cd7dcb7995b38f2024b0b5ec7967c59ed13a2f0a Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 29 Jul 2021 11:58:24 +0200 Subject: [PATCH 05/86] Parts of translation implementation for GAP8 HWCE --- .../Compilation/AcceptorTranslation.scala | 37 +++-- .../AcceleratorCodeGenerator.scala | 128 ++++++++++++++++++ .../shine/GAP8/ConvolutionFilterSize.scala | 22 +++ 3 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala create mode 100644 src/main/scala/shine/GAP8/ConvolutionFilterSize.scala diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index da955c829..129a74bd4 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -9,14 +9,10 @@ import shine.DPIA._ import shine.DPIA.primitives.functional._ import shine.DPIA.primitives.imperative.{Seq => _, _} import shine.DPIA.primitives.intermediate._ -import shine.OpenMP.primitives.{functional => omp} -import shine.OpenMP.primitives.{intermediate => ompI} -import shine.OpenCL.primitives.{functional => ocl} -import shine.OpenCL.primitives.{intermediate => oclI} -import shine.OpenCL.primitives.{imperative => oclImp} -import shine.cuda.primitives.{functional => cuda} -import shine.cuda.primitives.{intermediate => cudaI} -import shine.cuda.primitives.{imperative => cudaImp} +import shine.GAP8.primitives.imperative.{Conv3x3, Conv7x4} +import shine.OpenCL.primitives.{functional => ocl, imperative => oclImp, intermediate => oclI} +import shine.OpenMP.primitives.{functional => omp, intermediate => ompI} +import shine.cuda.primitives.{functional => cuda, imperative => cudaImp, intermediate => cudaI} object AcceptorTranslation { def acc(E: Phrase[ExpType]) @@ -354,6 +350,31 @@ object AcceptorTranslation { cudaImp.WmmaMMA(m, n, k, layoutA, layoutB, dataType, dataTypeAcc, aMatrix, bMatrix, cMatrix, A))))))) //GAP8 + //case shine.GAP8.primitives.functional.Conv(w, h, bias, dt, in, filter) => + case c@shine.GAP8.primitives.functional.Conv(fs) => + con(c.in)(λ(ExpType(c.h`.`(c.w`.`c.dt), read))(inInner => { + fs match { + case shine.GAP8._3x3 => + con(c.filter)(λ(ExpType(ArrayType(10, c.dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv3x3(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) + )) + case shine.GAP8._5x5 => + con(c.filter)(λ(ExpType(ArrayType(26, c.dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv5x5(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) + )) + case shine.GAP8._7x7 => + con(c.filter)(λ(ExpType(ArrayType(56, c.dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv7x7(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) + )) + case shine.GAP8._7x4 => + con(c.filter)(λ(ExpType(ArrayType(28, c.dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv7x4(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) + )) + case _=> + throw new Exception("Unsupported filter size") + } + })) + case r@shine.GAP8.primitives.functional.Run(cores) => { ??? } diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala new file mode 100644 index 000000000..90dfc3233 --- /dev/null +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -0,0 +1,128 @@ +package shine.GAP8.Compilation + +import arithexpr.arithmetic +import arithexpr.arithmetic.ArithExpr +import shine.DPIA.Compilation.TranslationContext +import shine.DPIA.Nat +import shine.DPIA.Phrases.Phrase +import shine.DPIA.Types.CommType +import shine.GAP8.ConvolutionFilterSize +import shine.GAP8.primitives.imperative.{Conv3x3, Conv5x5, Conv7x4, Conv7x7} +import shine.{C, OpenMP} + +import scala.collection.{immutable, mutable} + +// scalastyle:off +class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.Declarations, + override val ranges: C.Compilation.CodeGenerator.Ranges) + extends OpenMP.CodeGenerator(decls, ranges) { + override def name: String = "GAP8 ACC" + + override def translationContext: TranslationContext = super.translationContext + + override def cmd(env: Environment): Phrase[CommType] => Stmt = { + //TODO: Supoort multicycle output for 3x3 + case Conv3x3(w, h, bias, dt, in, filter, out) => + out |> acc(env, Nil, (outputC: C.AST.Expr) => { + in |> exp(env, Nil, (inC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + generateCalls(shine.GAP8._3x3, w, h, bias, inC, filterC, outputC) + }) + }) + }) + case Conv5x5(w, h, bias, dt, in, filter, out) => + out |> acc(env, Nil, (outputC: C.AST.Expr) => { + in |> exp(env, Nil, (inC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + generateCalls(shine.GAP8._5x5, w, h, bias, inC, filterC, outputC) + }) + }) + }) + case Conv7x7(w, h, bias, dt, in, filter, out) => + out |> acc(env, Nil, (outputC: C.AST.Expr) => { + in |> exp(env, Nil, (inC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + generateCalls(shine.GAP8._7x7, w, h, bias, inC, filterC, outputC) + }) + }) + }) + case Conv7x4(w, h, bias, dt, in, filter, out) => + out |> acc(env, Nil, (outputC: C.AST.Expr) => { + in |> exp(env, Nil, (inC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + generateCalls(shine.GAP8._7x4, w, h, bias, inC, filterC, outputC) + }) + }) + }) + case phrase => phrase |> super.cmd(env) + } + + private def generateCalls(fs: ConvolutionFilterSize, w: Nat, h: Nat, bias: Nat, + in: Expr, filter: Expr, output: Expr): Stmt = { + C.AST.Block(Seq( + hwceEnableCall, + hwceGenericInitCall(fs), + hwceSetYinModeCall(), + generateHwceCallFunction(fs, w, h, bias, in, filter, output), + hwceDisableCall + )) + } + + private def generateHwceCallFunction(fs: ConvolutionFilterSize, w: Nat, h: Nat, bias: Nat, + in: Expr, filter: Expr, output: Expr): Stmt = { + fs match { + case shine.GAP8._3x3 => + C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef(fs.functionName), + Seq(in, + output, + C.AST.Literal("NULL"), + C.AST.Literal("NULL"), + filter, + C.AST.Literal(ArithExpr.toInt(bias).toString), + C.AST.Literal(ArithExpr.toInt(w).toString), + C.AST.Literal(ArithExpr.toInt(h).toString), + C.AST.Literal("0x7") + ) + )) + case _ => + C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef(fs.functionName), + Seq(in, + output, + filter, + C.AST.Literal(ArithExpr.toInt(bias).toString), + C.AST.Literal(ArithExpr.toInt(w).toString), + C.AST.Literal(ArithExpr.toInt(h).toString), + ) + )) + } + } + + private val hwceEnableCall = C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("HWCE_Enable"), Seq())) + private val hwceDisableCall = C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("HWCE_Disable"), Seq())) + private val hwceSoftResetCall = C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("HwCE_SoftReset"), Seq())) + private def hwceSetInputBiasCall(bias: Int = 0) = C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef("HwCE_SetInputBias"), Seq(C.AST.Literal(bias.toString)) + )) + private def hwceSetYinModeCall(mode: Int = 1) = C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef("HwCE_SetYinMode"), + Seq(C.AST.Cast(C.AST.Type.u32, C.AST.Literal(mode.toString))) + )) + private def hwceGenericInitCall(fs: ConvolutionFilterSize, wstride: Int = 0, qnorm: Int = 0) = + C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef("HWCE_GenericInit"), + Seq( + C.AST.Cast(C.AST.Type.u32, C.AST.Literal(fs.toBackendConst)), + C.AST.Cast(C.AST.Type.u32, C.AST.Literal(wstride.toString)), + C.AST.Cast(C.AST.Type.u32, C.AST.Literal(qnorm.toString)) + ) + )) +} + +object AcceleratorCodeGenerator { + def apply() = new AcceleratorCodeGenerator( + mutable.ListBuffer[C.AST.Decl](), + immutable.Map[String, arithmetic.Range]() + ) +} diff --git a/src/main/scala/shine/GAP8/ConvolutionFilterSize.scala b/src/main/scala/shine/GAP8/ConvolutionFilterSize.scala new file mode 100644 index 000000000..3c52b285b --- /dev/null +++ b/src/main/scala/shine/GAP8/ConvolutionFilterSize.scala @@ -0,0 +1,22 @@ +package shine.GAP8 + +sealed trait ConvolutionFilterSize { + def toBackendConst: String + def functionName: String +} +case object _3x3 extends ConvolutionFilterSize { + override def toBackendConst: String = "HWCE_CONV3x3" + override def functionName: String = "HWCE_ProcessOneTile3x3_MultiOut" +} +case object _5x5 extends ConvolutionFilterSize { + override def toBackendConst: String = "HWCE_CONV5x5" + override def functionName: String = "HWCE_ProcessOneTile5x5" +} +case object _7x7 extends ConvolutionFilterSize { + override def toBackendConst: String = "HWCE_CONV7x7" + override def functionName: String = "HWCE_ProcessOneTile7x7" +} +case object _7x4 extends ConvolutionFilterSize { + override def toBackendConst: String = "HWCE_CONV7x7" + override def functionName: String = "HWCE_ProcessOneTile7x4" +} From 8bbc51bef2474d1df01e14903603f63d5b2381e7 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 29 Jul 2021 11:58:48 +0200 Subject: [PATCH 06/86] Added HWCE test prototype --- src/test/scala/shine/GAP8/hwce.scala | 61 ++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/test/scala/shine/GAP8/hwce.scala diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala new file mode 100644 index 000000000..4a77726a0 --- /dev/null +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -0,0 +1,61 @@ +package shine.GAP8 + +import rise.GAP8.DSL.{gap8Run, hwce} +import rise.core.DSL.HighLevelConstructs._ +import rise.core.DSL.Type._ +import rise.core.DSL._ +import rise.core.Expr +import rise.core.primitives._ +import rise.core.types._ +import rise.elevate.Rise +import shine.GAP8 + +class hwce extends test_util.Tests { + + private def checkHwceCall(filterSize: String) = { + ??? + } + + + + test("Minimal example") { + val w: Nat = 6 + val h: Nat = 6 + + val fW: Nat = 3 + val fH: Nat = 3 + /** + * HWCE performs 2D convolution, Input and filter being represented with 1D + * array though + * HWCE_ProcessOneTile3x3_MultiOut(e1, output, NULL, NULL, e2, 0, n, m, 0x7) + * */ + //TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) + val expr: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (fW`.`fH`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => + in |> + slide2D(3, 1) |> + mapSeq(mapSeq(fun(sub => { + zip(sub |> join)(filter |> join) |> + map(fun(x => fst(x) * snd(x))) |> + reduceSeq(add)(li16(0)) + }))) + ) + } + + println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) + } + + test("Hwce RISE primitive") { + val n: Nat = 6 + val m: Nat = 6 + val fW: Nat = 3 + val fH: Nat = 3 + val oW: Nat = 4 + val oH: Nat = 4 + + val expr: ToBeTyped[Rise] = + fun((n`.`m`.`i16) ->: (fW`.`fH`.`i16) ->: (oW`.`oH`.`i16))((in, filter) => + hwce()(in, filter) + ) + } +} From 10abc44f5489d098ea954c4f4e4810c94fe769b5 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 18 Aug 2021 11:12:21 +0200 Subject: [PATCH 07/86] GAP8 hwce tests + minor code cleanup --- .../rise/GAP8/primitives/gap8hwConv.scala | 24 --------------- .../rise/GAP8/primitives/gap8hwConvv3.scala | 24 --------------- .../GAP8/primitives/functional/Conv.scala | 20 ------------- src/test/scala/shine/GAP8/codegen.scala | 1 - src/test/scala/shine/GAP8/hwce.scala | 29 +++++++++++++++++-- 5 files changed, 26 insertions(+), 72 deletions(-) delete mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConv.scala delete mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala delete mode 100644 src/main/scala/shine/GAP8/primitives/functional/Conv.scala diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv.scala deleted file mode 100644 index a09b57d77..000000000 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv.scala +++ /dev/null @@ -1,24 +0,0 @@ -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // -// This file is automatically generated and should not be changed manually // -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // -package rise.GAP8.primitives -import rise.core.DSL._ -import rise.core.DSL.Type._ -import rise.core._ -import rise.core.types._ -import arithexpr.arithmetic._ -object gap8hwConv extends Builder { - private final case class Primitive()(override val t: Type = TypePlaceholder) extends rise.core.Primitive { - override val name: String = "gap8hwConv" - override def setType(ty: Type): Primitive = Primitive()(ty) - override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: Type = impl { (w: Nat) => impl { (h: Nat) => impl { (bias: Nat) => impl { (s: DataType) => ArrayType(h, ArrayType(w, s)) ->: ArrayType(10, s) ->: ArrayType(h - 2, ArrayType(w - 2, s)) } } } } - } - override def toString: String = "gap8hwConv" - override def primitive: rise.core.Primitive = Primitive()() - override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) - override def unapply(arg: Expr): Boolean = arg match { - case _: Primitive => true - case _ => false - } -} diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala deleted file mode 100644 index 3a6234e41..000000000 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConvv3.scala +++ /dev/null @@ -1,24 +0,0 @@ -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // -// This file is automatically generated and should not be changed manually // -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // -package rise.GAP8.primitives -import rise.core.DSL._ -import rise.core.DSL.Type._ -import rise.core._ -import rise.core.types._ -import arithexpr.arithmetic._ -object gap8hwConvv3 extends Builder { - private final case class Primitive()(override val t: Type = TypePlaceholder) extends rise.core.Primitive { - override val name: String = "gap8hwConvv3" - override def setType(ty: Type): Primitive = Primitive()(ty) - override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: Type = impl { (iw: Nat) => impl { (ih: Nat) => impl { (fw: Nat) => impl { (fh: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (bias: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(fh, ArrayType(fw, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } } - } - override def toString: String = "gap8hwConvv3" - override def primitive: rise.core.Primitive = Primitive()() - override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) - override def unapply(arg: Expr): Boolean = arg match { - case _: Primitive => true - case _ => false - } -} diff --git a/src/main/scala/shine/GAP8/primitives/functional/Conv.scala b/src/main/scala/shine/GAP8/primitives/functional/Conv.scala deleted file mode 100644 index d3bf462c9..000000000 --- a/src/main/scala/shine/GAP8/primitives/functional/Conv.scala +++ /dev/null @@ -1,20 +0,0 @@ -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // -// This file is automatically generated and should not be changed manually // -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // -package shine.GAP8.primitives.functional -import arithexpr.arithmetic._ -import shine.DPIA.Phrases._ -import shine.DPIA.Types.DataType._ -import shine.DPIA.Types._ -import shine.DPIA.Types.Kind.{ Identifier => _, _ } -import shine.DPIA._ -final case class Conv(fs: shine.GAP8.ConvolutionFilterSize)(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { - assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) - filter :: expT(ArrayType(10, dt), read) - true - } - override val t: ExpType = expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) - override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv = new Conv(fs)(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) - def unwrap: (Nat, Nat, Nat, DataType, Phrase[ExpType], Phrase[ExpType]) = (w, h, bias, dt, in, filter) -} diff --git a/src/test/scala/shine/GAP8/codegen.scala b/src/test/scala/shine/GAP8/codegen.scala index f22009308..93a2b3a2c 100644 --- a/src/test/scala/shine/GAP8/codegen.scala +++ b/src/test/scala/shine/GAP8/codegen.scala @@ -9,7 +9,6 @@ import rise.core.primitives._ import rise.core.types._ import rise.elevate.Rise import shine.GAP8 -import util.{ExecuteOpenCL, SyntaxChecker} class codegen extends test_util.Tests { diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 4a77726a0..9acd9ee08 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -1,14 +1,13 @@ package shine.GAP8 -import rise.GAP8.DSL.{gap8Run, hwce} +import rise.GAP8.DSL.hwce +import rise.GAP8.primitives.gap8hwConv3x3 import rise.core.DSL.HighLevelConstructs._ import rise.core.DSL.Type._ import rise.core.DSL._ -import rise.core.Expr import rise.core.primitives._ import rise.core.types._ import rise.elevate.Rise -import shine.GAP8 class hwce extends test_util.Tests { @@ -45,6 +44,30 @@ class hwce extends test_util.Tests { println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) } + test("Minimal example 2") { + val w: Nat = 6 + val h: Nat = 6 + + val fW: Nat = 3 + val fH: Nat = 3 + /** + * HWCE performs 2D convolution, Input and filter being represented with 1D + * array though + * HWCE_ProcessOneTile3x3_MultiOut(e1, output, NULL, NULL, e2, 0, n, m, 0x7) + * */ + //TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) + val expr: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (fW`.`fH`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => + gap8hwConv3x3(0)(in)(filter) + ) + } + + println(expr.toExpr) + println(expr.toExpr.t) + + println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) + } + test("Hwce RISE primitive") { val n: Nat = 6 val m: Nat = 6 From b767fb1be89b0a4fdbd71852786d94a7f3d1dc89 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 18 Aug 2021 11:13:36 +0200 Subject: [PATCH 08/86] WIP: GAP8 hwce primitives --- .../primitives/functional/FunConv3x3.scala | 20 +++++++++++++++++ .../primitives/functional/primitives.dpia | 22 ++++++++++++++++--- .../primitives/imperative/primitives.dpia | 4 ++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala new file mode 100644 index 000000000..01cd90c7c --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types.DataType._ +import shine.DPIA.Types._ +import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class FunConv3x3(fs: shine.GAP8.ConvolutionFilterSize)(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { + assert { + in :: expT(ArrayType(h, ArrayType(w, dt)), read) + filter :: expT(ArrayType(3, ArrayType(3, dt)), read) + true + } + override val t: ExpType = expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv3x3 = new FunConv3x3(fs)(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) + def unwrap: (Nat, Nat, Nat, DataType, Phrase[ExpType], Phrase[ExpType]) = (w, h, bias, dt, in, filter) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index 9ac106308..d96d7c5e8 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -2,11 +2,27 @@ def kernelCall{name: String, cores: Int, n:Int}(inTs: n*data, outT: data, args: def run{cores: Nat}(dt: data, input: exp[dt, write]): exp[dt, write] -def conv{fs: shine.GAP8.ConvolutionFilterSize}( +//rethink +//def conv{fs: shine.GAP8.ConvolutionFilterSize}( +// w: nat, +// h: nat, +// bias: nat, +// dt: data, +// in: exp[h.w.dt, read], +// //check +// filter: exp[3.3.dt, read] +//): exp[(h-2).(w-2).dt, write] + +//TODO: rethink +//TODO: Generate other primitives? +//TODO: Remember if there was something about how input size and filter +//TODO: relate to output? +//TODO: Eliminate ConvolutionFilterSize maybe? +def funConv3x3{fs: shine.GAP8.ConvolutionFilterSize}( w: nat, h: nat, bias: nat, dt: data, in: exp[h.w.dt, read], - filter: exp[10.dt, read] -): exp[(h-2).(w-2).dt, write] + filter: exp[3.3.dt, read] +): exp[(h-2).(w-2).dt, write] \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index c7d644fdc..5d3ea3319 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -1,6 +1,7 @@ def kernelCallCmd{name: String, cores: Int, n: Int} (inTs: n*data, dt: data, args: n*exp[*inTs, read], output: acc[dt]): comm +//TODO: join and pad def conv3x3(w: nat, h: nat, bias: nat, @@ -9,6 +10,7 @@ def conv3x3(w: nat, filter: exp[10.dt, read], out: acc[(h-2).(w-2).dt]): comm +//TODO: join and pad def conv5x5(w: nat, h: nat, bias: nat, @@ -17,6 +19,7 @@ def conv5x5(w: nat, filter: exp[26.dt, read], out: acc[(h-4).(w-4).dt]): comm +//TODO: join and pad def conv7x7(w: nat, h: nat, bias: nat, @@ -25,6 +28,7 @@ def conv7x7(w: nat, filter: exp[56.dt, read], out: acc[(h-6).(w-6).dt]): comm +//TODO: join def conv7x4(w: nat, h: nat, bias: nat, From 2c1bdc024f1f43ad3efff366c9676e3292a247c0 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 18 Aug 2021 11:14:03 +0200 Subject: [PATCH 09/86] WIP: GAP8 hwce rise primitives --- .../rise/GAP8/primitives/gap8hwConv3x3.scala | 24 +++++++++++++++++++ .../rise/GAP8/primitives/primitives.rise | 13 ++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala new file mode 100644 index 000000000..eb9ec3b3c --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala @@ -0,0 +1,24 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import arithexpr.arithmetic._ +object gap8hwConv3x3 extends Builder { + private final case class Primitive()(override val t: Type = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "gap8hwConv3x3" + override def setType(ty: Type): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: Type = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (fw: Nat) => impl { (fh: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(fh, ArrayType(fw, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } } + } + override def toString: String = "gap8hwConv3x3" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 0190283c9..6d648db7d 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -1,14 +1,17 @@ def gap8RunPrimitive: (cores: nat) -> {t: data} -> t -> t -def gap8hwConv: {w: nat} -> {h: nat} -> - {bias: nat} -> {s: data} -> - h.w.s -> 10.s -> (h-2).(w-2).s +//def gap8hwConv: {w: nat} -> {h: nat} -> +// {bias: nat} -> {s: data} -> +// h.w.s -> 10.s -> (h-2).(w-2).s //ConvType here as well, encapsulating sizes for each filter type //def gap8hwConv_v2: (type: ) -def gap8hwConvv3: {iw: nat} -> {ih: nat} -> +//TODO: bias +//TODO: turn this to 3x3 +//TODO: generate primitives for other sizes +def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> {fw: nat} -> {fh: nat} -> {ow: nat} -> {oh: nat} -> - {bias: nat} -> {s: data} -> + {s: data} -> ih.iw.s -> fh.fw.s -> oh.ow.s From dafa91e978142b907f4183400d7e435886d00bfb Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 18 Aug 2021 11:15:47 +0200 Subject: [PATCH 10/86] WIP: GAP8 hwce translation implementation --- .../DPIA/Compilation/AcceptorTranslation.scala | 9 +++++++-- .../scala/shine/DPIA/InferAccessAnnotation.scala | 9 +++++++++ src/main/scala/shine/DPIA/fromRise.scala | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index 129a74bd4..9907a2080 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -351,11 +351,16 @@ object AcceptorTranslation { //GAP8 //case shine.GAP8.primitives.functional.Conv(w, h, bias, dt, in, filter) => - case c@shine.GAP8.primitives.functional.Conv(fs) => + case c@shine.GAP8.primitives.functional.FunConv3x3(fs) => con(c.in)(λ(ExpType(c.h`.`(c.w`.`c.dt), read))(inInner => { fs match { case shine.GAP8._3x3 => - con(c.filter)(λ(ExpType(ArrayType(10, c.dt), read))(filterInner => + //TODO: first join then pad, andThen pass to continuation translation + //TODO: get 10.dt array out + //TODO: type of array is 10.dt here + import shine.DPIA.primitives.functional.{Join, PadClamp} + val paddedArray = PadClamp(0, 0, 1, c.dt, Join(c.h, c.w, read, c.dt, c.filter)) + con(paddedArray)(λ(ExpType(ArrayType(3, ArrayType(3, c.dt)), read))(filterInner => shine.GAP8.primitives.imperative.Conv3x3(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) )) case shine.GAP8._5x5 => diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index cc41c27ae..3bf00abef 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -622,6 +622,15 @@ private class InferAccessAnnotation { nFunT(cores, expT(t, write) ->: expT(t, write)) case _ => error() } + + case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { + case bias `(Nat)->:` ((rt.ArrayType(h, rt.ArrayType(w, s: rt.DataType))) ->: + (rt.ArrayType(fh, rt.ArrayType(fw, _))) ->: rt.ArrayType(oh, rt.ArrayType(ow, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, dataType(s))), read) + ->: expT(ArrayType(fh, ArrayType(fw, dataType(s))), read) ->: + expT(ArrayType(oh, ArrayType(ow, dataType(s))), write) + ) + } } checkConsistency(p.t, primitiveType) diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index 1054aa532..b19c99d4f 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -937,6 +937,21 @@ object fromRise { )) } + case rise.GAP8.primitives.gap8hwConv3x3() => fromType { + case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + expT(ArrayType(fh, ArrayType(fw, _)), `read`) ->: + //TODO: fix mismatch (whatever that means) + //TODO: Previous comment maybe related to 3.3 -> 10 matrix / array sizes + expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + depFun(NatKind, bias)( + fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => + fun[ExpType](expT(ArrayType(fh, ArrayType(fw, s)), read), filter => + shine.GAP8.primitives.functional.FunConv3x3(shine.GAP8._3x3)(w, h, bias, s, input, filter) + ) + ) + ) + } + case _ => throw new Exception(s"Missing rule for $p") } From 5d3b4d69a76a5e40d556b5b9c7d496763eef5ec6 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 8 Sep 2021 21:55:55 +0200 Subject: [PATCH 11/86] Updated gap8hwConv primitive --- .../scala/rise/GAP8/primitives/gap8hwConv3x3.scala | 7 ++++--- src/main/scala/rise/GAP8/primitives/primitives.rise | 13 +++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala index eb9ec3b3c..18b81a8cf 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala @@ -6,13 +6,14 @@ import rise.core.DSL._ import rise.core.DSL.Type._ import rise.core._ import rise.core.types._ +import rise.core.types.DataType._ import arithexpr.arithmetic._ object gap8hwConv3x3 extends Builder { - private final case class Primitive()(override val t: Type = TypePlaceholder) extends rise.core.Primitive { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { override val name: String = "gap8hwConv3x3" - override def setType(ty: Type): Primitive = Primitive()(ty) + override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: Type = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (fw: Nat) => impl { (fh: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(fh, ArrayType(fw, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(3, ArrayType(3, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } override def toString: String = "gap8hwConv3x3" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 6d648db7d..008550888 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -10,8 +10,13 @@ def gap8RunPrimitive: (cores: nat) -> {t: data} -> t -> t //TODO: bias //TODO: turn this to 3x3 //TODO: generate primitives for other sizes +//def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> +// {fw: nat} -> {fh: nat} -> +// {ow: nat} -> {oh: nat} -> +// {s: data} -> +// ih.iw.s -> fh.fw.s -> oh.ow.s + def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> - {fw: nat} -> {fh: nat} -> - {ow: nat} -> {oh: nat} -> - {s: data} -> - ih.iw.s -> fh.fw.s -> oh.ow.s + {ow: nat} -> {oh: nat} -> + {s: data} -> + ih.iw.s -> 3.3.s -> oh.ow.s \ No newline at end of file From ae2da4bd5c83df4a57c5204a7d8fdaa1d8b71329 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 8 Sep 2021 21:56:53 +0200 Subject: [PATCH 12/86] Updated translation chain regarding gap8 hwce --- .../Compilation/AcceptorTranslation.scala | 14 +++++++++++-- .../shine/DPIA/InferAccessAnnotation.scala | 20 ++++++++++++++++++- src/main/scala/shine/DPIA/fromRise.scala | 15 +++++++++++++- .../primitives/functional/FunConv3x3.scala | 10 +++++----- .../primitives/functional/primitives.dpia | 11 +++++++++- .../GAP8/primitives/imperative/Conv3x3.scala | 5 +++-- .../GAP8/primitives/imperative/Conv5x5.scala | 5 +++-- .../GAP8/primitives/imperative/Conv7x4.scala | 5 +++-- .../GAP8/primitives/imperative/Conv7x7.scala | 5 +++-- 9 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index a1cd719f1..0c1ba2646 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -354,8 +354,18 @@ object AcceptorTranslation { cudaImp.WmmaMMA(m, n, k, layoutA, layoutB, dataType, dataTypeAcc, aMatrix, bMatrix, cMatrix, A))))))) //GAP8 + + case shine.GAP8.primitives.functional.FunConv3x3(w, h, bias, dt, in, filter) => + con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { + import shine.DPIA.primitives.functional.{Join, PadClamp} + val paddedArray = PadClamp(3 * 3, 0, 1, dt, Join(3, 3, read, dt, filter)) + con(paddedArray)(λ(ExpType(ArrayType(10, dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv3x3(w, h, bias, dt, inInner, filterInner, A) + )) + })) + //case shine.GAP8.primitives.functional.Conv(w, h, bias, dt, in, filter) => - case c@shine.GAP8.primitives.functional.FunConv3x3(fs) => + /*case c@shine.GAP8.primitives.functional.FunConv3x3(fs) => con(c.in)(λ(ExpType(c.h`.`(c.w`.`c.dt), read))(inInner => { fs match { case shine.GAP8._3x3 => @@ -382,7 +392,7 @@ object AcceptorTranslation { case _=> throw new Exception("Unsupported filter size") } - })) + }))*/ case r@shine.GAP8.primitives.functional.Run(cores) => { ??? diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index 5daa2f1cf..5b353c3dc 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -603,13 +603,31 @@ private class InferAccessAnnotation { case _ => error() } - case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { + /*case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { case bias `(Nat)->:` ((rt.ArrayType(h, rt.ArrayType(w, s: rt.DataType))) ->: (rt.ArrayType(fh, rt.ArrayType(fw, _))) ->: rt.ArrayType(oh, rt.ArrayType(ow, _))) => nFunT(bias, expT(ArrayType(h, ArrayType(w, dataType(s))), read) ->: expT(ArrayType(fh, ArrayType(fw, dataType(s))), read) ->: expT(ArrayType(oh, ArrayType(ow, dataType(s))), write) ) + }*/ + + /*case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: + ArrayType(oh, ArrayType(ow, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) + ->: expT(ArrayType(3, ArrayType(3, s)), read) ->: + expT(ArrayType(oh, ArrayType(ow, s)), write) + ) + }*/ + + case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) + ->: expT(ArrayType(3, ArrayType(3, s)), read) ->: + expT(ArrayType(oh, ArrayType(ow, s)), write) + ) } } diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index e040d3e8c..b93262124 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -928,7 +928,7 @@ object fromRise { )) } - case rise.GAP8.primitives.gap8hwConv3x3() => fromType { + /*case rise.GAP8.primitives.gap8hwConv3x3() => fromType { case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: expT(ArrayType(fh, ArrayType(fw, _)), `read`) ->: //TODO: fix mismatch (whatever that means) @@ -941,6 +941,19 @@ object fromRise { ) ) ) + }*/ + + case rise.GAP8.primitives.gap8hwConv3x3() => fromType { + case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + expT(ArrayType(_, ArrayType(_, _)), `read`) ->: + expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + depFun(NatKind, bias)( + fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => + fun[ExpType](expT(ArrayType(3, ArrayType(3, s)), read), filter => + shine.GAP8.primitives.functional.FunConv3x3(w, h, bias, s, input, filter) + ) + ) + ) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala index 01cd90c7c..4048bba72 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala @@ -4,17 +4,17 @@ package shine.GAP8.primitives.functional import arithexpr.arithmetic._ import shine.DPIA.Phrases._ -import shine.DPIA.Types.DataType._ import shine.DPIA.Types._ -import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class FunConv3x3(fs: shine.GAP8.ConvolutionFilterSize)(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { +final case class FunConv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(3, ArrayType(3, dt)), read) true } override val t: ExpType = expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) - override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv3x3 = new FunConv3x3(fs)(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) - def unwrap: (Nat, Nat, Nat, DataType, Phrase[ExpType], Phrase[ExpType]) = (w, h, bias, dt, in, filter) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv3x3 = new FunConv3x3(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index d96d7c5e8..71f6fdc34 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -18,7 +18,16 @@ def run{cores: Nat}(dt: data, input: exp[dt, write]): exp[dt, write] //TODO: Remember if there was something about how input size and filter //TODO: relate to output? //TODO: Eliminate ConvolutionFilterSize maybe? -def funConv3x3{fs: shine.GAP8.ConvolutionFilterSize}( +//def funConv3x3{fs: shine.GAP8.ConvolutionFilterSize}( +// w: nat, +// h: nat, +// bias: nat, +// dt: data, +// in: exp[h.w.dt, read], +// filter: exp[3.3.dt, read] +//): exp[(h-2).(w-2).dt, write] + +def funConv3x3( w: nat, h: nat, bias: nat, diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala index ac02d61eb..294121c87 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala @@ -4,9 +4,10 @@ package shine.GAP8.primitives.imperative import arithexpr.arithmetic._ import shine.DPIA.Phrases._ -import shine.DPIA.Types.DataType._ import shine.DPIA.Types._ -import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala index ccfcce250..abd4f582f 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala @@ -4,9 +4,10 @@ package shine.GAP8.primitives.imperative import arithexpr.arithmetic._ import shine.DPIA.Phrases._ -import shine.DPIA.Types.DataType._ import shine.DPIA.Types._ -import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala index 1bf7762b7..dcee5059f 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala @@ -4,9 +4,10 @@ package shine.GAP8.primitives.imperative import arithexpr.arithmetic._ import shine.DPIA.Phrases._ -import shine.DPIA.Types.DataType._ import shine.DPIA.Types._ -import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala index 9bc7e0d73..3073fad9f 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala @@ -4,9 +4,10 @@ package shine.GAP8.primitives.imperative import arithexpr.arithmetic._ import shine.DPIA.Phrases._ -import shine.DPIA.Types.DataType._ import shine.DPIA.Types._ -import shine.DPIA.Types.Kind.{ Identifier => _, _ } +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { From 968a1813deabad245c1b25fad2ebc493c2572172 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 8 Sep 2021 21:57:23 +0200 Subject: [PATCH 13/86] Updated DataType(s) in gap8 hwce test --- src/test/scala/shine/GAP8/hwce.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 9acd9ee08..2b82c8ac2 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -7,6 +7,7 @@ import rise.core.DSL.Type._ import rise.core.DSL._ import rise.core.primitives._ import rise.core.types._ +import rise.core.types.DataType._ import rise.elevate.Rise class hwce extends test_util.Tests { @@ -48,8 +49,6 @@ class hwce extends test_util.Tests { val w: Nat = 6 val h: Nat = 6 - val fW: Nat = 3 - val fH: Nat = 3 /** * HWCE performs 2D convolution, Input and filter being represented with 1D * array though @@ -57,7 +56,7 @@ class hwce extends test_util.Tests { * */ //TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) val expr: ToBeTyped[Rise] = { - fun((w`.`h`.`i16) ->: (fW`.`fH`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => + fun((w`.`h`.`i16) ->: (3`.`3`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => gap8hwConv3x3(0)(in)(filter) ) } From 6a9b94265071ad7068f3a6f808c11cc79cbea897 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 8 Sep 2021 22:21:36 +0200 Subject: [PATCH 14/86] Temporary ignoring hwce tests --- src/test/scala/shine/GAP8/hwce.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 2b82c8ac2..5b8b7bf3f 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -18,7 +18,7 @@ class hwce extends test_util.Tests { - test("Minimal example") { + ignore("Minimal example") { val w: Nat = 6 val h: Nat = 6 @@ -45,7 +45,7 @@ class hwce extends test_util.Tests { println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) } - test("Minimal example 2") { + ignore("Minimal example 2") { val w: Nat = 6 val h: Nat = 6 @@ -67,7 +67,7 @@ class hwce extends test_util.Tests { println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) } - test("Hwce RISE primitive") { + ignore("Hwce RISE primitive") { val n: Nat = 6 val m: Nat = 6 val fW: Nat = 3 From 64759a3a7eb389a12ba5db7f1cb8ea25f3c77bfc Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 10 Sep 2021 10:26:02 +0200 Subject: [PATCH 15/86] WIP: HWCE code generation debugging --- .../shine/GAP8/Compilation/AcceleratorCodeGenerator.scala | 3 +++ src/main/scala/util/gen.scala | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 90dfc3233..1d5623d72 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -6,6 +6,7 @@ import shine.DPIA.Compilation.TranslationContext import shine.DPIA.Nat import shine.DPIA.Phrases.Phrase import shine.DPIA.Types.CommType +import shine.DPIA.primitives.functional.{Join, PadClamp} import shine.GAP8.ConvolutionFilterSize import shine.GAP8.primitives.imperative.{Conv3x3, Conv5x5, Conv7x4, Conv7x7} import shine.{C, OpenMP} @@ -21,6 +22,8 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def translationContext: TranslationContext = super.translationContext override def cmd(env: Environment): Phrase[CommType] => Stmt = { + //case Conv3x3(w, h, bias, dt, in, PadClamp(n, l, r, _, Join(_, _, _, _, filter)), out) => + // ??? //TODO: Supoort multicycle output for 3x3 case Conv3x3(w, h, bias, dt, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { diff --git a/src/main/scala/util/gen.scala b/src/main/scala/util/gen.scala index 6bb8d6872..b23073bdf 100644 --- a/src/main/scala/util/gen.scala +++ b/src/main/scala/util/gen.scala @@ -3,6 +3,7 @@ package util import rise.elevate.rules.traversal.default import shine.C.Compilation.{CodeGenerator => CCodeGenerator, ModuleGenerator => CModuleGenerator} import shine.DPIA.Compilation.FunDef +import shine.GAP8.Compilation.AcceleratorCodeGenerator import shine.OpenCL.Compilation._ import shine.OpenCL._ import shine.{C, DPIA, Pipe} @@ -105,11 +106,11 @@ object gen { case class function(name: String = "foo") { def fromExpr: Expr => GAP8.Module = - functionFromExpr(name, OpenMP.CodeGenerator()) andThen + functionFromExpr(name, AcceleratorCodeGenerator()) andThen GAP8.Module.fromCModule def asStringFromExpr: Expr => String = - functionAsStringFromExpr(name, OpenMP.CodeGenerator()) + functionAsStringFromExpr(name, AcceleratorCodeGenerator()) /** * Accelerator function only - Injects unpacking code From b843fc23383b7d91dbe322b05f2103fc17d2ae21 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 10 Sep 2021 10:26:14 +0200 Subject: [PATCH 16/86] Tests HWCE --- src/test/scala/shine/GAP8/codegen.scala | 3 +-- src/test/scala/shine/GAP8/hwce.scala | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/scala/shine/GAP8/codegen.scala b/src/test/scala/shine/GAP8/codegen.scala index 3fea1b35c..3a9168144 100644 --- a/src/test/scala/shine/GAP8/codegen.scala +++ b/src/test/scala/shine/GAP8/codegen.scala @@ -96,8 +96,7 @@ class codegen extends test_util.Tests { checkCoreNumber(8, code) findParamsStruct("float*", 3, code) findParamsStruct("int", 3, code) - - //println(code) + println(code) } test("Sobel filter on GAP8") { diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 5b8b7bf3f..0d16cb904 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -45,7 +45,7 @@ class hwce extends test_util.Tests { println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) } - ignore("Minimal example 2") { + test("Minimal example 2") { val w: Nat = 6 val h: Nat = 6 From 4579ef6704fc39f592e45b898dcee5cff161590f Mon Sep 17 00:00:00 2001 From: Michel Steuwer Date: Fri, 10 Sep 2021 13:52:58 +0100 Subject: [PATCH 17/86] Not fix for minimal hwce example --- .../DPIA/Compilation/AcceptorTranslation.scala | 8 +++++--- .../Compilation/AcceleratorCodeGenerator.scala | 15 +++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index 0c1ba2646..cebf9b1c8 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -355,10 +355,12 @@ object AcceptorTranslation { //GAP8 - case shine.GAP8.primitives.functional.FunConv3x3(w, h, bias, dt, in, filter) => + case shine.GAP8.primitives.functional.FunConv3x3(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { - import shine.DPIA.primitives.functional.{Join, PadClamp} - val paddedArray = PadClamp(3 * 3, 0, 1, dt, Join(3, 3, read, dt, filter)) +// import shine.DPIA.primitives.functional.{Join, PadClamp} +// val paddedArray = PadClamp(3 * 3, 0, 1, dt, Join(3, 3, read, dt, filter)) + // TODO: think about generalizing this. This currently only works if the filter is an identifier + val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(10, dt), read)) con(paddedArray)(λ(ExpType(ArrayType(10, dt), read))(filterInner => shine.GAP8.primitives.imperative.Conv3x3(w, h, bias, dt, inInner, filterInner, A) )) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 1d5623d72..07e551667 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -2,10 +2,11 @@ package shine.GAP8.Compilation import arithexpr.arithmetic import arithexpr.arithmetic.ArithExpr -import shine.DPIA.Compilation.TranslationContext +import rise.core.types.DataType.ArrayType +import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} import shine.DPIA.Nat import shine.DPIA.Phrases.Phrase -import shine.DPIA.Types.CommType +import shine.DPIA.Types.{CommType, ExpType} import shine.DPIA.primitives.functional.{Join, PadClamp} import shine.GAP8.ConvolutionFilterSize import shine.GAP8.primitives.imperative.{Conv3x3, Conv5x5, Conv7x4, Conv7x7} @@ -25,10 +26,16 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D //case Conv3x3(w, h, bias, dt, in, PadClamp(n, l, r, _, Join(_, _, _, _, filter)), out) => // ??? //TODO: Supoort multicycle output for 3x3 - case Conv3x3(w, h, bias, dt, in, filter, out) => + case Conv3x3(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + val oldFilterId = shine.DPIA.Phrases.Identifier(filter.name, + ExpType(ArrayType(3, ArrayType(3, dt)), rise.core.types.read)) + val ref = env.identEnv(oldFilterId) + val identEnv = env.identEnv - oldFilterId + val env2 = CodeGenerator.Environment(identEnv + ((filter, ref)), + env.commEnv, env.contEnv, env.letNatEnv) + filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._3x3, w, h, bias, inC, filterC, outputC) }) }) From 46fbf5da2aec957e47176a18fc4a390b0dfa84b5 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 21 Sep 2021 18:53:01 +0200 Subject: [PATCH 18/86] Added rest of the conv primitives --- .../rise/GAP8/primitives/gap8hwConv5x5.scala | 25 ++++++++++++++++ .../rise/GAP8/primitives/gap8hwConv7x4.scala | 25 ++++++++++++++++ .../rise/GAP8/primitives/gap8hwConv7x7.scala | 25 ++++++++++++++++ .../rise/GAP8/primitives/primitives.rise | 29 +++++++++---------- 4 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala create mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala create mode 100644 src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala new file mode 100644 index 000000000..9b01d7041 --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object gap8hwConv5x5 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "gap8hwConv5x5" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(5, ArrayType(5, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + } + override def toString: String = "gap8hwConv5x5" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala new file mode 100644 index 000000000..9506e2f1e --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object gap8hwConv7x4 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "gap8hwConv7x4" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(7, ArrayType(4, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + } + override def toString: String = "gap8hwConv7x4" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala new file mode 100644 index 000000000..f0e830766 --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object gap8hwConv7x7 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "gap8hwConv7x7" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(7, ArrayType(7, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + } + override def toString: String = "gap8hwConv7x7" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 008550888..56fe120ad 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -1,22 +1,21 @@ def gap8RunPrimitive: (cores: nat) -> {t: data} -> t -> t -//def gap8hwConv: {w: nat} -> {h: nat} -> -// {bias: nat} -> {s: data} -> -// h.w.s -> 10.s -> (h-2).(w-2).s +def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> + {ow: nat} -> {oh: nat} -> + {s: data} -> + ih.iw.s -> 3.3.s -> oh.ow.s -//ConvType here as well, encapsulating sizes for each filter type -//def gap8hwConv_v2: (type: ) +def gap8hwConv5x5: (bias: nat) -> {iw: nat} -> {ih: nat} -> + {ow: nat} -> {oh: nat} -> + {s: data} -> + ih.iw.s -> 5.5.s -> oh.ow.s -//TODO: bias -//TODO: turn this to 3x3 -//TODO: generate primitives for other sizes -//def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> -// {fw: nat} -> {fh: nat} -> -// {ow: nat} -> {oh: nat} -> -// {s: data} -> -// ih.iw.s -> fh.fw.s -> oh.ow.s +def gap8hwConv7x7: (bias: nat) -> {iw: nat} -> {ih: nat} -> + {ow: nat} -> {oh: nat} -> + {s: data} -> + ih.iw.s -> 7.7.s -> oh.ow.s -def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> +def gap8hwConv7x4: (bias: nat) -> {iw: nat} -> {ih: nat} -> {ow: nat} -> {oh: nat} -> {s: data} -> - ih.iw.s -> 3.3.s -> oh.ow.s \ No newline at end of file + ih.iw.s -> 7.4.s -> oh.ow.s \ No newline at end of file From afe8a98a30c00c0f5d6f657eed562ad87eedda1e Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 21 Sep 2021 18:53:52 +0200 Subject: [PATCH 19/86] Added rest of the DPIA primitives regarding gap8 hwce --- .../primitives/functional/FunConv5x5.scala | 20 +++++++ .../primitives/functional/FunConv7x4.scala | 20 +++++++ .../primitives/functional/FunConv7x7.scala | 20 +++++++ .../primitives/functional/primitives.dpia | 54 ++++++++++--------- .../GAP8/primitives/imperative/Conv7x4.scala | 2 +- .../primitives/imperative/primitives.dpia | 6 +-- 6 files changed, 90 insertions(+), 32 deletions(-) create mode 100644 src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala create mode 100644 src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala create mode 100644 src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala new file mode 100644 index 000000000..2e9c719fe --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class FunConv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { + assert { + in :: expT(ArrayType(h, ArrayType(w, dt)), read) + filter :: expT(ArrayType(5, ArrayType(5, dt)), read) + true + } + override val t: ExpType = expT(ArrayType(h - 4, ArrayType(w - 4, dt)), write) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv5x5 = new FunConv5x5(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala new file mode 100644 index 000000000..c0e58a236 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class FunConv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { + assert { + in :: expT(ArrayType(h, ArrayType(w, dt)), read) + filter :: expT(ArrayType(7, ArrayType(4, dt)), read) + true + } + override val t: ExpType = expT(ArrayType(h - 3, ArrayType(w - 6, dt)), write) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x4 = new FunConv7x4(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala new file mode 100644 index 000000000..b50c33b8b --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class FunConv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { + assert { + in :: expT(ArrayType(h, ArrayType(w, dt)), read) + filter :: expT(ArrayType(7, ArrayType(7, dt)), read) + true + } + override val t: ExpType = expT(ArrayType(h - 6, ArrayType(w - 6, dt)), write) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x7 = new FunConv7x7(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index 71f6fdc34..82a782535 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -2,31 +2,6 @@ def kernelCall{name: String, cores: Int, n:Int}(inTs: n*data, outT: data, args: def run{cores: Nat}(dt: data, input: exp[dt, write]): exp[dt, write] -//rethink -//def conv{fs: shine.GAP8.ConvolutionFilterSize}( -// w: nat, -// h: nat, -// bias: nat, -// dt: data, -// in: exp[h.w.dt, read], -// //check -// filter: exp[3.3.dt, read] -//): exp[(h-2).(w-2).dt, write] - -//TODO: rethink -//TODO: Generate other primitives? -//TODO: Remember if there was something about how input size and filter -//TODO: relate to output? -//TODO: Eliminate ConvolutionFilterSize maybe? -//def funConv3x3{fs: shine.GAP8.ConvolutionFilterSize}( -// w: nat, -// h: nat, -// bias: nat, -// dt: data, -// in: exp[h.w.dt, read], -// filter: exp[3.3.dt, read] -//): exp[(h-2).(w-2).dt, write] - def funConv3x3( w: nat, h: nat, @@ -34,4 +9,31 @@ def funConv3x3( dt: data, in: exp[h.w.dt, read], filter: exp[3.3.dt, read] -): exp[(h-2).(w-2).dt, write] \ No newline at end of file +): exp[(h-2).(w-2).dt, write] + +def funConv5x5( + w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[h.w.dt, read], + filter: exp[5.5.dt, read] +): exp[(h-4).(w-4).dt, write] + +def funConv7x7( + w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[h.w.dt, read], + filter: exp[7.7.dt, read] +): exp[(h-6).(w-6).dt, write] + +def funConv7x4( + w: nat, + h: nat, + bias: nat, + dt: data, + in: exp[h.w.dt, read], + filter: exp[7.4.dt, read] +): exp[(h-3).(w-6).dt, write] \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala index dcee5059f..2fc925825 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala @@ -13,7 +13,7 @@ final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(28, dt), read) - out :: accT(ArrayType(h - 6, ArrayType(w - 3, dt))) + out :: accT(ArrayType(h - 3, ArrayType(w - 6, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index 5d3ea3319..b52605f94 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -1,7 +1,6 @@ def kernelCallCmd{name: String, cores: Int, n: Int} (inTs: n*data, dt: data, args: n*exp[*inTs, read], output: acc[dt]): comm -//TODO: join and pad def conv3x3(w: nat, h: nat, bias: nat, @@ -10,7 +9,6 @@ def conv3x3(w: nat, filter: exp[10.dt, read], out: acc[(h-2).(w-2).dt]): comm -//TODO: join and pad def conv5x5(w: nat, h: nat, bias: nat, @@ -19,7 +17,6 @@ def conv5x5(w: nat, filter: exp[26.dt, read], out: acc[(h-4).(w-4).dt]): comm -//TODO: join and pad def conv7x7(w: nat, h: nat, bias: nat, @@ -28,11 +25,10 @@ def conv7x7(w: nat, filter: exp[56.dt, read], out: acc[(h-6).(w-6).dt]): comm -//TODO: join def conv7x4(w: nat, h: nat, bias: nat, dt: data, in: exp[h.w.dt, read], filter: exp[28.dt, read], - out: acc[(h-6).(w-3).dt]): comm + out: acc[(h-3).(w-6).dt]): comm From 2907da99de9f4f9aaad0e0dcda11a9384a59ae8e Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 21 Sep 2021 18:54:17 +0200 Subject: [PATCH 20/86] Ignoring currently unfunctional test --- src/test/scala/shine/GAP8/hwce.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 0d16cb904..3f18db2d2 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -9,6 +9,7 @@ import rise.core.primitives._ import rise.core.types._ import rise.core.types.DataType._ import rise.elevate.Rise +import shine.GAP8.Module.translateToString class hwce extends test_util.Tests { @@ -45,7 +46,7 @@ class hwce extends test_util.Tests { println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) } - test("Minimal example 2") { + ignore("Minimal example 2") { val w: Nat = 6 val h: Nat = 6 @@ -65,6 +66,7 @@ class hwce extends test_util.Tests { println(expr.toExpr.t) println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) + //println(translateToString(util.gen.gap8.hosted.fromExpr(expr))) } ignore("Hwce RISE primitive") { From 238a8fe4782d0b86bf8805eca581dfa131d68ac7 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 21 Sep 2021 18:54:57 +0200 Subject: [PATCH 21/86] Minor cleanup --- .../scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 07e551667..4e46a4a18 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -23,8 +23,6 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def translationContext: TranslationContext = super.translationContext override def cmd(env: Environment): Phrase[CommType] => Stmt = { - //case Conv3x3(w, h, bias, dt, in, PadClamp(n, l, r, _, Join(_, _, _, _, filter)), out) => - // ??? //TODO: Supoort multicycle output for 3x3 case Conv3x3(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { From 1951cb5930f2371fbf7c6d46d61eb7dee373f1ab Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 20 Oct 2021 12:18:57 +0200 Subject: [PATCH 22/86] Added HWCE call check, tests should invoke generation of the Hosted Module --- src/test/scala/shine/GAP8/hwce.scala | 32 ++++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 3f18db2d2..a1ad30c92 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -1,20 +1,22 @@ package shine.GAP8 -import rise.GAP8.DSL.hwce +import rise.GAP8.DSL.{gap8Run, hwce} import rise.GAP8.primitives.gap8hwConv3x3 import rise.core.DSL.HighLevelConstructs._ import rise.core.DSL.Type._ import rise.core.DSL._ import rise.core.primitives._ -import rise.core.types._ import rise.core.types.DataType._ +import rise.core.types._ import rise.elevate.Rise -import shine.GAP8.Module.translateToString +import shine.GAP8 class hwce extends test_util.Tests { - private def checkHwceCall(filterSize: String) = { - ??? + private def checkHwceCall(code: String, filterSize: String) = { + assert( + ("HWCE_ProcessOneTile" + filterSize).r.findAllIn(code).length >= 1 + ) } @@ -26,8 +28,6 @@ class hwce extends test_util.Tests { val fW: Nat = 3 val fH: Nat = 3 /** - * HWCE performs 2D convolution, Input and filter being represented with 1D - * array though * HWCE_ProcessOneTile3x3_MultiOut(e1, output, NULL, NULL, e2, 0, n, m, 0x7) * */ //TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) @@ -46,27 +46,31 @@ class hwce extends test_util.Tests { println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) } - ignore("Minimal example 2") { + test("Minimal example 2") { val w: Nat = 6 val h: Nat = 6 /** - * HWCE performs 2D convolution, Input and filter being represented with 1D - * array though * HWCE_ProcessOneTile3x3_MultiOut(e1, output, NULL, NULL, e2, 0, n, m, 0x7) * */ //TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) val expr: ToBeTyped[Rise] = { fun((w`.`h`.`i16) ->: (3`.`3`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => + gap8Run(8)( gap8hwConv3x3(0)(in)(filter) + ) ) } - println(expr.toExpr) - println(expr.toExpr.t) + //println(expr.toExpr) + //println(expr.toExpr.t) - println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) - //println(translateToString(util.gen.gap8.hosted.fromExpr(expr))) + val hostedModule = util.gen.gap8.hosted.fromExpr(expr) + val code = GAP8.Module.translateToString(hostedModule) + + checkHwceCall(code, "3x3") + + println(code) } ignore("Hwce RISE primitive") { From 3e400dae0652a3925500c677b94692bbbaad0c28 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 20 Oct 2021 12:19:59 +0200 Subject: [PATCH 23/86] Added implementatinos for other types of convolution --- .../Compilation/AcceptorTranslation.scala | 60 ++++++++----------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index cebf9b1c8..3aacfd353 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -354,48 +354,38 @@ object AcceptorTranslation { cudaImp.WmmaMMA(m, n, k, layoutA, layoutB, dataType, dataTypeAcc, aMatrix, bMatrix, cMatrix, A))))))) //GAP8 - + // TODO: think about generalizing this. This currently only works if the filter is an identifier case shine.GAP8.primitives.functional.FunConv3x3(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { -// import shine.DPIA.primitives.functional.{Join, PadClamp} -// val paddedArray = PadClamp(3 * 3, 0, 1, dt, Join(3, 3, read, dt, filter)) - // TODO: think about generalizing this. This currently only works if the filter is an identifier + // import shine.DPIA.primitives.functional.{Join, PadClamp} + // val paddedArray = PadClamp(3 * 3, 0, 1, dt, Join(3, 3, read, dt, filter)) val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(10, dt), read)) con(paddedArray)(λ(ExpType(ArrayType(10, dt), read))(filterInner => shine.GAP8.primitives.imperative.Conv3x3(w, h, bias, dt, inInner, filterInner, A) )) })) - - //case shine.GAP8.primitives.functional.Conv(w, h, bias, dt, in, filter) => - /*case c@shine.GAP8.primitives.functional.FunConv3x3(fs) => - con(c.in)(λ(ExpType(c.h`.`(c.w`.`c.dt), read))(inInner => { - fs match { - case shine.GAP8._3x3 => - //TODO: first join then pad, andThen pass to continuation translation - //TODO: get 10.dt array out - //TODO: type of array is 10.dt here - import shine.DPIA.primitives.functional.{Join, PadClamp} - val paddedArray = PadClamp(0, 0, 1, c.dt, Join(c.h, c.w, read, c.dt, c.filter)) - con(paddedArray)(λ(ExpType(ArrayType(3, ArrayType(3, c.dt)), read))(filterInner => - shine.GAP8.primitives.imperative.Conv3x3(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) - )) - case shine.GAP8._5x5 => - con(c.filter)(λ(ExpType(ArrayType(26, c.dt), read))(filterInner => - shine.GAP8.primitives.imperative.Conv5x5(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) - )) - case shine.GAP8._7x7 => - con(c.filter)(λ(ExpType(ArrayType(56, c.dt), read))(filterInner => - shine.GAP8.primitives.imperative.Conv7x7(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) - )) - case shine.GAP8._7x4 => - con(c.filter)(λ(ExpType(ArrayType(28, c.dt), read))(filterInner => - shine.GAP8.primitives.imperative.Conv7x4(c.w, c.h, c.bias, c.dt, inInner, filterInner, A) - )) - case _=> - throw new Exception("Unsupported filter size") - } - }))*/ - + //TODO: Placeholders. Rethink + case shine.GAP8.primitives.functional.FunConv5x5(w, h, bias, dt, in, filter: Identifier[ExpType]) => + con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { + val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(26, dt), read)) + con(paddedArray)(λ(ExpType(ArrayType(26, dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv5x5(w, h, bias, dt, inInner, filterInner, A) + )) + })) + case shine.GAP8.primitives.functional.FunConv7x7(w, h, bias, dt, in, filter: Identifier[ExpType]) => + con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { + val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(56, dt), read)) + con(paddedArray)(λ(ExpType(ArrayType(56, dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv7x7(w, h, bias, dt, inInner, filterInner, A) + )) + })) + case shine.GAP8.primitives.functional.FunConv7x4(w, h, bias, dt, in, filter: Identifier[ExpType]) => + con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { + val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(28, dt), read)) + con(paddedArray)(λ(ExpType(ArrayType(28, dt), read))(filterInner => + shine.GAP8.primitives.imperative.Conv7x4(w, h, bias, dt, inInner, filterInner, A) + )) + })) case r@shine.GAP8.primitives.functional.Run(cores) => { ??? } From bd81b635f32bc66f733d08f50558a3565792cabf Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 20 Oct 2021 13:20:46 +0200 Subject: [PATCH 24/86] Slightly refactored tests in codegen, added kmeans test --- src/test/scala/shine/GAP8/codegen.scala | 72 +++++++++++++++++++++---- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/src/test/scala/shine/GAP8/codegen.scala b/src/test/scala/shine/GAP8/codegen.scala index 3a9168144..dc81ac230 100644 --- a/src/test/scala/shine/GAP8/codegen.scala +++ b/src/test/scala/shine/GAP8/codegen.scala @@ -11,6 +11,7 @@ import rise.core.types._ import rise.elevate.Rise import shine.GAP8 +// scalastyle:off class codegen extends test_util.Tests { private def findParamsStruct(typeName: String, count: Int, code: String) = { @@ -22,9 +23,6 @@ class codegen extends test_util.Tests { .sliding(typeName.length + 1) .count(wrapped => wrapped.toString().equalsIgnoreCase(typeName + " ")) .shouldBe(count) - - //.count(line => line.contains(typeName)) - //.shouldBe(count) } private def findDeviceBufferSync(count: Int, code: String) = { @@ -59,7 +57,6 @@ class codegen extends test_util.Tests { findDeviceBufferSync(2, code) checkCoreNumber(4, code) findParamsStruct("int32_t*", 2, code) - //SyntaxChecker(code) } test("Variable size") { @@ -78,11 +75,11 @@ class codegen extends test_util.Tests { test("Matmul") { val expr: ToBeTyped[Expr] = depFun((n: Nat, m: Nat, o: Nat) => - fun((n`.`o`.`f32) ->: (o`.`m`.`f32) ->: (n`.`m`.`f32))((a, b) => + fun((n`.`o`.`u32) ->: (o`.`m`.`u32) ->: (n`.`m`.`u32))((a, b) => gap8Run(8)( a |> mapSeq(fun(rowa => b |> transpose |> mapSeq(fun(colb => - zip(rowa)(colb) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(lf32(0.0f)) + zip(rowa)(colb) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(cast(l(0)) :: u32) )) )) ) @@ -94,9 +91,9 @@ class codegen extends test_util.Tests { findDeviceBufferSync(3, code) checkCoreNumber(8, code) - findParamsStruct("float*", 3, code) + findParamsStruct("uint32_t*", 3, code) findParamsStruct("int", 3, code) - println(code) + //println(code) } test("Sobel filter on GAP8") { @@ -104,11 +101,11 @@ class codegen extends test_util.Tests { fun((n`.`m`.`u8) ->: (3`.`3`.`int) ->: (3`.`3`.`int) ->: (n`.`m`.`u8))((pic, h_w, v_w) => gap8Run(8)( pic |> - padClamp2D(l = 1, r = 1) |> + padCst2D(1, 1)(cast(l(0)) :: u8) |> slide2D(sz = 3, st = 1) |> mapSeq(mapSeq(fun(submat => { - zip(submat |> join)(h_w |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeq(add)(cast(l(0)) :: u32) |> letf(h => - zip(submat |> join)(v_w |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeq(add)(cast(l(0)) :: u32) |> letf(v => + zip(submat |> join)(h_w |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeqUnroll(add)(cast(l(0)) :: u32) |> letf(h => + zip(submat |> join)(v_w |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeqUnroll(add)(cast(l(0)) :: u32) |> letf(v => cast(apps.SobelFilter.gapSqrt(h * h + v * v)) :: u8 ) ) @@ -127,5 +124,58 @@ class codegen extends test_util.Tests { findParamsStruct("uint8_t*", 2, code) findParamsStruct("int", 2, code) findParamsStruct("int*", 2, code) + //println(code) + } + + test("KMeans on GAP8") { + val testF = foreignFun("test", + Seq("dist", "tuple"), + """{ + | uint32_t min_dist = tuple._fst; + | uint32_t i = tuple._snd._fst; + | uint32_t index = tuple._snd._snd; + | if (dist < min_dist) { + | return (struct Record_uint32_t__uint32_t_uint32_t_){ dist, { i + 1 , i } }; + | } else { + | return (struct Record_uint32_t__uint32_t_uint32_t_){ min_dist, { i + 1, index } }; + | } + }""".stripMargin, + u32 ->: (u32 x (u32 x u32)) ->: (u32 x (u32 x u32)) + ) + + val update = fun(u32 ->: (u32 x u32) ->: u32)((dist, pair) => + dist + (pair._1 - pair._2) * (pair._1 - pair._2) + ) + + val select = fun(tuple => tuple._2._2) + + // p -> number of points, c -> number of clusters, f -> number of features + // from lift.highLevel.kmeans featuresType = ArrayType(ArrayType(Float, P), F) + // features matrix F x P + // from lift.highLevel.kmeans clustersType = ArrayType(ArrayType(Float, F), C) + // clusters matrix C X F + val expr: ToBeTyped[Rise] = depFun((p: Nat, c: Nat, f: Nat) => + fun((f`.`p`.`u32) ->: (c`.`f`.`u32) ->: (p`.`u32))((features, clusters) => + gap8Run(8)( + features |> transpose |> mapSeq(fun(feature => + clusters |> reduceSeq(fun(tuple => fun(cluster => { + val dist = zip(feature)(cluster) |> reduceSeq(update)(cast(l(0)) :: u32) + testF(dist)(tuple) + })))( + makePair(cast(l(4294967295L)) :: u32)(makePair(cast(l(0)) :: u32)(cast(l(0)) :: u32)) + ) |> select + )) + ) + ) + ) + + val hostedModule = util.gen.gap8.hosted.fromExpr(expr) + val code = GAP8.Module.translateToString(hostedModule) + + findDeviceBufferSync(3, code) + checkCoreNumber(8, code) + findParamsStruct("uint32_t*", 3, code) + findParamsStruct("int", 3, code) + //println(code) } } From 19410908d5953cc671cdc2187a29a505078a6531 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 20 Oct 2021 13:32:06 +0200 Subject: [PATCH 25/86] Working on HWCE support; Bugfixes regarding code generation for GAP8 in general --- .../shine/GAP8/Compilation/HostCodeGenerator.scala | 5 +++++ .../shine/OpenCL/Compilation/HostManagedBuffers.scala | 3 +++ src/main/scala/shine/OpenMP/CodeGenerator.scala | 4 +++- src/main/scala/util/gen.scala | 11 +++++------ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala index dc8b1ee95..1035b7bad 100644 --- a/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala @@ -172,6 +172,11 @@ case class HostCodeGenerator( private def managedTyp(dt: DataType): C.AST.Type = dt match { case ArrayType(_, elemType) => C.AST.PointerType(typ(elemType)) + //TODO: Rethink + case PairType(dt1, dt2) => C.AST.StructType( + "Tuple_" + dt1.toString + "_" + dt2.toString, + Seq((typ(dt1), "_fst"), (typ(dt2), "_snd")) + ) case _ => throw new Exception(s"did not expect $dt") } diff --git a/src/main/scala/shine/OpenCL/Compilation/HostManagedBuffers.scala b/src/main/scala/shine/OpenCL/Compilation/HostManagedBuffers.scala index 86ac0553b..02761eee8 100644 --- a/src/main/scala/shine/OpenCL/Compilation/HostManagedBuffers.scala +++ b/src/main/scala/shine/OpenCL/Compilation/HostManagedBuffers.scala @@ -6,6 +6,7 @@ import shine.DPIA._ import shine.DPIA.Phrases._ import shine.DPIA.Types._ import shine.DPIA.primitives.{imperative => dpia} +import shine.GAP8.primitives.imperative.{Conv3x3, Conv5x5, Conv7x4, Conv7x7} import shine.OpenCL._ import shine.OpenCL.primitives.imperative.HostExecution import shine.OpenCL.primitives.{imperative => ocl} @@ -178,6 +179,8 @@ object HostManagedBuffers { newArgs.map(_.t.dataType), newOutput.t.dataType, k.args.map(VisitAndRebuild(_, this)), newOutput )) case _: HostExecution => Stop(p) + case _: Conv3x3 | _: Conv5x5 | _: Conv7x7 | _: Conv7x4 => + Continue(p, this) case unexpected => throw new Exception(s"did not expect $unexpected") } } diff --git a/src/main/scala/shine/OpenMP/CodeGenerator.scala b/src/main/scala/shine/OpenMP/CodeGenerator.scala index 9870cc202..b19cf4345 100644 --- a/src/main/scala/shine/OpenMP/CodeGenerator.scala +++ b/src/main/scala/shine/OpenMP/CodeGenerator.scala @@ -291,6 +291,9 @@ class CodeGenerator(override val decls: CCodeGenerator.Declarations, case (_: ScalarType, Nil) => CCodeGen.codeGenForeignFunctionCall(funDecl, inTs, outT, args, env, cont) + case (pt@PairType(dt1, dt2), _) => + CCodeGen.codeGenForeignFunctionCall(funDecl, inTs, outT, args, env, cont) + // TODO: This has to be generalised at some point ... case (VectorType(_, elemType), i :: Nil) => // this is not really generic, to treat all arguments the same ... @@ -313,7 +316,6 @@ class CodeGenerator(override val decls: CCodeGenerator.Declarations, } CCodeGen.codeGenForeignCall(funDecl.name, args, env, i :: Nil, cont) - case _ => throw new Exception(s"Can not generate fun call to $funDecl with current path $ps") } diff --git a/src/main/scala/util/gen.scala b/src/main/scala/util/gen.scala index b23073bdf..da5209c46 100644 --- a/src/main/scala/util/gen.scala +++ b/src/main/scala/util/gen.scala @@ -120,8 +120,8 @@ object gen { ): Expr => String = functionFromExpr(name, gen) andThen GAP8.Module.injectUnpacking andThen - C.Module.translateToString andThen - run(SyntaxChecker(_)) + C.Module.translateToString// andThen + //run(SyntaxChecker(_)) } type HostedModule = GAP8.Module @@ -134,15 +134,14 @@ object gen { case class hosted(name: String = "foo"){ - def funDefToCModule(): FunDef => C.Module = - shine.C.Compilation.ModuleGenerator.funDefToModule(shine.C.Compilation.CodeGenerator()) - + def funDefToAcceleratorModule(): FunDef => C.Module = + shine.C.Compilation.ModuleGenerator.funDefToModule(shine.GAP8.Compilation.AcceleratorCodeGenerator()) def fromExpr: Expr => HostedModule = exprToPhrase andThen fromPhrase def fromPhrase: Phrase => HostedModule = partialHostCompiler(name) composeWith - ((((x: FunDef) => x) x map(funDefToCModule())) andThen hostFunDefToHostPart) + ((((x: FunDef) => x) x map(funDefToAcceleratorModule())) andThen hostFunDefToHostPart) private val hostFunDefToHostPart: ((FunDef, Seq[C.Module])) => (C.Module, Seq[C.Module]) = { case (hostModule, acceleratorModule) => From 577a678f79953a228e251848d7d5c758fecd0d87 Mon Sep 17 00:00:00 2001 From: bpervan Date: Sat, 23 Oct 2021 13:16:24 +0200 Subject: [PATCH 26/86] Added GAP8 hardware convolution rule --- .../rise/elevate/rules/algorithmic.scala | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/main/scala/rise/elevate/rules/algorithmic.scala b/src/main/scala/rise/elevate/rules/algorithmic.scala index 656e2f77b..2ef250a76 100644 --- a/src/main/scala/rise/elevate/rules/algorithmic.scala +++ b/src/main/scala/rise/elevate/rules/algorithmic.scala @@ -14,6 +14,7 @@ import rise.core.types._ import rise.elevate._ import rise.elevate.strategies.normalForm.DFNF import rise.elevate.strategies.predicate._ +import rise.GAP8.primitives._ // noinspection MutatorLikeMethodIsParameterless object algorithmic { @@ -561,4 +562,53 @@ object algorithmic { case e @ App(sum2, App(join(), in)) if sum2 =~= ((sum !: sum2.t): Expr) => Success((preserveType(in) |> transpose |> map(sum) |> sum) !: e.t) } + + /** + * TODO: A couple of things to think about: + * 1.This is extremely specific. Is there a way to make it more general in any way? + * 2. Concrete HWCE primitive depends not only on the size of the sliding window, + * but on the appropirate dimensions of the input parameters as well. Patch that in + * 3. slide2D has to be deconstructed fully to ensure that the underlying pattern + * fully conforms with the slide2D + * 4. Generalize mapSeq() and reduceSeq() + * */ + @rule def gap8hwConvMerge: Strategy[Rise] = { + case e @ + App( + App(mapSeq(), + App(mapSeq(), Lambda(_, + App( + App( + App(reduceSeq(), add()), + App(cast(), _)), + App( + App(map(), Lambda(_, + App(App(mul(), App(fst(), _)), App(snd(), _)) + ) + ), + App(App(zip(), App(join(), _)), App(join(), _)) + ) + ) + ) + ) + ), + App(Lambda(_, + App(_, + App(Lambda(_, + App( + DepApp(NatKind, DepApp(NatKind, slide(), size), step), _ + ) + ), _) + ) + ), _) + ) => + (size, step) match { + case (Cst(iSize), Cst(iStep)) => + if(1 == iStep && 3 == iSize) Success(gap8hwConv3x3(0)) + else if(1 == iStep && 5 == iSize) Success(gap8hwConv5x5(0)) + else if(1 == iStep && 7 == iSize) Success(gap8hwConv7x7(0)) + else Failure(gap8hwConvMerge) + case _ => Failure(gap8hwConvMerge) + } + } } From 13ce0e91d03bc58fff28de4de7b91d7199859b5f Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 25 Oct 2021 17:28:25 +0200 Subject: [PATCH 27/86] Fixed HWCE strategy --- src/main/scala/rise/elevate/rules/algorithmic.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/scala/rise/elevate/rules/algorithmic.scala b/src/main/scala/rise/elevate/rules/algorithmic.scala index 2ef250a76..7f46de225 100644 --- a/src/main/scala/rise/elevate/rules/algorithmic.scala +++ b/src/main/scala/rise/elevate/rules/algorithmic.scala @@ -571,6 +571,7 @@ object algorithmic { * 3. slide2D has to be deconstructed fully to ensure that the underlying pattern * fully conforms with the slide2D * 4. Generalize mapSeq() and reduceSeq() + * 5. This should apply only if wrapped somewhere within gap8run (HWCE is in cluster) * */ @rule def gap8hwConvMerge: Strategy[Rise] = { case e @ @@ -586,7 +587,7 @@ object algorithmic { App(App(mul(), App(fst(), _)), App(snd(), _)) ) ), - App(App(zip(), App(join(), _)), App(join(), _)) + App(App(zip(), App(join(), _)), App(join(), filter)) ) ) ) @@ -600,13 +601,13 @@ object algorithmic { ) ), _) ) - ), _) + ), in) ) => (size, step) match { case (Cst(iSize), Cst(iStep)) => - if(1 == iStep && 3 == iSize) Success(gap8hwConv3x3(0)) - else if(1 == iStep && 5 == iSize) Success(gap8hwConv5x5(0)) - else if(1 == iStep && 7 == iSize) Success(gap8hwConv7x7(0)) + if(1 == iStep && 3 == iSize) Success(gap8hwConv3x3(0)(in)(filter) !: e.t) + else if(1 == iStep && 5 == iSize) Success(gap8hwConv5x5(0)(in)(filter) !: e.t) + else if(1 == iStep && 7 == iSize) Success(gap8hwConv7x7(0)(in)(filter) !: e.t) else Failure(gap8hwConvMerge) case _ => Failure(gap8hwConvMerge) } From 075a164b65619f2a3f479eb5551d9db529fd2819 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 25 Oct 2021 17:29:08 +0200 Subject: [PATCH 28/86] Added test cases to hwce test suite --- src/test/scala/shine/GAP8/hwce.scala | 199 ++++++++++++++++++++++----- 1 file changed, 163 insertions(+), 36 deletions(-) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index a1ad30c92..591295337 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -1,7 +1,8 @@ package shine.GAP8 +import elevate.core.Strategy import rise.GAP8.DSL.{gap8Run, hwce} -import rise.GAP8.primitives.gap8hwConv3x3 +import rise.GAP8.primitives.{gap8RunPrimitive, gap8hwConv3x3, gap8hwConv5x5, gap8hwConv7x4, gap8hwConv7x7} import rise.core.DSL.HighLevelConstructs._ import rise.core.DSL.Type._ import rise.core.DSL._ @@ -9,51 +10,129 @@ import rise.core.primitives._ import rise.core.types.DataType._ import rise.core.types._ import rise.elevate.Rise +import rise.elevate.rules.algorithmic.gap8hwConvMerge +import rise.elevate.strategies.traversal._ import shine.GAP8 class hwce extends test_util.Tests { + val exprNoPipes: ToBeTyped[Rise] = { + fun((6`.`6`.`i16) ->: (3`.`3`.`i16) ->: ((6 - 2)`.`(6 - 2)`.`i16))((in, filter) => + gap8Run(8)( + mapSeq(mapSeq(fun(sub => { + reduceSeq(add)(li16(0))(map(fun(x => fst(x) * snd(x)))(zip(join(sub))(join(filter)))) + })))(slide2D(3, 1)(in)) + ) + ) + } + private def checkHwceCall(code: String, filterSize: String) = { assert( ("HWCE_ProcessOneTile" + filterSize).r.findAllIn(code).length >= 1 ) } - - - ignore("Minimal example") { + test("Optimization strategy 3x3") { val w: Nat = 6 val h: Nat = 6 - val fW: Nat = 3 - val fH: Nat = 3 /** + * TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) * HWCE_ProcessOneTile3x3_MultiOut(e1, output, NULL, NULL, e2, 0, n, m, 0x7) * */ - //TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) - val expr: ToBeTyped[Rise] = { - fun((w`.`h`.`i16) ->: (fW`.`fH`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => - in |> - slide2D(3, 1) |> - mapSeq(mapSeq(fun(sub => { - zip(sub |> join)(filter |> join) |> - map(fun(x => fst(x) * snd(x))) |> - reduceSeq(add)(li16(0)) - }))) + val exprOnAcc: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (3`.`3`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => + gap8Run(8)( + in |> + slide2D(3, 1) |> + mapSeq(mapSeq(fun(sub => { + zip(sub |> join)(filter |> join) |> + map(fun(x => fst(x) * snd(x))) |> + reduceSeq(add)(li16(0)) + }))) + ) ) } - println(util.gen.gap8.function("cluster_core_task").asStringFromExpr(expr)) + val conv: Strategy[Rise] = + (gap8hwConvMerge `@` everywhere) + + val lowExpr = conv(exprOnAcc).get + val module = util.gen.gap8.hosted.fromExpr(lowExpr) + val code = GAP8.Module.translateToString(module) + + checkHwceCall(code, "3x3") } - test("Minimal example 2") { - val w: Nat = 6 - val h: Nat = 6 + ignore("Optimization strategy 5x5") { + val w: Nat = 10 + val h: Nat = 10 + + /** + * HWCE_ProcessOneTile5x5(e1, output, e2, 0, n, m) + * */ + val exprOnAcc: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (5`.`5`.`i16) ->: ((w - 4)`.`(h - 4)`.`i16))((in, filter) => + gap8Run(8)( + in |> + slide2D(5, 1) |> + mapSeq(mapSeq(fun(sub => { + zip(sub |> join)(filter |> join) |> + map(fun(x => fst(x) * snd(x))) |> + reduceSeq(add)(li16(0)) + }))) + ) + ) + } + + val conv: Strategy[Rise] = + (gap8hwConvMerge `@` everywhere) + + val lowExpr = conv(exprOnAcc).get + val module = util.gen.gap8.hosted.fromExpr(lowExpr) + val code = GAP8.Module.translateToString(module) + + checkHwceCall(code, "5x5") + } + + ignore("Optimization strategy 7x7") { + val w: Nat = 10 + val h: Nat = 10 + + /** + * HWCE_ProcessOneTile7x7(e1, output, e2, 0, n, m) + * */ + val exprOnAcc: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (7`.`7`.`i16) ->: ((w - 6)`.`(h - 6)`.`i16))((in, filter) => + gap8Run(8)( + in |> + slide2D(7, 1) |> + mapSeq(mapSeq(fun(sub => { + zip(sub |> join)(filter |> join) |> + map(fun(x => fst(x) * snd(x))) |> + reduceSeq(add)(li16(0)) + }))) + ) + ) + } + + val conv: Strategy[Rise] = + (gap8hwConvMerge `@` everywhere) + + val lowExpr = conv(exprOnAcc).get + val module = util.gen.gap8.hosted.fromExpr(lowExpr) + val code = GAP8.Module.translateToString(module) + + checkHwceCall(code, "7x7") + } + + test("Direct use of gap8hwConv3x3") { + val w: Nat = 9 + val h: Nat = 9 /** * HWCE_ProcessOneTile3x3_MultiOut(e1, output, NULL, NULL, e2, 0, n, m, 0x7) * */ - //TODO: Pad filter with one 0 or do that in data prep step on backend (codegen) val expr: ToBeTyped[Rise] = { fun((w`.`h`.`i16) ->: (3`.`3`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => gap8Run(8)( @@ -62,28 +141,76 @@ class hwce extends test_util.Tests { ) } - //println(expr.toExpr) - //println(expr.toExpr.t) - val hostedModule = util.gen.gap8.hosted.fromExpr(expr) val code = GAP8.Module.translateToString(hostedModule) checkHwceCall(code, "3x3") + //println(code) + } + + ignore("Direct use of gap8hwConv5x5") { + val w: Nat = 10 + val h: Nat = 10 + + /** + * HWCE_ProcessOneTile5x5(e1, output, e2, 0, n, m) + * */ + val expr: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (5`.`5`.`i16) ->: ((w - 4)`.`(h - 4)`.`i16))((in, filter) => + gap8Run(8)( + gap8hwConv5x5(0)(in)(filter) + ) + ) + } - println(code) + val hostedModule = util.gen.gap8.hosted.fromExpr(expr) + val code = GAP8.Module.translateToString(hostedModule) + + checkHwceCall(code, "5x5") + //println(code) } - ignore("Hwce RISE primitive") { - val n: Nat = 6 - val m: Nat = 6 - val fW: Nat = 3 - val fH: Nat = 3 - val oW: Nat = 4 - val oH: Nat = 4 - - val expr: ToBeTyped[Rise] = - fun((n`.`m`.`i16) ->: (fW`.`fH`.`i16) ->: (oW`.`oH`.`i16))((in, filter) => - hwce()(in, filter) + ignore("Direct use of gap8hwConv7x7") { + val w: Nat = 10 + val h: Nat = 10 + + /** + * HWCE_ProcessOneTile7x7(e1, output, e2, 0, n, m) + * */ + val expr: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (7`.`7`.`i16) ->: ((w - 6)`.`(h - 6)`.`i16))((in, filter) => + gap8Run(8)( + gap8hwConv7x7(0)(in)(filter) + ) ) + } + + val hostedModule = util.gen.gap8.hosted.fromExpr(expr) + val code = GAP8.Module.translateToString(hostedModule) + + checkHwceCall(code, "7x7") + //println(code) + } + + ignore("Direct use of gap8hwConv7x4") { + val w: Nat = 10 + val h: Nat = 10 + + /** + * HWCE_ProcessOneTile7x4(e1, output, e2, 0, n, m) + * */ + val expr: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (7`.`4`.`i16) ->: ((w - 6)`.`(h - 3)`.`i16))((in, filter) => + gap8Run(8)( + gap8hwConv7x4(0)(in)(filter) + ) + ) + } + + val hostedModule = util.gen.gap8.hosted.fromExpr(expr) + val code = GAP8.Module.translateToString(hostedModule) + + checkHwceCall(code, "7x4") + //println(code) } } From b72ae8efccc1e0943fe8e6cb13c4b875bf214793 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 25 Oct 2021 21:22:38 +0200 Subject: [PATCH 29/86] Flipped output matrix dimensions --- .../rise/GAP8/primitives/gap8hwConv3x3.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv5x5.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv7x4.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv7x7.scala | 2 +- .../scala/rise/GAP8/primitives/primitives.rise | 8 ++++---- .../GAP8/primitives/functional/FunConv3x3.scala | 4 ++-- .../GAP8/primitives/functional/FunConv5x5.scala | 4 ++-- .../GAP8/primitives/functional/FunConv7x4.scala | 4 ++-- .../GAP8/primitives/functional/FunConv7x7.scala | 4 ++-- .../GAP8/primitives/functional/primitives.dpia | 16 ++++++++-------- .../GAP8/primitives/imperative/Conv3x3.scala | 4 ++-- .../GAP8/primitives/imperative/Conv5x5.scala | 4 ++-- .../GAP8/primitives/imperative/Conv7x4.scala | 4 ++-- .../GAP8/primitives/imperative/Conv7x7.scala | 4 ++-- .../GAP8/primitives/imperative/primitives.dpia | 16 ++++++++-------- 15 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala index 18b81a8cf..fec7815c8 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala @@ -13,7 +13,7 @@ object gap8hwConv3x3 extends Builder { override val name: String = "gap8hwConv3x3" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(3, ArrayType(3, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(3, ArrayType(3, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } } override def toString: String = "gap8hwConv3x3" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala index 9b01d7041..b4884472b 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala @@ -13,7 +13,7 @@ object gap8hwConv5x5 extends Builder { override val name: String = "gap8hwConv5x5" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(5, ArrayType(5, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(5, ArrayType(5, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } } override def toString: String = "gap8hwConv5x5" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala index 9506e2f1e..e4280176b 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala @@ -13,7 +13,7 @@ object gap8hwConv7x4 extends Builder { override val name: String = "gap8hwConv7x4" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(7, ArrayType(4, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(7, ArrayType(4, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } } override def toString: String = "gap8hwConv7x4" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala index f0e830766..7b42053e6 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala @@ -13,7 +13,7 @@ object gap8hwConv7x7 extends Builder { override val name: String = "gap8hwConv7x7" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(7, ArrayType(7, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(7, ArrayType(7, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } } override def toString: String = "gap8hwConv7x7" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 56fe120ad..4d47a62cf 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -3,19 +3,19 @@ def gap8RunPrimitive: (cores: nat) -> {t: data} -> t -> t def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> {ow: nat} -> {oh: nat} -> {s: data} -> - ih.iw.s -> 3.3.s -> oh.ow.s + iw.ih.s -> 3.3.s -> ow.oh.s def gap8hwConv5x5: (bias: nat) -> {iw: nat} -> {ih: nat} -> {ow: nat} -> {oh: nat} -> {s: data} -> - ih.iw.s -> 5.5.s -> oh.ow.s + iw.ih.s -> 5.5.s -> ow.oh.s def gap8hwConv7x7: (bias: nat) -> {iw: nat} -> {ih: nat} -> {ow: nat} -> {oh: nat} -> {s: data} -> - ih.iw.s -> 7.7.s -> oh.ow.s + iw.ih.s -> 7.7.s -> ow.oh.s def gap8hwConv7x4: (bias: nat) -> {iw: nat} -> {ih: nat} -> {ow: nat} -> {oh: nat} -> {s: data} -> - ih.iw.s -> 7.4.s -> oh.ow.s \ No newline at end of file + iw.ih.s -> 7.4.s -> ow.oh.s \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala index 4048bba72..8df7ff9c8 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(3, ArrayType(3, dt)), read) true } - override val t: ExpType = expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) + override val t: ExpType = expT(ArrayType(w - 2, ArrayType(h - 2, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv3x3 = new FunConv3x3(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala index 2e9c719fe..f8952e35b 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(5, ArrayType(5, dt)), read) true } - override val t: ExpType = expT(ArrayType(h - 4, ArrayType(w - 4, dt)), write) + override val t: ExpType = expT(ArrayType(w - 4, ArrayType(h - 4, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv5x5 = new FunConv5x5(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala index c0e58a236..7cb40a040 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(7, ArrayType(4, dt)), read) true } - override val t: ExpType = expT(ArrayType(h - 3, ArrayType(w - 6, dt)), write) + override val t: ExpType = expT(ArrayType(w - 6, ArrayType(h - 3, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x4 = new FunConv7x4(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala index b50c33b8b..b9def4e85 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(7, ArrayType(7, dt)), read) true } - override val t: ExpType = expT(ArrayType(h - 6, ArrayType(w - 6, dt)), write) + override val t: ExpType = expT(ArrayType(w - 6, ArrayType(h - 6, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x7 = new FunConv7x7(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index 82a782535..2eeef8639 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -7,33 +7,33 @@ def funConv3x3( h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[3.3.dt, read] -): exp[(h-2).(w-2).dt, write] +): exp[(w-2).(h-2).dt, write] def funConv5x5( w: nat, h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[5.5.dt, read] -): exp[(h-4).(w-4).dt, write] +): exp[(w-4).(h-4).dt, write] def funConv7x7( w: nat, h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[7.7.dt, read] -): exp[(h-6).(w-6).dt, write] +): exp[(w-6).(h-6).dt, write] def funConv7x4( w: nat, h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[7.4.dt, read] -): exp[(h-3).(w-6).dt, write] \ No newline at end of file +): exp[(w-6).(h-3).dt, write] \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala index 294121c87..e43cffeba 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(10, dt), read) - out :: accT(ArrayType(h - 2, ArrayType(w - 2, dt))) + out :: accT(ArrayType(w - 2, ArrayType(h - 2, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala index abd4f582f..88706fe8b 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(26, dt), read) - out :: accT(ArrayType(h - 4, ArrayType(w - 4, dt))) + out :: accT(ArrayType(w - 4, ArrayType(h - 4, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala index 2fc925825..f8702b79d 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(28, dt), read) - out :: accT(ArrayType(h - 3, ArrayType(w - 6, dt))) + out :: accT(ArrayType(w - 6, ArrayType(h - 3, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala index 3073fad9f..39d96b18a 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(h, ArrayType(w, dt)), read) + in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(56, dt), read) - out :: accT(ArrayType(h - 6, ArrayType(w - 6, dt))) + out :: accT(ArrayType(w - 6, ArrayType(h - 6, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index b52605f94..ffc15bbd5 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -5,30 +5,30 @@ def conv3x3(w: nat, h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[10.dt, read], - out: acc[(h-2).(w-2).dt]): comm + out: acc[(w-2).(h-2).dt]): comm def conv5x5(w: nat, h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[26.dt, read], - out: acc[(h-4).(w-4).dt]): comm + out: acc[(w-4).(h-4).dt]): comm def conv7x7(w: nat, h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[56.dt, read], - out: acc[(h-6).(w-6).dt]): comm + out: acc[(w-6).(h-6).dt]): comm def conv7x4(w: nat, h: nat, bias: nat, dt: data, - in: exp[h.w.dt, read], + in: exp[w.h.dt, read], filter: exp[28.dt, read], - out: acc[(h-3).(w-6).dt]): comm + out: acc[(w-6).(h-3).dt]): comm From 554cd434cc028aa0041c6f3c8fc1a3aee3b57558 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 25 Oct 2021 21:24:01 +0200 Subject: [PATCH 30/86] Added rest of the HWCE primitives; Minor refactor --- .../shine/DPIA/InferAccessAnnotation.scala | 32 ++++++++++++- src/main/scala/shine/DPIA/fromRise.scala | 47 +++++++++++++++++-- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index 5b353c3dc..06639c999 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -8,6 +8,7 @@ import rise.core.DSL.Type.{->:, ArrayTypeConstructors, TupleTypeConstructors, `( import rise.openMP.{primitives => rompp} import rise.openCL.{primitives => roclp} import rise.Cuda.{primitives => rocup} +import rise.GAP8.{primitives => rg8p} import shine.DPIA.Types._ import shine.DPIA.Types.TypeCheck.SubTypeCheckHelper import shine.DPIA.fromRise._ @@ -597,7 +598,7 @@ private class InferAccessAnnotation { (expT(dt, read) ->: expT(dt, write)) ->: expT(fragType, read) ->: expT(fragType, write) } - case rise.GAP8.primitives.gap8RunPrimitive() => p.t match { + case rg8p.gap8RunPrimitive() => p.t match { case cores `(Nat)->:` ((t: rt.DataType) ->: (_: rt.DataType)) => nFunT(cores, expT(t, write) ->: expT(t, write)) case _ => error() @@ -621,7 +622,7 @@ private class InferAccessAnnotation { ) }*/ - case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { + case rg8p.gap8hwConv3x3() => p.t match { case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) @@ -629,6 +630,33 @@ private class InferAccessAnnotation { expT(ArrayType(oh, ArrayType(ow, s)), write) ) } + + case rg8p.gap8hwConv5x5() => p.t match { + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) + ->: expT(ArrayType(5, ArrayType(5, s)), read) ->: + expT(ArrayType(oh, ArrayType(ow, s)), write) + ) + } + + case rg8p.gap8hwConv7x7() => p.t match { + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) + ->: expT(ArrayType(7, ArrayType(7, s)), read) ->: + expT(ArrayType(oh, ArrayType(ow, s)), write) + ) + } + + case rg8p.gap8hwConv7x4() => p.t match { + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) + ->: expT(ArrayType(7, ArrayType(4, s)), read) ->: + expT(ArrayType(oh, ArrayType(ow, s)), write) + ) + } } checkConsistency(p.t, primitiveType) diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index b93262124..1e5198f0a 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -101,9 +101,11 @@ object fromRise { import rise.openCL.{primitives => rocl} import rise.openMP.{primitives => romp} import rise.Cuda.{primitives => rcuda} + import rise.GAP8.{primitives => rgap8} import shine.OpenCL.primitives.{functional => ocl} import shine.OpenMP.primitives.{functional => omp} import shine.cuda.primitives.{functional => cuda} + import shine.GAP8.primitives.{functional => gap8} import shine.DPIA.Types.MatchingDSL._ import shine.OpenCL.{Global, Warp, WorkGroup, Lane, Local} @@ -921,7 +923,7 @@ object fromRise { case core.reduce() => throw new Exception(s"$p has no implementation") - case rise.GAP8.primitives.gap8RunPrimitive() => fromType { + case rgap8.gap8RunPrimitive() => fromType { case nFunT(cores, expT(t, `write`) ->: _) => depFun(NatKind, cores)(fun[ExpType](expT(t, write), e => shine.GAP8.primitives.functional.Run(cores)(t, e) @@ -943,19 +945,58 @@ object fromRise { ) }*/ - case rise.GAP8.primitives.gap8hwConv3x3() => fromType { + case rgap8.gap8hwConv3x3() => fromType { case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: expT(ArrayType(_, ArrayType(_, _)), `read`) ->: expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => depFun(NatKind, bias)( fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => fun[ExpType](expT(ArrayType(3, ArrayType(3, s)), read), filter => - shine.GAP8.primitives.functional.FunConv3x3(w, h, bias, s, input, filter) + gap8.FunConv3x3(w, h, bias, s, input, filter) ) ) ) } + case rgap8.gap8hwConv5x5() => fromType { + case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + expT(ArrayType(_, ArrayType(_, _)), `read`) ->: + expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + depFun(NatKind, bias)( + fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => + fun[ExpType](expT(ArrayType(5, ArrayType(5, s)), read), filter => + gap8.FunConv5x5(w, h, bias, s, input, filter) + ) + ) + ) + } + + case rgap8.gap8hwConv7x7() => fromType { + case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + expT(ArrayType(_, ArrayType(_, _)), `read`) ->: + expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + depFun(NatKind, bias)( + fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => + fun[ExpType](expT(ArrayType(7, ArrayType(7, s)), read), filter => + gap8.FunConv7x7(w, h, bias, s, input, filter) + ) + ) + ) + } + + case rgap8.gap8hwConv7x4() => fromType { + case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + expT(ArrayType(_, ArrayType(_, _)), `read`) ->: + expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + depFun(NatKind, bias)( + fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => + fun[ExpType](expT(ArrayType(7, ArrayType(4, s)), read), filter => + gap8.FunConv7x4(w, h, bias, s, input, filter) + ) + ) + ) + } + case _ => throw new Exception(s"Missing rule for $p") } From a5cf5f33a1fa7f445ebf267f9786be634c9df957 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 25 Oct 2021 21:25:14 +0200 Subject: [PATCH 31/86] Added support for HWCE primitives (other than 3x3); Minor refactor --- .../AcceleratorCodeGenerator.scala | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 4e46a4a18..85311b96e 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -2,6 +2,7 @@ package shine.GAP8.Compilation import arithexpr.arithmetic import arithexpr.arithmetic.ArithExpr +import rise.core.types.DataType import rise.core.types.DataType.ArrayType import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} import shine.DPIA.Nat @@ -22,42 +23,55 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def translationContext: TranslationContext = super.translationContext + private def swapEnvIdentifier( + identifier: shine.DPIA.Phrases.Identifier[ExpType], + dt: DataType, + env: Environment, + height: Nat, + width: Nat + ): Environment = { + val oldFilterId = shine.DPIA.Phrases.Identifier(identifier.name, + ExpType(ArrayType(height, ArrayType(width, dt)), rise.core.types.read)) + val ref = env.identEnv(oldFilterId) + val identEnv = env.identEnv - oldFilterId + CodeGenerator.Environment(identEnv + ((identifier, ref)), + env.commEnv, env.contEnv, env.letNatEnv) + } + override def cmd(env: Environment): Phrase[CommType] => Stmt = { //TODO: Supoort multicycle output for 3x3 case Conv3x3(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - val oldFilterId = shine.DPIA.Phrases.Identifier(filter.name, - ExpType(ArrayType(3, ArrayType(3, dt)), rise.core.types.read)) - val ref = env.identEnv(oldFilterId) - val identEnv = env.identEnv - oldFilterId - val env2 = CodeGenerator.Environment(identEnv + ((filter, ref)), - env.commEnv, env.contEnv, env.letNatEnv) + val env2 = swapEnvIdentifier(filter, dt, env, 3, 3) filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._3x3, w, h, bias, inC, filterC, outputC) }) }) }) - case Conv5x5(w, h, bias, dt, in, filter, out) => + case Conv5x5(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + val env2 = swapEnvIdentifier(filter, dt, env, 5, 5) + filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._5x5, w, h, bias, inC, filterC, outputC) }) }) }) - case Conv7x7(w, h, bias, dt, in, filter, out) => + case Conv7x7(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + val env2 = swapEnvIdentifier(filter, dt, env, 7, 7) + filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._7x7, w, h, bias, inC, filterC, outputC) }) }) }) - case Conv7x4(w, h, bias, dt, in, filter, out) => + case Conv7x4(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - filter |> exp(env, Nil, (filterC: C.AST.Expr) => { + val env2 = swapEnvIdentifier(filter, dt, env, 7, 4) + filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._7x4, w, h, bias, inC, filterC, outputC) }) }) From 24defe8b9d069767f8c692c647c1ab0fbba6274a Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 25 Oct 2021 21:26:58 +0200 Subject: [PATCH 32/86] hwce tests ignore -> test --- src/test/scala/shine/GAP8/hwce.scala | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 591295337..bce380362 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -1,8 +1,8 @@ package shine.GAP8 import elevate.core.Strategy -import rise.GAP8.DSL.{gap8Run, hwce} -import rise.GAP8.primitives.{gap8RunPrimitive, gap8hwConv3x3, gap8hwConv5x5, gap8hwConv7x4, gap8hwConv7x7} +import rise.GAP8.DSL.gap8Run +import rise.GAP8.primitives.{gap8hwConv3x3, gap8hwConv5x5, gap8hwConv7x4, gap8hwConv7x7} import rise.core.DSL.HighLevelConstructs._ import rise.core.DSL.Type._ import rise.core.DSL._ @@ -64,7 +64,7 @@ class hwce extends test_util.Tests { checkHwceCall(code, "3x3") } - ignore("Optimization strategy 5x5") { + test("Optimization strategy 5x5") { val w: Nat = 10 val h: Nat = 10 @@ -95,7 +95,7 @@ class hwce extends test_util.Tests { checkHwceCall(code, "5x5") } - ignore("Optimization strategy 7x7") { + test("Optimization strategy 7x7") { val w: Nat = 10 val h: Nat = 10 @@ -148,7 +148,7 @@ class hwce extends test_util.Tests { //println(code) } - ignore("Direct use of gap8hwConv5x5") { + test("Direct use of gap8hwConv5x5") { val w: Nat = 10 val h: Nat = 10 @@ -170,7 +170,7 @@ class hwce extends test_util.Tests { //println(code) } - ignore("Direct use of gap8hwConv7x7") { + test("Direct use of gap8hwConv7x7") { val w: Nat = 10 val h: Nat = 10 @@ -192,7 +192,7 @@ class hwce extends test_util.Tests { //println(code) } - ignore("Direct use of gap8hwConv7x4") { + test("Direct use of gap8hwConv7x4") { val w: Nat = 10 val h: Nat = 10 From afb1e20bce54d2efd8a528a7d8622cfd836f8574 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 29 Oct 2021 15:44:19 +0200 Subject: [PATCH 33/86] mapSeq -> mapPar; Removed transpose from KMeans test --- src/test/scala/shine/GAP8/codegen.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/test/scala/shine/GAP8/codegen.scala b/src/test/scala/shine/GAP8/codegen.scala index dc81ac230..872c113ea 100644 --- a/src/test/scala/shine/GAP8/codegen.scala +++ b/src/test/scala/shine/GAP8/codegen.scala @@ -9,6 +9,7 @@ import rise.core.primitives._ import rise.core.types.DataType._ import rise.core.types._ import rise.elevate.Rise +import rise.openMP.primitives.mapPar import shine.GAP8 // scalastyle:off @@ -77,8 +78,8 @@ class codegen extends test_util.Tests { val expr: ToBeTyped[Expr] = depFun((n: Nat, m: Nat, o: Nat) => fun((n`.`o`.`u32) ->: (o`.`m`.`u32) ->: (n`.`m`.`u32))((a, b) => gap8Run(8)( - a |> mapSeq(fun(rowa => - b |> transpose |> mapSeq(fun(colb => + a |> mapPar(fun(rowa => + b |> transpose |> mapPar(fun(colb => zip(rowa)(colb) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(cast(l(0)) :: u32) )) )) @@ -103,7 +104,7 @@ class codegen extends test_util.Tests { pic |> padCst2D(1, 1)(cast(l(0)) :: u8) |> slide2D(sz = 3, st = 1) |> - mapSeq(mapSeq(fun(submat => { + mapPar(mapPar(fun(submat => { zip(submat |> join)(h_w |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeqUnroll(add)(cast(l(0)) :: u32) |> letf(h => zip(submat |> join)(v_w |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeqUnroll(add)(cast(l(0)) :: u32) |> letf(v => cast(apps.SobelFilter.gapSqrt(h * h + v * v)) :: u8 @@ -155,9 +156,9 @@ class codegen extends test_util.Tests { // from lift.highLevel.kmeans clustersType = ArrayType(ArrayType(Float, F), C) // clusters matrix C X F val expr: ToBeTyped[Rise] = depFun((p: Nat, c: Nat, f: Nat) => - fun((f`.`p`.`u32) ->: (c`.`f`.`u32) ->: (p`.`u32))((features, clusters) => + fun((p`.`f`.`u32) ->: (c`.`f`.`u32) ->: (p`.`u32))((features, clusters) => gap8Run(8)( - features |> transpose |> mapSeq(fun(feature => + features |> mapPar(fun(feature => clusters |> reduceSeq(fun(tuple => fun(cluster => { val dist = zip(feature)(cluster) |> reduceSeq(update)(cast(l(0)) :: u32) testF(dist)(tuple) From 5a2b2acc8a6273d011b4bfe2db049db674b018f7 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 29 Oct 2021 15:49:59 +0200 Subject: [PATCH 34/86] Added sobel filter + hwce test (currently ignored) --- src/test/scala/shine/GAP8/hwce.scala | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index bce380362..7d2f0bf9e 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -32,6 +32,42 @@ class hwce extends test_util.Tests { ) } + ignore("Sobel filter utilizes HWCE") { + val expr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => + fun((n`.`m`.`i16) ->: (3`.`3`.`i16) ->: (3`.`3`.`i16) ->: (n`.`m`.`i16))((pic, h_w, v_w) => + gap8Run(8)( + pic |> + padCst2D(1, 1)(cast(l(0)) :: i16) |> + slide2D(sz = 3, st = 1) |> + mapSeq(mapSeq(fun(submat => { + zip(submat |> join)(h_w |> join) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(li16(0)) |> letf(h => + zip(submat |> join)(v_w |> join) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(li16(0)) |> letf(v => { + cast(apps.SobelFilter.gapSqrt(cast(h * h + v * v) :: u32)) :: i16 + }) + ) + } + ))) + ) + ) + ) + + val conv: Strategy[Rise] = + (gap8hwConvMerge `@` everywhere) + + val lowExpr = conv(expr).get + val module = util.gen.gap8.hosted.fromExpr(lowExpr) + val code = GAP8.Module.translateToString(module) + + + //println(expr.toExpr) + //println(exprNoPipes.toExpr) + //println(lowExpr) + + //println(code) + + //checkHwceCall(code, "3x3") + } + test("Optimization strategy 3x3") { val w: Nat = 6 val h: Nat = 6 From 7e2921106ada0c29ed7bc28e78eed06b4c39013e Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 29 Oct 2021 15:53:08 +0200 Subject: [PATCH 35/86] Added convolution 3x3 test --- src/test/scala/shine/GAP8/codegen.scala | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/scala/shine/GAP8/codegen.scala b/src/test/scala/shine/GAP8/codegen.scala index 872c113ea..491ae7db2 100644 --- a/src/test/scala/shine/GAP8/codegen.scala +++ b/src/test/scala/shine/GAP8/codegen.scala @@ -179,4 +179,31 @@ class codegen extends test_util.Tests { findParamsStruct("int", 3, code) //println(code) } + + test("Convolution 3x3") { + val w: Nat = 12 + val h: Nat = 12 + val expr: ToBeTyped[Rise] = { + fun((w`.`h`.`i16) ->: (3`.`3`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => + gap8Run(8)( + in |> + slide2D(3, 1) |> + mapPar(mapPar(fun(sub => { + zip(sub |> join)(filter |> join) |> + map(fun(x => fst(x) * snd(x))) |> + reduceSeq(add)(li16(0)) + }))) + ) + ) + + } + + val module = util.gen.gap8.hosted.fromExpr(expr) + val code = GAP8.Module.translateToString(module) + + findDeviceBufferSync(3, code) + checkCoreNumber(8, code) + findParamsStruct("int16_t*", 3, code) + println(code) + } } From b3afce4400942a9e21ede9151c577180c44ffd09 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 29 Oct 2021 16:13:32 +0200 Subject: [PATCH 36/86] Minor test refactors --- src/test/scala/shine/GAP8/codegen.scala | 23 +++++++++++------------ src/test/scala/shine/GAP8/hwce.scala | 3 +++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/test/scala/shine/GAP8/codegen.scala b/src/test/scala/shine/GAP8/codegen.scala index 491ae7db2..bf859ab75 100644 --- a/src/test/scala/shine/GAP8/codegen.scala +++ b/src/test/scala/shine/GAP8/codegen.scala @@ -181,21 +181,20 @@ class codegen extends test_util.Tests { } test("Convolution 3x3") { - val w: Nat = 12 - val h: Nat = 12 val expr: ToBeTyped[Rise] = { - fun((w`.`h`.`i16) ->: (3`.`3`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => - gap8Run(8)( - in |> - slide2D(3, 1) |> - mapPar(mapPar(fun(sub => { - zip(sub |> join)(filter |> join) |> - map(fun(x => fst(x) * snd(x))) |> - reduceSeq(add)(li16(0)) - }))) + depFun((w:Nat, h: Nat) => + fun((w`.`h`.`i16) ->: (3`.`3`.`i16) ->: ((w - 2)`.`(h - 2)`.`i16))((in, filter) => + gap8Run(8)( + in |> + slide2D(3, 1) |> + mapPar(mapPar(fun(sub => { + zip(sub |> join)(filter |> join) |> + map(fun(x => fst(x) * snd(x))) |> + reduceSeq(add)(li16(0)) + }))) + ) ) ) - } val module = util.gen.gap8.hosted.fromExpr(expr) diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index 7d2f0bf9e..acb80eaaf 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -14,6 +14,9 @@ import rise.elevate.rules.algorithmic.gap8hwConvMerge import rise.elevate.strategies.traversal._ import shine.GAP8 +/** + * HWCE constraint: W has to be even + * */ class hwce extends test_util.Tests { val exprNoPipes: ToBeTyped[Rise] = { From 494aaaaf78527ec7595afca6b5611c328b180269 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 29 Oct 2021 16:26:16 +0200 Subject: [PATCH 37/86] C/P #218 --- .../GAP8/Compilation/SeparateHostAndAcceleratorCode.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/scala/shine/GAP8/Compilation/SeparateHostAndAcceleratorCode.scala b/src/main/scala/shine/GAP8/Compilation/SeparateHostAndAcceleratorCode.scala index a3978bd34..96170f233 100644 --- a/src/main/scala/shine/GAP8/Compilation/SeparateHostAndAcceleratorCode.scala +++ b/src/main/scala/shine/GAP8/Compilation/SeparateHostAndAcceleratorCode.scala @@ -2,7 +2,7 @@ package shine.GAP8.Compilation import arithexpr.arithmetic.ArithExpr.toInt import arithexpr.arithmetic.NamedVar -import rise.core.types.{DataKind, DataType, NatIdentifier, NatKind} +import rise.core.types.{DataKind, DataType, NatIdentifier, NatKind, NatToNat, NatToNatLambda} import rise.core.types.DataType._ import shine.DPIA.Compilation.FunDef import shine.DPIA.Phrases._ @@ -109,6 +109,12 @@ object SeparateHostAndAcceleratorCode { case _ => Continue(p, this) } + override def natToNat(ft: NatToNat): NatToNat = ft match { + case NatToNatLambda(x, b) => + NatToNatLambda(x, this.copy(boundN = boundN + x).nat(b)) + case _ => super.natToNat(ft) + } + override def nat[N <: Nat](n: N): N = { natIdents ++= n.varList.collect { case v: NamedVar if !boundN(v) => v From de1247bd2a08c47b755ce7ba17464cafa31ba971 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 8 Jun 2022 21:42:21 +0200 Subject: [PATCH 38/86] Minor cleanup --- src/main/scala/rise/GAP8/DSL.scala | 1 - .../shine/DPIA/InferAccessAnnotation.scala | 18 ------------------ src/main/scala/shine/DPIA/fromRise.scala | 15 --------------- 3 files changed, 34 deletions(-) diff --git a/src/main/scala/rise/GAP8/DSL.scala b/src/main/scala/rise/GAP8/DSL.scala index f72326d16..0c99f6f1f 100644 --- a/src/main/scala/rise/GAP8/DSL.scala +++ b/src/main/scala/rise/GAP8/DSL.scala @@ -6,5 +6,4 @@ import shine.DPIA.Nat object DSL { def gap8Run(cores: Nat): ToBeTyped[Expr] = primitives.gap8RunPrimitive(cores) - def hwce(): ToBeTyped[Expr] = ??? } diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index ea4883887..e1b1164f5 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -603,24 +603,6 @@ private class InferAccessAnnotation { case _ => error() } - /*case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { - case bias `(Nat)->:` ((rt.ArrayType(h, rt.ArrayType(w, s: rt.DataType))) ->: - (rt.ArrayType(fh, rt.ArrayType(fw, _))) ->: rt.ArrayType(oh, rt.ArrayType(ow, _))) => - nFunT(bias, expT(ArrayType(h, ArrayType(w, dataType(s))), read) - ->: expT(ArrayType(fh, ArrayType(fw, dataType(s))), read) ->: - expT(ArrayType(oh, ArrayType(ow, dataType(s))), write) - ) - }*/ - - /*case rise.GAP8.primitives.gap8hwConv3x3() => p.t match { - case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: - ArrayType(oh, ArrayType(ow, _))) => - nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) - ->: expT(ArrayType(3, ArrayType(3, s)), read) ->: - expT(ArrayType(oh, ArrayType(ow, s)), write) - ) - }*/ - case rg8p.gap8hwConv3x3() => p.t match { case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index 0476cd64e..972381e28 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -929,21 +929,6 @@ object fromRise { )) } - /*case rise.GAP8.primitives.gap8hwConv3x3() => fromType { - case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: - expT(ArrayType(fh, ArrayType(fw, _)), `read`) ->: - //TODO: fix mismatch (whatever that means) - //TODO: Previous comment maybe related to 3.3 -> 10 matrix / array sizes - expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => - depFun(NatKind, bias)( - fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => - fun[ExpType](expT(ArrayType(fh, ArrayType(fw, s)), read), filter => - shine.GAP8.primitives.functional.FunConv3x3(shine.GAP8._3x3)(w, h, bias, s, input, filter) - ) - ) - ) - }*/ - case rgap8.gap8hwConv3x3() => fromType { case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: expT(ArrayType(_, ArrayType(_, _)), `read`) ->: From e6119f07deb214b03539c4add6a4e119c13dc3ab Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 12 Jul 2022 11:35:58 +0100 Subject: [PATCH 39/86] Uncommented syntax checking step for gap8 function generation; Commented out code print in test --- src/main/scala/util/gen.scala | 4 ++-- src/test/scala/shine/GAP8/codegen.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/util/gen.scala b/src/main/scala/util/gen.scala index da5209c46..d8ec4e69d 100644 --- a/src/main/scala/util/gen.scala +++ b/src/main/scala/util/gen.scala @@ -120,8 +120,8 @@ object gen { ): Expr => String = functionFromExpr(name, gen) andThen GAP8.Module.injectUnpacking andThen - C.Module.translateToString// andThen - //run(SyntaxChecker(_)) + C.Module.translateToString andThen + run(SyntaxChecker(_)) } type HostedModule = GAP8.Module diff --git a/src/test/scala/shine/GAP8/codegen.scala b/src/test/scala/shine/GAP8/codegen.scala index bf859ab75..81331055a 100644 --- a/src/test/scala/shine/GAP8/codegen.scala +++ b/src/test/scala/shine/GAP8/codegen.scala @@ -203,6 +203,6 @@ class codegen extends test_util.Tests { findDeviceBufferSync(3, code) checkCoreNumber(8, code) findParamsStruct("int16_t*", 3, code) - println(code) + //println(code) } } From 54d6cbc5c05a885c002290a9aad2f41f5623f543 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 12 Jul 2022 11:39:49 +0100 Subject: [PATCH 40/86] Added comment hinting future syntax checking of GAP8 code --- src/main/scala/util/gen.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/scala/util/gen.scala b/src/main/scala/util/gen.scala index d8ec4e69d..84c3e6ea4 100644 --- a/src/main/scala/util/gen.scala +++ b/src/main/scala/util/gen.scala @@ -114,6 +114,8 @@ object gen { /** * Accelerator function only - Injects unpacking code + * + * TODO: Introduce appropriate syntax checking for GAP8 application code (not only for accelerator function) * */ private def functionAsStringFromExpr(name: String = "foo", gen: CCodeGenerator = CCodeGenerator() From b573b3ee4abed276114f30c0bcf442342980cf5d Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 25 Apr 2023 11:06:20 +0200 Subject: [PATCH 41/86] Added DMA transfer-supporting primitives for GAP8 --- .../scala/rise/GAP8/primitives/copyToL1.scala | 25 +++++++++++++++++++ .../scala/rise/GAP8/primitives/copyToL2.scala | 25 +++++++++++++++++++ .../rise/GAP8/primitives/primitives.rise | 5 +++- .../GAP8/primitives/functional/CopyToL1.scala | 19 ++++++++++++++ .../GAP8/primitives/functional/CopyToL2.scala | 19 ++++++++++++++ .../primitives/functional/primitives.dpia | 5 +++- .../GAP8/primitives/imperative/DmaCopy.scala | 21 ++++++++++++++++ .../primitives/imperative/MemoryAlloc.scala | 20 +++++++++++++++ .../primitives/imperative/primitives.dpia | 13 ++++++++++ 9 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 src/main/scala/rise/GAP8/primitives/copyToL1.scala create mode 100644 src/main/scala/rise/GAP8/primitives/copyToL2.scala create mode 100644 src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala create mode 100644 src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/MemoryAlloc.scala diff --git a/src/main/scala/rise/GAP8/primitives/copyToL1.scala b/src/main/scala/rise/GAP8/primitives/copyToL1.scala new file mode 100644 index 000000000..60a25ec57 --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/copyToL1.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object copyToL1 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "copyToL1" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = impl { (t: DataType) => t ->: t } + } + override def toString: String = "copyToL1" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/copyToL2.scala b/src/main/scala/rise/GAP8/primitives/copyToL2.scala new file mode 100644 index 000000000..3323c0573 --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/copyToL2.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object copyToL2 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "copyToL2" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = impl { (t: DataType) => t ->: t } + } + override def toString: String = "copyToL2" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 4d47a62cf..1b2f596ec 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -18,4 +18,7 @@ def gap8hwConv7x7: (bias: nat) -> {iw: nat} -> {ih: nat} -> def gap8hwConv7x4: (bias: nat) -> {iw: nat} -> {ih: nat} -> {ow: nat} -> {oh: nat} -> {s: data} -> - iw.ih.s -> 7.4.s -> ow.oh.s \ No newline at end of file + iw.ih.s -> 7.4.s -> ow.oh.s + +def copyToL1: {t: data} -> t -> t +def copyToL2: {t: data} -> t -> t \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala b/src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala new file mode 100644 index 000000000..463174574 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala @@ -0,0 +1,19 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class CopyToL1(val dt: DataType, val input: Phrase[ExpType]) extends ExpPrimitive { + assert { + input :: expT(dt, write) + true + } + override val t: ExpType = expT(dt, read) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): CopyToL1 = new CopyToL1(v.data(dt), VisitAndRebuild(input, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala b/src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala new file mode 100644 index 000000000..c27397e94 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala @@ -0,0 +1,19 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class CopyToL2(val dt: DataType, val input: Phrase[ExpType]) extends ExpPrimitive { + assert { + input :: expT(dt, write) + true + } + override val t: ExpType = expT(dt, read) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): CopyToL2 = new CopyToL2(v.data(dt), VisitAndRebuild(input, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index 2eeef8639..310d44a45 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -36,4 +36,7 @@ def funConv7x4( dt: data, in: exp[w.h.dt, read], filter: exp[7.4.dt, read] -): exp[(w-6).(h-3).dt, write] \ No newline at end of file +): exp[(w-6).(h-3).dt, write] + +def copyToL1(dt: data, input: exp[dt, write]): exp[dt, read] +def copyToL2(dt: data, input: exp[dt, write]): exp[dt, read] \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala b/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala new file mode 100644 index 000000000..4252da365 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala @@ -0,0 +1,21 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class DmaCopy(tt: shine.GAP8.DMATransferType)(val dt: DataType, val src: Phrase[ExpType], val dst: Phrase[AccType]) extends CommandPrimitive { + assert { + src :: expT(dt, read) + dst :: accT(dt) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): DmaCopy = new DmaCopy(tt)(v.data(dt), VisitAndRebuild(src, v), VisitAndRebuild(dst, v)) + def unwrap: (DataType, Phrase[ExpType], Phrase[AccType]) = (dt, src, dst) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/MemoryAlloc.scala b/src/main/scala/shine/GAP8/primitives/imperative/MemoryAlloc.scala new file mode 100644 index 000000000..7d40909e8 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/MemoryAlloc.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class MemoryAlloc(mt: shine.GAP8.MemoryType)(val dt: DataType, val f: Phrase[FunType[PhrasePairType[ExpType, AccType], CommType]]) extends CommandPrimitive { + assert { + f :: FunType(PhrasePairType(expT(dt, read), accT(dt)), comm) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): MemoryAlloc = new MemoryAlloc(mt)(v.data(dt), VisitAndRebuild(f, v)) + def unwrap: (DataType, Phrase[FunType[PhrasePairType[ExpType, AccType], CommType]]) = (dt, f) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index ffc15bbd5..ae4cde21e 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -32,3 +32,16 @@ def conv7x4(w: nat, in: exp[w.h.dt, read], filter: exp[28.dt, read], out: acc[(w-6).(h-3).dt]): comm + + +//def dmaCopy{a: shine.GAP8.MemoryType}(dt: data): comm + +def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, read], dst: acc[dt]): comm +//def memoryAlloc{mt: shine.GAP8.MemoryType}(size: nat, dt: data): comm +def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm + +//def new(dt: data, f: var[dt] -> comm): comm +//def dmaCopy(a: shine.GAP8.MemoryType, dt: data): comm +//def dmaCopy(a: shine.GAP8.MemoryType, dt: data, output: acc[dt]): acc[dt] +//def dmaCopyToL1(dt: data, output: acc[dt]): acc[dt] +//def dmaCopyToL2(dt: data, output: acc[dt]): acc[dt] From 43754cd88536b4e1440acf42d2921203dfbf6561 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 25 Apr 2023 11:07:24 +0200 Subject: [PATCH 42/86] GAP8 DMA support helper classes and constructs --- src/main/scala/shine/GAP8/DMATransferType.scala | 13 +++++++++++++ src/main/scala/shine/GAP8/DSL/package.scala | 16 ++++++++++++++++ src/main/scala/shine/GAP8/MemoryType.scala | 6 ++++++ 3 files changed, 35 insertions(+) create mode 100644 src/main/scala/shine/GAP8/DMATransferType.scala create mode 100644 src/main/scala/shine/GAP8/DSL/package.scala create mode 100644 src/main/scala/shine/GAP8/MemoryType.scala diff --git a/src/main/scala/shine/GAP8/DMATransferType.scala b/src/main/scala/shine/GAP8/DMATransferType.scala new file mode 100644 index 000000000..8636665b6 --- /dev/null +++ b/src/main/scala/shine/GAP8/DMATransferType.scala @@ -0,0 +1,13 @@ +package shine.GAP8 + +sealed trait DMATransferType { + def toGAP8string: String +} + +case object L1toL2 extends DMATransferType { + override def toGAP8string: String = "RT_DMA_DIR_LOC2EXT" +} + +case object L2toL1 extends DMATransferType { + override def toGAP8string: String = "RT_DMA_DIR_EXT2LOC" +} \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/DSL/package.scala b/src/main/scala/shine/GAP8/DSL/package.scala new file mode 100644 index 000000000..136a0aa2f --- /dev/null +++ b/src/main/scala/shine/GAP8/DSL/package.scala @@ -0,0 +1,16 @@ +package shine.GAP8 + +import rise.core.types.DataType +import shine.DPIA.DSL.λ +import shine.DPIA.Phrases.Phrase +import shine.DPIA.Types.CommType +import shine.DPIA.{VarType, varT} +import shine.GAP8.primitives.imperative.MemoryAlloc + +package object DSL { + object GAP8MemoryAlloc { + def apply(memoryType: shine.GAP8.MemoryType) + (dt: DataType, f: Phrase[VarType] => Phrase[CommType]): MemoryAlloc = + MemoryAlloc(memoryType)(dt, λ(varT(dt))(v => f(v))) + } +} diff --git a/src/main/scala/shine/GAP8/MemoryType.scala b/src/main/scala/shine/GAP8/MemoryType.scala new file mode 100644 index 000000000..b1928daa6 --- /dev/null +++ b/src/main/scala/shine/GAP8/MemoryType.scala @@ -0,0 +1,6 @@ +package shine.GAP8 + +sealed trait MemoryType + +case object L1 extends MemoryType +case object L2 extends MemoryType From c696bc0351eb217e40fcfca07f9df16f9ee999da Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 25 Apr 2023 11:08:50 +0200 Subject: [PATCH 43/86] WIP: Code generator for memory allocation and DMA transfers on GAP8 accelerator side; Minor refactoring --- .../AcceleratorCodeGenerator.scala | 95 ++++++++++++++++--- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 85311b96e..9d54c97c7 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -2,15 +2,16 @@ package shine.GAP8.Compilation import arithexpr.arithmetic import arithexpr.arithmetic.ArithExpr +import arithexpr.arithmetic.ArithExpr.toInt import rise.core.types.DataType import rise.core.types.DataType.ArrayType import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} import shine.DPIA.Nat -import shine.DPIA.Phrases.Phrase -import shine.DPIA.Types.{CommType, ExpType} +import shine.DPIA.Phrases.{Identifier, Lambda, Phrase, PhrasePair} +import shine.DPIA.Types.{AccType, CommType, ExpType} import shine.DPIA.primitives.functional.{Join, PadClamp} -import shine.GAP8.ConvolutionFilterSize -import shine.GAP8.primitives.imperative.{Conv3x3, Conv5x5, Conv7x4, Conv7x7} +import shine.GAP8.{ConvolutionFilterSize, MemoryType} +import shine.GAP8.primitives.imperative.{Conv3x3, Conv5x5, Conv7x4, Conv7x7, DmaCopy, MemoryAlloc} import shine.{C, OpenMP} import scala.collection.{immutable, mutable} @@ -24,14 +25,16 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def translationContext: TranslationContext = super.translationContext private def swapEnvIdentifier( - identifier: shine.DPIA.Phrases.Identifier[ExpType], + identifier: Identifier[ExpType], dt: DataType, env: Environment, height: Nat, width: Nat ): Environment = { - val oldFilterId = shine.DPIA.Phrases.Identifier(identifier.name, - ExpType(ArrayType(height, ArrayType(width, dt)), rise.core.types.read)) + val oldFilterId = Identifier( + identifier.name, + ExpType(ArrayType(height, ArrayType(width, dt)), rise.core.types.read) + ) val ref = env.identEnv(oldFilterId) val identEnv = env.identEnv - oldFilterId CodeGenerator.Environment(identEnv + ((identifier, ref)), @@ -40,7 +43,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def cmd(env: Environment): Phrase[CommType] => Stmt = { //TODO: Supoort multicycle output for 3x3 - case Conv3x3(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => + case Conv3x3(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { val env2 = swapEnvIdentifier(filter, dt, env, 3, 3) @@ -49,7 +52,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) }) - case Conv5x5(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => + case Conv5x5(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { val env2 = swapEnvIdentifier(filter, dt, env, 5, 5) @@ -58,7 +61,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) }) - case Conv7x7(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => + case Conv7x7(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { val env2 = swapEnvIdentifier(filter, dt, env, 7, 7) @@ -67,7 +70,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) }) - case Conv7x4(w, h, bias, dt, in, filter: shine.DPIA.Phrases.Identifier[ExpType], out) => + case Conv7x4(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { val env2 = swapEnvIdentifier(filter, dt, env, 7, 4) @@ -76,9 +79,79 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) }) + + //rt_dma_memcpy(src, dest, size, direction, merge, struct + // Source address Destination address Size Direction Merge Struct + // Identifier[ExpType] Identifier[ExpType] Nat Nat Nat Identifier[ExpType] + case copy@DmaCopy(transferType) => + println("In DmaCopy") + val (size, elemType) = copy.dt match { + case ArrayType(size, elemType) => + (toInt(size), elemType) + case _ => throw new RuntimeException(s"Expected ArrayType, got ${copy.dt}") + } + copy.src |> exp(env, Nil, (srcC: C.AST.Expr) => { + copy.dst |> acc(env, Nil, (dstC: C.AST.Expr) => { + C.AST.Block(Seq( + C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef("rt_dma_memcpy"), + Seq( + srcC, + dstC, + //C.AST.Literal(ArithExpr.toInt(copy.dt.asInstanceOf[ArrayType].size).toString), + C.AST.Literal(ArithExpr.toInt(size).toString), + C.AST.Literal(copy.tt.toGAP8string), + C.AST.Literal(""), + C.AST.Literal("") + ) + )) + )) + }) + }) + + //short int* ImageIn_L1_Temp_Converted = + // (short int*) rt_alloc(RT_ALLOC_CL_DATA, (IMG_W + 2) * ((IMG_H / NUM_STRIPES) + 2) * sizeof(short int)); + // Array Type Memory Type Size + // DataType Nat / Address Space Nat + case malloc@MemoryAlloc(memoryType) => { + println("In MemoryAlloc") + val dt = malloc.dt + malloc.f match { + case Lambda(v, p) => + val ve = Identifier(s"${v.name}_e", v.t.t1) + val va = Identifier(s"${v.name}_a", v.t.t2) + val vC = C.AST.DeclRef(v.name) + + C.AST.Block(immutable.Seq( + // + //C.AST.DeclStmt(C.AST.VarDecl(vC.name, typ(dt), Funcall (malloc))), + C.AST.DeclStmt(C.AST.VarDecl( + vC.name, + typ(dt), + Some(C.AST.FunCall( + C.AST.DeclRef("rt_alloc"), + Seq() + )) + )), + //Generate here a call to malloc + Phrase.substitute(PhrasePair(ve, va), `for` = v, `in` = p) |> cmd(env updatedIdentEnv (ve -> vC) + updatedIdentEnv (va -> vC)))) + + /*C.AST.Block(Seq( + C.AST.ExprStmt(C.AST.Assignment( + ???, + ??? + )) + ))*/ + case _ => throw new RuntimeException("This should not happen") + } + } + case phrase => phrase |> super.cmd(env) } + private def arraySizeHelper(dt: DataType): Nat = ??? + private def generateCalls(fs: ConvolutionFilterSize, w: Nat, h: Nat, bias: Nat, in: Expr, filter: Expr, output: Expr): Stmt = { C.AST.Block(Seq( From 7ea37bce702447508bc60e735b06f251c09276ad Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 25 Apr 2023 11:09:39 +0200 Subject: [PATCH 44/86] GAP8 copyToL1 and copyToL2 translation implementation --- .../scala/shine/DPIA/InferAccessAnnotation.scala | 12 ++++++++++++ src/main/scala/shine/DPIA/fromRise.scala | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index e1b1164f5..ae65477d5 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -638,6 +638,18 @@ private class InferAccessAnnotation { expT(ArrayType(oh, ArrayType(ow, s)), write) ) } + + case rg8p.copyToL1() => p.t match { + case (dt: DataType) ->: (_: DataType) => + expT(dt, write) ->: expT(dt, read) + case _ => error() + } + + case rg8p.copyToL2() => p.t match { + case (dt: DataType) ->: (_: DataType) => + expT(dt, write) ->: expT(dt, read) + case _ => error() + } } checkConsistency(p.t, primitiveType) diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index 972381e28..b6e5e1f8b 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -981,6 +981,15 @@ object fromRise { ) } + case rgap8.copyToL1() => fromType { + case expT(t, `write`) ->: expT(_, `read`) => + fun[ExpType](expT(t, write), e => gap8.CopyToL1(t, e)) + } + + case rgap8.copyToL2() => fromType { + case expT(dt, `write`) ->: expT(_, `read`) => + fun[ExpType](expT(dt, write), e => gap8.CopyToL2(dt, e)) + } case _ => throw new Exception(s"Missing rule for $p") } From 4563119e41ca023b99ca3157bf1d1676e800bd58 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 25 Apr 2023 11:11:08 +0200 Subject: [PATCH 45/86] WIP: copyToL1 and copyToL2 support for GAP8 --- .../Compilation/ContinuationTranslation.scala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala b/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala index db385a900..c93399865 100644 --- a/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala @@ -4,6 +4,7 @@ import rise.core.types.{AddressSpace, DataType, NatKind, read, write} import rise.core.types.DataType._ import rise.core.DSL.Type._ import rise.core.substitute.{natInType => substituteNatInType} +import rise.core.types.AddressSpace.Private import shine.DPIA.Compilation.TranslationToImperative._ import shine.DPIA.DSL.{comment, _} import shine.DPIA.Phrases._ @@ -12,11 +13,14 @@ import shine.DPIA.Types._ import shine.DPIA._ import shine.DPIA.primitives.functional._ import shine.DPIA.primitives.imperative.{Seq => _, _} +import shine.GAP8.{L1, L1toL2, L2, L2toL1} import shine.OpenCL.AdjustArraySizesForAllocations import shine.OpenMP.primitives.{functional => omp} import shine.OpenCL.primitives.{functional => ocl} import shine.cuda.primitives.{functional => cuda} import shine.cuda.primitives.{imperative => cudaIm} +import shine.GAP8.primitives.{functional => gap8} +import shine.GAP8.primitives.{imperative => gap8Imp} object ContinuationTranslation { def con(E: Phrase[ExpType]) @@ -401,10 +405,21 @@ object ContinuationTranslation { case ocl.ToMem(addrSpace, dt, input) => val adj = AdjustArraySizesForAllocations(input, dt, addrSpace) - shine.OpenCL.DSL.`new` (addrSpace) (adj.dt, tmp => acc(input)(adj.accF(tmp.wr)) `;` C(adj.exprF(tmp.rd))) + case gap8.CopyToL1(dt, input) => + shine.GAP8.DSL.GAP8MemoryAlloc(L1)(dt, tmp => { + gap8Imp.DmaCopy(L2toL1)(dt, input, tmp.wr) `;` + C(tmp.rd) + }) + + case gap8.CopyToL2(dt, input) => + shine.GAP8.DSL.GAP8MemoryAlloc(L2)(dt, tmp => { + gap8Imp.DmaCopy(L1toL2)(dt, input, tmp.wr) `;` + C(tmp.rd) + }) + // CUDA case cuda.GlobalToShared(dt, inputGlobal) => val adj = AdjustArraySizesForAllocations(inputGlobal, dt, AddressSpace.Local) From 66d2269ea4f23353098a80c3ac4e1992efb1cb1c Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 25 Apr 2023 11:14:55 +0200 Subject: [PATCH 46/86] Added temp application for implementation testing (GAP8 DMA and HWCE) --- src/main/scala/apps/GAP8HwceDma.scala | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/scala/apps/GAP8HwceDma.scala diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala new file mode 100644 index 000000000..6779c3d0a --- /dev/null +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -0,0 +1,26 @@ +package apps + +import rise.GAP8.DSL.gap8Run +import rise.GAP8.primitives.{copyToL1, copyToL2} +import rise.core.DSL.Type.TypeConstructors +import rise.core.DSL.{ToBeTyped, fun} +import rise.core.primitives.mapSeq +import rise.core.types.DataType.{ArrayType, u8} +import rise.elevate.Rise +import shine.GAP8.Module.translateToString + +object GAP8HwceDma { + def main(args: Array[String]): Unit = { + val expr: ToBeTyped[Rise] = fun(ArrayType(10, u8) ->: ArrayType(10, u8))(in => + gap8Run(8)( + in |> + mapSeq(fun(x => x)) |> + copyToL1 |> + mapSeq(fun(x => x)) |> + copyToL2 + ) + ) + + println(translateToString(util.gen.gap8.hosted.fromExpr(expr))) + } +} From f4fe99fa9faf4a069dfdf2ef2e97ed7f94aa8708 Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 26 Apr 2023 12:42:18 +0200 Subject: [PATCH 47/86] Changed access annotation from read to write for src in dmaCopy; Cleanup --- .../shine/GAP8/primitives/imperative/DmaCopy.scala | 2 +- .../GAP8/primitives/imperative/primitives.dpia | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala b/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala index 4252da365..6b72f8038 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala @@ -11,7 +11,7 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class DmaCopy(tt: shine.GAP8.DMATransferType)(val dt: DataType, val src: Phrase[ExpType], val dst: Phrase[AccType]) extends CommandPrimitive { assert { - src :: expT(dt, read) + src :: expT(dt, write) dst :: accT(dt) true } diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index ae4cde21e..866d09ed5 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -33,15 +33,5 @@ def conv7x4(w: nat, filter: exp[28.dt, read], out: acc[(w-6).(h-3).dt]): comm - -//def dmaCopy{a: shine.GAP8.MemoryType}(dt: data): comm - -def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, read], dst: acc[dt]): comm -//def memoryAlloc{mt: shine.GAP8.MemoryType}(size: nat, dt: data): comm -def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm - -//def new(dt: data, f: var[dt] -> comm): comm -//def dmaCopy(a: shine.GAP8.MemoryType, dt: data): comm -//def dmaCopy(a: shine.GAP8.MemoryType, dt: data, output: acc[dt]): acc[dt] -//def dmaCopyToL1(dt: data, output: acc[dt]): acc[dt] -//def dmaCopyToL2(dt: data, output: acc[dt]): acc[dt] +def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, write], dst: acc[dt]): comm +def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm \ No newline at end of file From 9640b636ce32b5065f036fc55b2da95de861135a Mon Sep 17 00:00:00 2001 From: bpervan Date: Wed, 26 Apr 2023 12:43:34 +0200 Subject: [PATCH 48/86] Refactor & cleanup --- .../AcceleratorCodeGenerator.scala | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 9d54c97c7..4cea43540 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -98,9 +98,8 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D Seq( srcC, dstC, - //C.AST.Literal(ArithExpr.toInt(copy.dt.asInstanceOf[ArrayType].size).toString), C.AST.Literal(ArithExpr.toInt(size).toString), - C.AST.Literal(copy.tt.toGAP8string), + C.AST.Literal(transferType.toGAP8string), C.AST.Literal(""), C.AST.Literal("") ) @@ -122,9 +121,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D val va = Identifier(s"${v.name}_a", v.t.t2) val vC = C.AST.DeclRef(v.name) - C.AST.Block(immutable.Seq( - // - //C.AST.DeclStmt(C.AST.VarDecl(vC.name, typ(dt), Funcall (malloc))), + C.AST.Block(Seq( C.AST.DeclStmt(C.AST.VarDecl( vC.name, typ(dt), @@ -134,15 +131,9 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D )) )), //Generate here a call to malloc - Phrase.substitute(PhrasePair(ve, va), `for` = v, `in` = p) |> cmd(env updatedIdentEnv (ve -> vC) - updatedIdentEnv (va -> vC)))) - - /*C.AST.Block(Seq( - C.AST.ExprStmt(C.AST.Assignment( - ???, - ??? - )) - ))*/ + Phrase.substitute(PhrasePair(ve, va), `for` = v, `in` = p) |> + cmd(env updatedIdentEnv (ve -> vC) updatedIdentEnv (va -> vC)) + )) case _ => throw new RuntimeException("This should not happen") } } From 5a75ce05b247f53dd9d7196cb7d36c55f577c4c8 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 27 Apr 2023 09:22:25 +0200 Subject: [PATCH 49/86] Changed memory allocation / dma transfer paradigm --- .../scala/rise/GAP8/primitives/allocL1.scala | 25 +++++++++++++++++++ .../scala/rise/GAP8/primitives/allocL2.scala | 25 +++++++++++++++++++ .../rise/GAP8/primitives/primitives.rise | 5 +++- .../GAP8/primitives/functional/AllocL1.scala | 19 ++++++++++++++ .../GAP8/primitives/functional/AllocL2.scala | 19 ++++++++++++++ .../GAP8/primitives/functional/CopyToL1.scala | 4 +-- .../GAP8/primitives/functional/CopyToL2.scala | 4 +-- .../primitives/functional/primitives.dpia | 7 ++++-- .../GAP8/primitives/imperative/DmaCopy.scala | 2 +- .../primitives/imperative/primitives.dpia | 2 +- 10 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 src/main/scala/rise/GAP8/primitives/allocL1.scala create mode 100644 src/main/scala/rise/GAP8/primitives/allocL2.scala create mode 100644 src/main/scala/shine/GAP8/primitives/functional/AllocL1.scala create mode 100644 src/main/scala/shine/GAP8/primitives/functional/AllocL2.scala diff --git a/src/main/scala/rise/GAP8/primitives/allocL1.scala b/src/main/scala/rise/GAP8/primitives/allocL1.scala new file mode 100644 index 000000000..42318250b --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/allocL1.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object allocL1 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "allocL1" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = impl { (t: DataType) => t ->: t } + } + override def toString: String = "allocL1" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/allocL2.scala b/src/main/scala/rise/GAP8/primitives/allocL2.scala new file mode 100644 index 000000000..033a713c3 --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/allocL2.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object allocL2 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "allocL2" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = impl { (t: DataType) => t ->: t } + } + override def toString: String = "allocL2" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 1b2f596ec..59323f6a2 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -21,4 +21,7 @@ def gap8hwConv7x4: (bias: nat) -> {iw: nat} -> {ih: nat} -> iw.ih.s -> 7.4.s -> ow.oh.s def copyToL1: {t: data} -> t -> t -def copyToL2: {t: data} -> t -> t \ No newline at end of file +def copyToL2: {t: data} -> t -> t + +def allocL1: {t: data} -> t -> t +def allocL2: {t: data} -> t -> t \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/functional/AllocL1.scala b/src/main/scala/shine/GAP8/primitives/functional/AllocL1.scala new file mode 100644 index 000000000..9dc947c83 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/AllocL1.scala @@ -0,0 +1,19 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class AllocL1(val dt: DataType, val input: Phrase[ExpType]) extends ExpPrimitive { + assert { + input :: expT(dt, write) + true + } + override val t: ExpType = expT(dt, read) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): AllocL1 = new AllocL1(v.data(dt), VisitAndRebuild(input, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/AllocL2.scala b/src/main/scala/shine/GAP8/primitives/functional/AllocL2.scala new file mode 100644 index 000000000..529bf6bea --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/AllocL2.scala @@ -0,0 +1,19 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class AllocL2(val dt: DataType, val input: Phrase[ExpType]) extends ExpPrimitive { + assert { + input :: expT(dt, write) + true + } + override val t: ExpType = expT(dt, read) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): AllocL2 = new AllocL2(v.data(dt), VisitAndRebuild(input, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala b/src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala index 463174574..b23324332 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/CopyToL1.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class CopyToL1(val dt: DataType, val input: Phrase[ExpType]) extends ExpPrimitive { assert { - input :: expT(dt, write) + input :: expT(dt, read) true } - override val t: ExpType = expT(dt, read) + override val t: ExpType = expT(dt, write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): CopyToL1 = new CopyToL1(v.data(dt), VisitAndRebuild(input, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala b/src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala index c27397e94..8b87ad227 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/CopyToL2.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class CopyToL2(val dt: DataType, val input: Phrase[ExpType]) extends ExpPrimitive { assert { - input :: expT(dt, write) + input :: expT(dt, read) true } - override val t: ExpType = expT(dt, read) + override val t: ExpType = expT(dt, write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): CopyToL2 = new CopyToL2(v.data(dt), VisitAndRebuild(input, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index 310d44a45..fa6a90827 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -38,5 +38,8 @@ def funConv7x4( filter: exp[7.4.dt, read] ): exp[(w-6).(h-3).dt, write] -def copyToL1(dt: data, input: exp[dt, write]): exp[dt, read] -def copyToL2(dt: data, input: exp[dt, write]): exp[dt, read] \ No newline at end of file +def copyToL1(dt: data, input: exp[dt, read]): exp[dt, write] +def copyToL2(dt: data, input: exp[dt, read]): exp[dt, write] + +def allocL1(dt: data, input: exp[dt, write]): exp[dt, read] +def allocL2(dt: data, input: exp[dt, write]): exp[dt, read] \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala b/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala index 6b72f8038..4252da365 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/DmaCopy.scala @@ -11,7 +11,7 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class DmaCopy(tt: shine.GAP8.DMATransferType)(val dt: DataType, val src: Phrase[ExpType], val dst: Phrase[AccType]) extends CommandPrimitive { assert { - src :: expT(dt, write) + src :: expT(dt, read) dst :: accT(dt) true } diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index 866d09ed5..6dfd9acfb 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -33,5 +33,5 @@ def conv7x4(w: nat, filter: exp[28.dt, read], out: acc[(w-6).(h-3).dt]): comm -def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, write], dst: acc[dt]): comm +def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, read], dst: acc[dt]): comm def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm \ No newline at end of file From 84bf5893984e3b6dc970b5e725ee9e919f011003 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 27 Apr 2023 09:23:34 +0200 Subject: [PATCH 50/86] Added alloc consts to MemoryType; Added brief implementation of type to size in bytes converter --- src/main/scala/shine/GAP8/AST/Types.scala | 30 ++++++++++++++++++++++ src/main/scala/shine/GAP8/MemoryType.scala | 12 ++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 src/main/scala/shine/GAP8/AST/Types.scala diff --git a/src/main/scala/shine/GAP8/AST/Types.scala b/src/main/scala/shine/GAP8/AST/Types.scala new file mode 100644 index 000000000..0d66dc946 --- /dev/null +++ b/src/main/scala/shine/GAP8/AST/Types.scala @@ -0,0 +1,30 @@ +package shine.GAP8.AST + +import rise.core.types.DataType + +object Types { + //TODO: Refactor in the style of OpenCL + def sizeInBytes(dt: DataType): Int = dt match { + case rise.core.types.DataType.bool => 1 + case rise.core.types.DataType.u8 => 1 + case rise.core.types.DataType.u16 => 2 + case rise.core.types.DataType.u32 => 4 + case rise.core.types.DataType.u64 => 8 + case rise.core.types.DataType.i8 => 1 + case rise.core.types.DataType.i16 => 2 + case rise.core.types.DataType.i32 => 4 + case rise.core.types.DataType.i64 => 8 + case rise.core.types.DataType.int => 4 + case rise.core.types.DataType.NatType => 4 + case rise.core.types.DataType.IndexType(size) => 4 + case rise.core.types.DataType.VectorType(size, elemType) => (sizeInBytes(elemType) * size).evalInt + case rise.core.types.DataType.PairType(e1, e2) => sizeInBytes(e1) + sizeInBytes(e2) + case rise.core.types.DataType.ArrayType(size, elemType) => (sizeInBytes(elemType) * size).evalInt + case rise.core.types.DataType.DepArrayType(size, natToData) => ??? + case _ => + throw new RuntimeException("Should not happen") + } +} + +//TODO +case class SizeInBytes() diff --git a/src/main/scala/shine/GAP8/MemoryType.scala b/src/main/scala/shine/GAP8/MemoryType.scala index b1928daa6..721c1fd05 100644 --- a/src/main/scala/shine/GAP8/MemoryType.scala +++ b/src/main/scala/shine/GAP8/MemoryType.scala @@ -1,6 +1,12 @@ package shine.GAP8 -sealed trait MemoryType +sealed trait MemoryType { + def toAllocString: String +} -case object L1 extends MemoryType -case object L2 extends MemoryType +case object L1 extends MemoryType { + override def toAllocString: String = "RT_ALLOC_CL_DATA" +} +case object L2 extends MemoryType { + override def toAllocString: String = "RT_ALLOC_L2_CL_DATA" +} From 21e5f095abd3b7a515021a06d6865cc616d132f4 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 27 Apr 2023 09:24:35 +0200 Subject: [PATCH 51/86] Malloc / DMA transfer refactor --- .../Compilation/AcceptorTranslation.scala | 30 ++++++++++++------- .../Compilation/ContinuationTranslation.scala | 12 +++++++- .../shine/DPIA/InferAccessAnnotation.scala | 14 ++++++++- src/main/scala/shine/DPIA/fromRise.scala | 16 ++++++++-- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index 81aa84535..40ef60528 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -1,25 +1,22 @@ package shine.DPIA.Compilation import arithexpr.arithmetic.{NamedVar, RangeAdd} +import rise.core.DSL.Type._ +import rise.core.substitute.{natInType => substituteNatInType} +import rise.core.types.DataType._ +import rise.core.types.{Nat, NatIdentifier, _} import shine.DPIA.Compilation.TranslationToImperative._ import shine.DPIA.DSL.{comment, _} import shine.DPIA.Phrases._ -import rise.core.types.{DataType, Fragment, MatrixLayout, NatIdentifier, NatKind, read, write} -import rise.core.DSL.Type._ -import rise.core.types.DataType._ -import rise.core.substitute.{natInType => substituteNatInType} import shine.DPIA.Types.{AccType, CommType, ExpType, TypeCheck, comm} -import rise.core.types.DataTypeOps._ import shine.DPIA._ import shine.DPIA.primitives.functional._ import shine.DPIA.primitives.imperative.{Seq => _, _} +import shine.GAP8.{L1toL2, L2toL1} +import shine.GAP8.primitives.{functional => gap8, imperative => gap8Imp} +import shine.OpenCL.primitives.{functional => ocl, imperative => oclImp} import shine.OpenMP.primitives.{functional => omp} -import shine.OpenCL.primitives.{functional => ocl} -import shine.OpenCL.primitives.{imperative => oclImp} -import shine.cuda.primitives.{functional => cuda} -import shine.cuda.primitives.{imperative => cudaImp} -import shine.GAP8.primitives.{functional => gap8} -import shine.GAP8.primitives.{imperative => gap8Imp} +import shine.cuda.primitives.{functional => cuda, imperative => cudaImp} object AcceptorTranslation { def acc(E: Phrase[ExpType]) @@ -426,6 +423,17 @@ object AcceptorTranslation { gap8Imp.Conv7x4(w, h, bias, dt, inInner, filterInner, A) )) })) + + case gap8.CopyToL1(dt, input) => + con(input)(λ(ExpType(dt, read))(i => + gap8Imp.DmaCopy(L2toL1)(dt, i, A) + )) + + case gap8.CopyToL2(dt, input) => + con(input)(λ(ExpType(dt, read))(i => + gap8Imp.DmaCopy(L1toL2)(dt, i, A) + )) + case r@shine.GAP8.primitives.functional.Run(cores) => { ??? } diff --git a/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala b/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala index c93399865..f9d381654 100644 --- a/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala @@ -408,7 +408,7 @@ object ContinuationTranslation { shine.OpenCL.DSL.`new` (addrSpace) (adj.dt, tmp => acc(input)(adj.accF(tmp.wr)) `;` C(adj.exprF(tmp.rd))) - case gap8.CopyToL1(dt, input) => + /*case gap8.CopyToL1(dt, input) => shine.GAP8.DSL.GAP8MemoryAlloc(L1)(dt, tmp => { gap8Imp.DmaCopy(L2toL1)(dt, input, tmp.wr) `;` C(tmp.rd) @@ -418,6 +418,16 @@ object ContinuationTranslation { shine.GAP8.DSL.GAP8MemoryAlloc(L2)(dt, tmp => { gap8Imp.DmaCopy(L1toL2)(dt, input, tmp.wr) `;` C(tmp.rd) + })*/ + + case gap8.AllocL1(dt, input) => + shine.GAP8.DSL.GAP8MemoryAlloc(L1)(dt, tmp => { + acc(input)(tmp.wr) `;` C(tmp.rd) + }) + + case gap8.AllocL2(dt, input) => + shine.GAP8.DSL.GAP8MemoryAlloc(L2)(dt, tmp => { + acc(input)(tmp.wr) `;` C(tmp.rd) }) // CUDA diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index ae65477d5..2d42cb2f0 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -641,11 +641,23 @@ private class InferAccessAnnotation { case rg8p.copyToL1() => p.t match { case (dt: DataType) ->: (_: DataType) => - expT(dt, write) ->: expT(dt, read) + expT(dt, read) ->: expT(dt, write) case _ => error() } case rg8p.copyToL2() => p.t match { + case (dt: DataType) ->: (_: DataType) => + expT(dt, read) ->: expT(dt, write) + case _ => error() + } + + case rg8p.allocL1() => p.t match { + case (dt: DataType) ->: (_: DataType) => + expT(dt, write) ->: expT(dt, read) + case _ => error() + } + + case rg8p.allocL2() => p.t match { case (dt: DataType) ->: (_: DataType) => expT(dt, write) ->: expT(dt, read) case _ => error() diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index b6e5e1f8b..1c1040f67 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -982,13 +982,23 @@ object fromRise { } case rgap8.copyToL1() => fromType { - case expT(t, `write`) ->: expT(_, `read`) => - fun[ExpType](expT(t, write), e => gap8.CopyToL1(t, e)) + case expT(t, `read`) ->: expT(_, `write`) => + fun[ExpType](expT(t, read), e => gap8.CopyToL1(t, e)) } case rgap8.copyToL2() => fromType { + case expT(dt, `read`) ->: expT(_, `write`) => + fun[ExpType](expT(dt, read), e => gap8.CopyToL2(dt, e)) + } + + case rgap8.allocL1() => fromType { + case expT(dt, `write`) ->: expT(_, `read`) => + fun[ExpType](expT(dt, write), e => gap8.AllocL1(dt, e)) + } + + case rgap8.allocL2() => fromType { case expT(dt, `write`) ->: expT(_, `read`) => - fun[ExpType](expT(dt, write), e => gap8.CopyToL2(dt, e)) + fun[ExpType](expT(dt, write), e => gap8.AllocL2(dt, e)) } case _ => throw new Exception(s"Missing rule for $p") From 7c7b9e1ce92d3ad2d9c03392ec28c2718421ca7c Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 27 Apr 2023 09:27:58 +0200 Subject: [PATCH 52/86] WIP: Implementation of code generation for Malloc / DMA transfer --- .../AcceleratorCodeGenerator.scala | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 4cea43540..a5497a3bf 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -2,16 +2,14 @@ package shine.GAP8.Compilation import arithexpr.arithmetic import arithexpr.arithmetic.ArithExpr -import arithexpr.arithmetic.ArithExpr.toInt import rise.core.types.DataType import rise.core.types.DataType.ArrayType import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} import shine.DPIA.Nat import shine.DPIA.Phrases.{Identifier, Lambda, Phrase, PhrasePair} -import shine.DPIA.Types.{AccType, CommType, ExpType} -import shine.DPIA.primitives.functional.{Join, PadClamp} -import shine.GAP8.{ConvolutionFilterSize, MemoryType} -import shine.GAP8.primitives.imperative.{Conv3x3, Conv5x5, Conv7x4, Conv7x7, DmaCopy, MemoryAlloc} +import shine.DPIA.Types.{CommType, ExpType} +import shine.GAP8.ConvolutionFilterSize +import shine.GAP8.primitives.imperative._ import shine.{C, OpenMP} import scala.collection.{immutable, mutable} @@ -84,24 +82,19 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D // Source address Destination address Size Direction Merge Struct // Identifier[ExpType] Identifier[ExpType] Nat Nat Nat Identifier[ExpType] case copy@DmaCopy(transferType) => - println("In DmaCopy") - val (size, elemType) = copy.dt match { - case ArrayType(size, elemType) => - (toInt(size), elemType) - case _ => throw new RuntimeException(s"Expected ArrayType, got ${copy.dt}") - } - copy.src |> exp(env, Nil, (srcC: C.AST.Expr) => { - copy.dst |> acc(env, Nil, (dstC: C.AST.Expr) => { + val size = shine.GAP8.AST.Types.sizeInBytes(copy.dt) + copy.dst |> acc(env, Nil, (dstC: C.AST.Expr) => { + copy.src |> exp(env, Nil, (srcC: C.AST.Expr) => { C.AST.Block(Seq( C.AST.ExprStmt(C.AST.FunCall( C.AST.DeclRef("rt_dma_memcpy"), Seq( srcC, dstC, - C.AST.Literal(ArithExpr.toInt(size).toString), + C.AST.Literal(size.toString), C.AST.Literal(transferType.toGAP8string), - C.AST.Literal(""), - C.AST.Literal("") + C.AST.Literal("merge"), + C.AST.Literal("transferobj") ) )) )) @@ -113,7 +106,6 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D // Array Type Memory Type Size // DataType Nat / Address Space Nat case malloc@MemoryAlloc(memoryType) => { - println("In MemoryAlloc") val dt = malloc.dt malloc.f match { case Lambda(v, p) => @@ -127,12 +119,21 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D typ(dt), Some(C.AST.FunCall( C.AST.DeclRef("rt_alloc"), - Seq() + Seq( + C.AST.Literal(memoryType.toAllocString), + C.AST.Literal(shine.GAP8.AST.Types.sizeInBytes(dt).toString) + ) )) )), - //Generate here a call to malloc Phrase.substitute(PhrasePair(ve, va), `for` = v, `in` = p) |> - cmd(env updatedIdentEnv (ve -> vC) updatedIdentEnv (va -> vC)) + cmd(env updatedIdentEnv (ve -> vC) updatedIdentEnv (va -> vC)), + //TODO: Generate dealloc / free? + C.AST.ExprStmt( + C.AST.FunCall( + C.AST.DeclRef("free"), + Seq() + ) + ) )) case _ => throw new RuntimeException("This should not happen") } @@ -141,8 +142,6 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D case phrase => phrase |> super.cmd(env) } - private def arraySizeHelper(dt: DataType): Nat = ??? - private def generateCalls(fs: ConvolutionFilterSize, w: Nat, h: Nat, bias: Nat, in: Expr, filter: Expr, output: Expr): Stmt = { C.AST.Block(Seq( @@ -204,6 +203,8 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D C.AST.Cast(C.AST.Type.u32, C.AST.Literal(qnorm.toString)) ) )) + + override def typ(dt: DataType): Type = super.typ(dt) } object AcceleratorCodeGenerator { From c4ea399b22e57e5c45b5d00d078ed12fd895efea Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 28 Apr 2023 10:11:48 +0200 Subject: [PATCH 53/86] Minor refactor --- .../AcceleratorCodeGenerator.scala | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index a5497a3bf..a36b4d960 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -78,9 +78,16 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) - //rt_dma_memcpy(src, dest, size, direction, merge, struct - // Source address Destination address Size Direction Merge Struct - // Identifier[ExpType] Identifier[ExpType] Nat Nat Nat Identifier[ExpType] + + /** + * Generates a call to DMA transfer + * rt_dma_memcpy(src, dest, size, direction, merge, struct) + * rt_dma_wait(struct) + * + * TODO: Rethink this as it issues a call which will wait for the transfer to complete + * immediately after the transfer has begun. Separating these two concerns could enable + * parallelization of transfers and other useful calculations + * */ case copy@DmaCopy(transferType) => val size = shine.GAP8.AST.Types.sizeInBytes(copy.dt) copy.dst |> acc(env, Nil, (dstC: C.AST.Expr) => { @@ -93,9 +100,13 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D dstC, C.AST.Literal(size.toString), C.AST.Literal(transferType.toGAP8string), - C.AST.Literal("merge"), - C.AST.Literal("transferobj") + C.AST.Literal(0.toString), + C.AST.Literal("&L2toL1") ) + )), + C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef("rt_dma_wait"), + Seq(C.AST.Literal("&L2toL1")) )) )) }) From b8423cddb8f18b3b0238fa8ca990f5ea69334205 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 4 May 2023 14:48:47 +0200 Subject: [PATCH 54/86] Added GAP8 + HWCE + DMA testing application --- src/main/scala/apps/GAP8HwceDma.scala | 97 ++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 6779c3d0a..43ec3d6e1 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -1,26 +1,105 @@ package apps import rise.GAP8.DSL.gap8Run -import rise.GAP8.primitives.{copyToL1, copyToL2} +import rise.GAP8.primitives.{allocL1, copyToL1, copyToL2, gap8hwConv3x3} import rise.core.DSL.Type.TypeConstructors -import rise.core.DSL.{ToBeTyped, fun} -import rise.core.primitives.mapSeq -import rise.core.types.DataType.{ArrayType, u8} +import rise.core.DSL.Type.`.` +import rise.core.DSL.{ToBeTyped, depFun, fun, letf} +import rise.core.primitives.{add, mapSeq} +import rise.core.types.DataType.{ArrayType, i16, u8} +import rise.core.types.Nat import rise.elevate.Rise import shine.GAP8.Module.translateToString object GAP8HwceDma { def main(args: Array[String]): Unit = { - val expr: ToBeTyped[Rise] = fun(ArrayType(10, u8) ->: ArrayType(10, u8))(in => + val size: Nat = 10 + val fixSize: ToBeTyped[Rise] = fun(ArrayType(size, u8) ->: ArrayType(size, u8))(in => + gap8Run(8)( + in |> + copyToL1 |> + allocL1 |> + mapSeq(fun(x => x)) |> + allocL1 |> + copyToL2 + ) + ) + println(translateToString(util.gen.gap8.hosted.fromExpr(fixSize))) + + val varSize: ToBeTyped[Rise] = depFun((sz: Nat) => + fun(ArrayType(sz, u8) ->: ArrayType(sz, u8))(in => + gap8Run(8)( + in |> + copyToL1 |> + allocL1 |> + mapSeq(fun(x => x)) |> + allocL1 |> + copyToL2 + ))) + //println(translateToString(util.gen.gap8.hosted.fromExpr(varSize))) + + val hwceDebug: ToBeTyped[Rise] = fun( + ArrayType(size, ArrayType(size, u8)) ->: + ArrayType(3, ArrayType(3, u8)) ->: + ArrayType(size - 2, ArrayType(size - 2, u8)))((in, filter) => + gap8Run(8)( + gap8hwConv3x3(0)(in, filter) + ) + ) + println(translateToString(util.gen.gap8.hosted.fromExpr(hwceDebug))) + + + val fixSizeDmaHwce: ToBeTyped[Rise] = fun( + ArrayType(size, ArrayType(size, u8)) ->: + ArrayType(3, ArrayType(3, u8)) ->: + ArrayType(size - 2, ArrayType(size - 2, u8)))((in, filter) => gap8Run(8)( in |> - mapSeq(fun(x => x)) |> copyToL1 |> - mapSeq(fun(x => x)) |> - copyToL2 + allocL1 |> + letf(innerin => + filter |> + copyToL1 |> + allocL1 |> letf(innerf => + gap8hwConv3x3(0)(innerin, innerf) |> allocL1 |> copyToL2 + ) + ) + ) + ) + println(translateToString(util.gen.gap8.hosted.fromExpr(fixSizeDmaHwce))) + + /*val varSize: ToBeTyped[Rise] = depFun((n: Nat) => + fun(ArrayType(n, u8) ->: ArrayType(n, u8))(in => + gap8Run(8)( + in |> + copyToL1 |> + allocL1 |> + mapSeq(fun(x => x)) |> + allocL1 |> + copyToL2 + ) ) ) + println(translateToString(util.gen.gap8.hosted.fromExpr(varSize)))*/ - println(translateToString(util.gen.gap8.hosted.fromExpr(expr))) + /* + * + val w: Nat = 9 + val h: Nat = 9 + val twoDandHWCE: ToBeTyped[Rise] = { + fun(ArrayType(w, ArrayType(h, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: ArrayType((w-2), ArrayType((h-2), i16)))((in, filter) => + gap8Run(8)( + in |> + copyToL1 |> + allocL1 |> + mapSeq(fun(x =>x)) |> + allocL1 |> + copyToL2 + //gap8hwConv3x3(0)(in)(filter) + ) + ) + } + println(translateToString(util.gen.gap8.hosted.fromExpr(twoDandHWCE))) + * */ } } From 4ee92770e66255d3d4e9152bbb7dab26a26b3694 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 4 May 2023 14:49:55 +0200 Subject: [PATCH 55/86] Temporary debugging println; Added (commented) alternative Phrase for a padded array --- .../scala/shine/DPIA/Compilation/AcceptorTranslation.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index 40ef60528..b48b4c865 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -394,9 +394,10 @@ object AcceptorTranslation { // TODO: think about generalizing this. This currently only works if the filter is an identifier case gap8.FunConv3x3(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { - // import shine.DPIA.primitives.functional.{Join, PadClamp} // val paddedArray = PadClamp(3 * 3, 0, 1, dt, Join(3, 3, read, dt, filter)) + //val paddedArray = PadCst(3 * 3, 0, 1, dt, Literal(Unsigned8BitIntData(0)), Join(3, 3, read, dt, filter)) val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(10, dt), read)) + println(s"paddedarray: $paddedArray") con(paddedArray)(λ(ExpType(ArrayType(10, dt), read))(filterInner => gap8Imp.Conv3x3(w, h, bias, dt, inInner, filterInner, A) )) From bd38ac419e8e34d4d70191964bb809a2ad556083 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 4 May 2023 14:51:10 +0200 Subject: [PATCH 56/86] Temporary debugging printlns --- .../shine/GAP8/Compilation/AcceleratorCodeGenerator.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index a36b4d960..1c4dad99e 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -33,6 +33,8 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D identifier.name, ExpType(ArrayType(height, ArrayType(width, dt)), rise.core.types.read) ) + println(s"I'm looking for $oldFilterId in ${env.identEnv}") + //println(s"temp $temp") val ref = env.identEnv(oldFilterId) val identEnv = env.identEnv - oldFilterId CodeGenerator.Environment(identEnv + ((identifier, ref)), @@ -44,7 +46,9 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D case Conv3x3(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { + println(s"Old env: $env") val env2 = swapEnvIdentifier(filter, dt, env, 3, 3) + println(s"New env: $env2") filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._3x3, w, h, bias, inC, filterC, outputC) }) From 951e9394cbdd4b36af6d31d135410048bf63bb6c Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 5 May 2023 23:20:59 +0200 Subject: [PATCH 57/86] Added Cast primitive; Added pattern matching case to ContinuationTranslation; Introduced Cast to AcceptorTranslation in the context of FunConvNxM (ditching previous hacky solutions with creating new identifies --- .../Compilation/AcceptorTranslation.scala | 32 +++++++++++++------ .../Compilation/ContinuationTranslation.scala | 15 ++------- .../GAP8/primitives/functional/Cast.scala | 19 +++++++++++ .../primitives/functional/primitives.dpia | 4 ++- 4 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 src/main/scala/shine/GAP8/primitives/functional/Cast.scala diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index b48b4c865..23e854997 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -390,36 +390,50 @@ object AcceptorTranslation { con(cMatrix)(λ(ExpType(FragmentType(m, n, k, dataTypeAcc, Fragment.Accumulator, MatrixLayout.None), read))(cMatrix => cudaImp.WmmaMMA(m, n, k, layoutA, layoutB, dataType, dataTypeAcc, aMatrix, bMatrix, cMatrix, A))))))) - //GAP8 + // GAP8 // TODO: think about generalizing this. This currently only works if the filter is an identifier case gap8.FunConv3x3(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { - // val paddedArray = PadClamp(3 * 3, 0, 1, dt, Join(3, 3, read, dt, filter)) - //val paddedArray = PadCst(3 * 3, 0, 1, dt, Literal(Unsigned8BitIntData(0)), Join(3, 3, read, dt, filter)) - val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(10, dt), read)) - println(s"paddedarray: $paddedArray") + // val paddedArray = PadCst(3 * 3, 0, 1, dt, Literal(Unsigned8BitIntData(0)), Join(3, 3, read, dt, filter)) + // val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(10, dt), read)) + val paddedArray = gap8.Cast( + ArrayType(3, ArrayType(3, dt)), + ArrayType(10, dt), + filter + ) con(paddedArray)(λ(ExpType(ArrayType(10, dt), read))(filterInner => gap8Imp.Conv3x3(w, h, bias, dt, inInner, filterInner, A) )) })) - //TODO: Placeholders. Rethink case gap8.FunConv5x5(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { - val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(26, dt), read)) + val paddedArray = gap8.Cast( + ArrayType(5, ArrayType(5, dt)), + ArrayType(26, dt), + filter + ) con(paddedArray)(λ(ExpType(ArrayType(26, dt), read))(filterInner => gap8Imp.Conv5x5(w, h, bias, dt, inInner, filterInner, A) )) })) case gap8.FunConv7x7(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { - val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(56, dt), read)) + val paddedArray = gap8.Cast( + ArrayType(7, ArrayType(7, dt)), + ArrayType(56, dt), + filter + ) con(paddedArray)(λ(ExpType(ArrayType(56, dt), read))(filterInner => gap8Imp.Conv7x7(w, h, bias, dt, inInner, filterInner, A) )) })) case gap8.FunConv7x4(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { - val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(28, dt), read)) + val paddedArray = gap8.Cast( + ArrayType(7, ArrayType(4, dt)), + ArrayType(28, dt), + filter + ) con(paddedArray)(λ(ExpType(ArrayType(28, dt), read))(filterInner => gap8Imp.Conv7x4(w, h, bias, dt, inInner, filterInner, A) )) diff --git a/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala b/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala index f9d381654..7431ec418 100644 --- a/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/ContinuationTranslation.scala @@ -408,18 +408,6 @@ object ContinuationTranslation { shine.OpenCL.DSL.`new` (addrSpace) (adj.dt, tmp => acc(input)(adj.accF(tmp.wr)) `;` C(adj.exprF(tmp.rd))) - /*case gap8.CopyToL1(dt, input) => - shine.GAP8.DSL.GAP8MemoryAlloc(L1)(dt, tmp => { - gap8Imp.DmaCopy(L2toL1)(dt, input, tmp.wr) `;` - C(tmp.rd) - }) - - case gap8.CopyToL2(dt, input) => - shine.GAP8.DSL.GAP8MemoryAlloc(L2)(dt, tmp => { - gap8Imp.DmaCopy(L1toL2)(dt, input, tmp.wr) `;` - C(tmp.rd) - })*/ - case gap8.AllocL1(dt, input) => shine.GAP8.DSL.GAP8MemoryAlloc(L1)(dt, tmp => { acc(input)(tmp.wr) `;` C(tmp.rd) @@ -430,6 +418,9 @@ object ContinuationTranslation { acc(input)(tmp.wr) `;` C(tmp.rd) }) + case gap8.Cast(dt1, dt2, input) => + con(input)(λ(expT(dt1, read))(inputT => C(gap8.Cast(dt1, dt2, inputT)))) + // CUDA case cuda.GlobalToShared(dt, inputGlobal) => val adj = AdjustArraySizesForAllocations(inputGlobal, dt, AddressSpace.Local) diff --git a/src/main/scala/shine/GAP8/primitives/functional/Cast.scala b/src/main/scala/shine/GAP8/primitives/functional/Cast.scala new file mode 100644 index 000000000..263c817ec --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/Cast.scala @@ -0,0 +1,19 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Cast(val dt1: DataType, val dt2: DataType, val input: Phrase[ExpType]) extends ExpPrimitive { + assert { + input :: expT(dt1, read) + true + } + override val t: ExpType = expT(dt2, read) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Cast = new Cast(v.data(dt1), v.data(dt2), VisitAndRebuild(input, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index fa6a90827..d6ec00141 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -42,4 +42,6 @@ def copyToL1(dt: data, input: exp[dt, read]): exp[dt, write] def copyToL2(dt: data, input: exp[dt, read]): exp[dt, write] def allocL1(dt: data, input: exp[dt, write]): exp[dt, read] -def allocL2(dt: data, input: exp[dt, write]): exp[dt, read] \ No newline at end of file +def allocL2(dt: data, input: exp[dt, write]): exp[dt, read] + +def cast(dt1: data, dt2: data, input: exp[dt1, read]): exp[dt2, read] \ No newline at end of file From 311e78617e78d24712025b590ba18dea4cf5a9bb Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 5 May 2023 23:29:42 +0200 Subject: [PATCH 58/86] Removed swapEnvIdentifier as it's no longer necessary; Added appropriate call to rt_free; Added exp override to support Cast primitive --- .../AcceleratorCodeGenerator.scala | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 1c4dad99e..26545ab1d 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -3,12 +3,12 @@ package shine.GAP8.Compilation import arithexpr.arithmetic import arithexpr.arithmetic.ArithExpr import rise.core.types.DataType -import rise.core.types.DataType.ArrayType import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} import shine.DPIA.Nat import shine.DPIA.Phrases.{Identifier, Lambda, Phrase, PhrasePair} import shine.DPIA.Types.{CommType, ExpType} import shine.GAP8.ConvolutionFilterSize +import shine.GAP8.primitives.functional.Cast import shine.GAP8.primitives.imperative._ import shine.{C, OpenMP} @@ -22,34 +22,21 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def translationContext: TranslationContext = super.translationContext - private def swapEnvIdentifier( - identifier: Identifier[ExpType], - dt: DataType, - env: Environment, - height: Nat, - width: Nat - ): Environment = { - val oldFilterId = Identifier( - identifier.name, - ExpType(ArrayType(height, ArrayType(width, dt)), rise.core.types.read) - ) - println(s"I'm looking for $oldFilterId in ${env.identEnv}") - //println(s"temp $temp") - val ref = env.identEnv(oldFilterId) - val identEnv = env.identEnv - oldFilterId - CodeGenerator.Environment(identEnv + ((identifier, ref)), - env.commEnv, env.contEnv, env.letNatEnv) + override def exp(env: Environment, + path: List[shine.C.Compilation.CodeGenerator.PathExpr], + cont: Expr => Stmt): Phrase[ExpType] => Stmt = { + case Cast(_, _, input) => + super.exp(env, path, cont)(input) + case other => + super.exp(env, path, cont)(other) } override def cmd(env: Environment): Phrase[CommType] => Stmt = { //TODO: Supoort multicycle output for 3x3 - case Conv3x3(w, h, bias, dt, in, filter: Identifier[ExpType], out) => + case Conv3x3(w, h, bias, dt, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - println(s"Old env: $env") - val env2 = swapEnvIdentifier(filter, dt, env, 3, 3) - println(s"New env: $env2") - filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._3x3, w, h, bias, inC, filterC, outputC) }) }) @@ -57,8 +44,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D case Conv5x5(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - val env2 = swapEnvIdentifier(filter, dt, env, 5, 5) - filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._5x5, w, h, bias, inC, filterC, outputC) }) }) @@ -66,8 +52,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D case Conv7x7(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - val env2 = swapEnvIdentifier(filter, dt, env, 7, 7) - filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._7x7, w, h, bias, inC, filterC, outputC) }) }) @@ -75,14 +60,12 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D case Conv7x4(w, h, bias, dt, in, filter: Identifier[ExpType], out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { - val env2 = swapEnvIdentifier(filter, dt, env, 7, 4) - filter |> exp(env2, Nil, (filterC: C.AST.Expr) => { + filter |> exp(env, Nil, (filterC: C.AST.Expr) => { generateCalls(shine.GAP8._7x4, w, h, bias, inC, filterC, outputC) }) }) }) - /** * Generates a call to DMA transfer * rt_dma_memcpy(src, dest, size, direction, merge, struct) @@ -145,8 +128,12 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D //TODO: Generate dealloc / free? C.AST.ExprStmt( C.AST.FunCall( - C.AST.DeclRef("free"), - Seq() + C.AST.DeclRef("rt_free"), + Seq( + C.AST.Literal(memoryType.toAllocString), + C.AST.Literal(vC.name), + C.AST.Literal(shine.GAP8.AST.Types.sizeInBytes(dt).toString) + ) ) ) )) From 8e519dbd85f1981eeaccf526a5a98ac1d026a303 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 15 May 2023 22:48:17 +0200 Subject: [PATCH 59/86] Added event set call to GAP8 module --- src/main/scala/shine/GAP8/Module.scala | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/scala/shine/GAP8/Module.scala b/src/main/scala/shine/GAP8/Module.scala index e6928dcff..bcf9c6882 100644 --- a/src/main/scala/shine/GAP8/Module.scala +++ b/src/main/scala/shine/GAP8/Module.scala @@ -88,6 +88,18 @@ object Module { )) } + //TODO: Recheck, this is not needed if HWCE is not used. (Move to AcceleratorCodeGenerator?) + /** + * Sets the corresponding bit in the event mask to 1. This is presumably necessary to enable the logic needed + * to work with HWCE + * */ + val setEventMaskStmt = C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef("eu_evt_maskSet"), + Seq( + C.AST.Literal("1 << ARCHI_CL_EVT_ACC0") + ) + )) + val wrappedFunction = C.AST.Function( code = C.AST.FunDecl( @@ -95,7 +107,8 @@ object Module { returnType = C.AST.Type.void, params = Seq(C.AST.ParamDecl("args", C.AST.PointerType(C.AST.Type.void))), body = C.AST.Block( - Seq(structCastDecl) + Seq(setEventMaskStmt) + ++ Seq(structCastDecl) ++ unpackingStmts ++ accFunction.map(f => Seq(f)).getOrElse(Seq()).map(_.code.body) ) From ecb04418f475d8057ac75d627392e688946d41f2 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 15 May 2023 22:49:54 +0200 Subject: [PATCH 60/86] Pointer cast when generating rt_alloc call; Array declaration is now of pointer type --- .../AcceleratorCodeGenerator.scala | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 26545ab1d..bd70ce0ad 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -114,14 +114,19 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D C.AST.Block(Seq( C.AST.DeclStmt(C.AST.VarDecl( vC.name, - typ(dt), - Some(C.AST.FunCall( - C.AST.DeclRef("rt_alloc"), - Seq( - C.AST.Literal(memoryType.toAllocString), - C.AST.Literal(shine.GAP8.AST.Types.sizeInBytes(dt).toString) + arrayToPointerType(dt), + Some( + C.AST.Cast( + C.AST.PointerType(shine.GAP8.AST.Types.toStdint(dt), false), + C.AST.FunCall( + C.AST.DeclRef("rt_alloc"), + Seq( + C.AST.Literal(memoryType.toAllocString), + C.AST.Literal(shine.GAP8.AST.Types.sizeInBytes(dt).toString) + ) + ) ) - )) + ) )), Phrase.substitute(PhrasePair(ve, va), `for` = v, `in` = p) |> cmd(env updatedIdentEnv (ve -> vC) updatedIdentEnv (va -> vC)), @@ -206,6 +211,14 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D ) )) + private def arrayToPointerType(dt: DataType): Type = + dt match { + case rise.core.types.DataType.ArrayType(size, elemType) => + C.AST.PointerType( + C.AST.BasicType(shine.GAP8.AST.Types.toStdint(elemType).toString, false) + ) + case _ => typ(dt) + } override def typ(dt: DataType): Type = super.typ(dt) } From 27ec7c44c0f7728ccd610a08769dddcef86d756f Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 15 May 2023 22:50:33 +0200 Subject: [PATCH 61/86] Added toStdint method --- src/main/scala/shine/GAP8/AST/Types.scala | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/scala/shine/GAP8/AST/Types.scala b/src/main/scala/shine/GAP8/AST/Types.scala index 0d66dc946..8dbb9c575 100644 --- a/src/main/scala/shine/GAP8/AST/Types.scala +++ b/src/main/scala/shine/GAP8/AST/Types.scala @@ -24,6 +24,25 @@ object Types { case _ => throw new RuntimeException("Should not happen") } + + def toStdint(dt: DataType): shine.C.AST.Type = { + dt match { + case rise.core.types.DataType.bool => shine.C.AST.BasicType("bool") + case rise.core.types.DataType.u8 => shine.C.AST.Type.u8 + case rise.core.types.DataType.u16 => shine.C.AST.Type.u16 + case rise.core.types.DataType.u32 => shine.C.AST.Type.u32 + case rise.core.types.DataType.u64 => shine.C.AST.Type.u64 + case rise.core.types.DataType.i8 => shine.C.AST.Type.i8 + case rise.core.types.DataType.i16 => shine.C.AST.Type.i16 + case rise.core.types.DataType.i32 => shine.C.AST.Type.i32 + case rise.core.types.DataType.i64 => shine.C.AST.Type.i64 + case rise.core.types.DataType.int => shine.C.AST.Type.int + case rise.core.types.DataType.f32 => shine.C.AST.Type.float + case rise.core.types.DataType.f64 => shine.C.AST.Type.double + case rise.core.types.DataType.ArrayType(size, elemType) => toStdint(elemType) + case _ => throw new RuntimeException("Not implemented") + } + } } //TODO From b65766e41acb3640d947474826d6c4fa1944c420 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 15 May 2023 23:00:59 +0200 Subject: [PATCH 62/86] Handled ext/loc memory references in the context of DMA transfers --- .../GAP8/Compilation/AcceleratorCodeGenerator.scala | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index bd70ce0ad..8325c7be6 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -70,7 +70,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D * Generates a call to DMA transfer * rt_dma_memcpy(src, dest, size, direction, merge, struct) * rt_dma_wait(struct) - * + * ext loc * TODO: Rethink this as it issues a call which will wait for the transfer to complete * immediately after the transfer has begun. Separating these two concerns could enable * parallelization of transfers and other useful calculations @@ -79,12 +79,18 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D val size = shine.GAP8.AST.Types.sizeInBytes(copy.dt) copy.dst |> acc(env, Nil, (dstC: C.AST.Expr) => { copy.src |> exp(env, Nil, (srcC: C.AST.Expr) => { + val (ext, loc) = transferType match { + case shine.GAP8.L1toL2 => + (dstC, srcC) + case shine.GAP8.L2toL1 => + (srcC, dstC) + } C.AST.Block(Seq( C.AST.ExprStmt(C.AST.FunCall( C.AST.DeclRef("rt_dma_memcpy"), Seq( - srcC, - dstC, + ext, + loc, C.AST.Literal(size.toString), C.AST.Literal(transferType.toGAP8string), C.AST.Literal(0.toString), From db29ccc324ffcfac98dd242b5f603e79f113ceb4 Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 18 May 2023 09:13:31 +0200 Subject: [PATCH 63/86] DMA + 2xHWCE WIP --- src/main/scala/apps/GAP8HwceDma.scala | 173 ++++++++++++++++++-------- 1 file changed, 119 insertions(+), 54 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 43ec3d6e1..5480f2a2b 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -2,18 +2,46 @@ package apps import rise.GAP8.DSL.gap8Run import rise.GAP8.primitives.{allocL1, copyToL1, copyToL2, gap8hwConv3x3} +import rise.core.DSL.HighLevelConstructs.{slide2D, zipND} import rise.core.DSL.Type.TypeConstructors import rise.core.DSL.Type.`.` -import rise.core.DSL.{ToBeTyped, depFun, fun, letf} -import rise.core.primitives.{add, mapSeq} +import rise.core.DSL.{ToBeTyped, TypeAnnotationHelper, depFun, foreignFun, fun, let, letf, li16, lu8} +import rise.core.primitives.{add, cast, fst, join, mapSeq, padCst, slide, snd, zip} import rise.core.types.DataType.{ArrayType, i16, u8} import rise.core.types.Nat import rise.elevate.Rise +import rise.openMP.primitives.mapPar import shine.GAP8.Module.translateToString +// scalastyle: off object GAP8HwceDma { def main(args: Array[String]): Unit = { - val size: Nat = 10 + val gapSqrt = foreignFun("gap_sqrt", + Seq("a_nInput"), + """ + | { + | uint32_t op = a_nInput; + | uint32_t res = 0; + | + | uint32_t one = 1uL << 30; + | while (one > op){ + | one >>= 2; + | } + | while (one != 0) { + | if (op >= res + one){ + | op = op - (res + one); + | res = res + 2 * one; + | } + | res >>= 1; + | one >>= 2; + | } + | return res; + | } + |""".stripMargin, + i16 ->: i16 + ) + + val size: Nat = 4 val fixSize: ToBeTyped[Rise] = fun(ArrayType(size, u8) ->: ArrayType(size, u8))(in => gap8Run(8)( in |> @@ -24,7 +52,7 @@ object GAP8HwceDma { copyToL2 ) ) - println(translateToString(util.gen.gap8.hosted.fromExpr(fixSize))) + //println(translateToString(util.gen.gap8.hosted.fromExpr(fixSize))) val varSize: ToBeTyped[Rise] = depFun((sz: Nat) => fun(ArrayType(sz, u8) ->: ArrayType(sz, u8))(in => @@ -38,68 +66,105 @@ object GAP8HwceDma { ))) //println(translateToString(util.gen.gap8.hosted.fromExpr(varSize))) - val hwceDebug: ToBeTyped[Rise] = fun( - ArrayType(size, ArrayType(size, u8)) ->: - ArrayType(3, ArrayType(3, u8)) ->: - ArrayType(size - 2, ArrayType(size - 2, u8)))((in, filter) => - gap8Run(8)( - gap8hwConv3x3(0)(in, filter) - ) - ) - println(translateToString(util.gen.gap8.hosted.fromExpr(hwceDebug))) - - val fixSizeDmaHwce: ToBeTyped[Rise] = fun( - ArrayType(size, ArrayType(size, u8)) ->: - ArrayType(3, ArrayType(3, u8)) ->: - ArrayType(size - 2, ArrayType(size - 2, u8)))((in, filter) => + ArrayType(size, ArrayType(size, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(size - 2, ArrayType(size - 2, i16)))((in, filter) => gap8Run(8)( - in |> - copyToL1 |> - allocL1 |> - letf(innerin => - filter |> - copyToL1 |> - allocL1 |> letf(innerf => - gap8hwConv3x3(0)(innerin, innerf) |> allocL1 |> copyToL2 - ) + in |> copyToL1 |> allocL1 |> letf(innerin => + filter |> copyToL1 |> allocL1 |> letf(innerf => + gap8hwConv3x3(0)(innerin, innerf) |> allocL1 |> copyToL2 ) + ) ) ) - println(translateToString(util.gen.gap8.hosted.fromExpr(fixSizeDmaHwce))) + //println(translateToString(util.gen.gap8.hosted("conv").fromExpr(fixSizeDmaHwce))) - /*val varSize: ToBeTyped[Rise] = depFun((n: Nat) => - fun(ArrayType(n, u8) ->: ArrayType(n, u8))(in => + val n: Nat = 320 + val m: Nat = 240 + val numStripes: Nat = 12 + val stripeSize: Nat = n * (m / numStripes) + val tileSize: Nat = 80 * 80 + val tiledFixSizeDmaHwce: ToBeTyped[Rise] = + fun( + ArrayType(n, ArrayType(m, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(n - 2, ArrayType(m - 2, i16)))((pic, hw, vw) => gap8Run(8)( - in |> - copyToL1 |> - allocL1 |> - mapSeq(fun(x => x)) |> - allocL1 |> - copyToL2 + hw |> copyToL1 |> allocL1 |> letf(l1hw => + vw |> copyToL1 |> allocL1 |> letf(l1vw => + pic |> slide(stripeSize)(stripeSize - 1) |> + mapSeq(fun(stripe => + stripe |> copyToL1 |> allocL1 |> letf(l1stripe => + l1stripe |> mapPar(fun(row => row |> padCst(1)(1)(li16(0)))) |> // mapSeq(fun(x => cast(x) :: i16)) |> + letf(l1convstripe => + gap8hwConv3x3(0)(l1convstripe, l1hw) |> letf(hconvres => + gap8hwConv3x3(0)(l1convstripe, l1vw) |> letf(vconvres => + zip(hconvres)(vconvres) |> + mapPar(fun((h, v) => + gapSqrt(add(h * h)(v * v)) + )) |> allocL1 |> copyToL2 + ) + ) + ) + ))) + ) + ) ) ) - ) - println(translateToString(util.gen.gap8.hosted.fromExpr(varSize)))*/ + //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) - /* - * - val w: Nat = 9 - val h: Nat = 9 - val twoDandHWCE: ToBeTyped[Rise] = { - fun(ArrayType(w, ArrayType(h, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: ArrayType((w-2), ArrayType((h-2), i16)))((in, filter) => + val tiledFixSizeDmaHwce2: ToBeTyped[Rise] = + fun( + ArrayType(n, ArrayType(m, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(n - 2, ArrayType(m - 2, i16)))((pic, hw, vw) => gap8Run(8)( - in |> - copyToL1 |> - allocL1 |> - mapSeq(fun(x =>x)) |> - allocL1 |> - copyToL2 - //gap8hwConv3x3(0)(in)(filter) + hw |> copyToL1 |> allocL1 |> letf(l1hw => + vw |> copyToL1 |> allocL1 |> letf(l1vw => + pic |> slide(80)(80) |> + mapSeq(fun(tile => + tile |> copyToL1 |> allocL1 |> letf(l1tile => + gap8hwConv3x3(0)(l1tile, l1hw) |> letf(hconvres => + gap8hwConv3x3(0)(l1tile, l1vw) |> letf(vconvres => + zipND(2)(hconvres, vconvres) |> mapPar(fun((h, v) => + gapSqrt(add(h * h)(v * v)) + )) |> allocL1 |> copyToL2 + ) + ) + ) + )) + ) + ) ) ) - } - println(translateToString(util.gen.gap8.hosted.fromExpr(twoDandHWCE))) - * */ + + //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce2))) + + val simpleNoSlide: ToBeTyped[Rise] = + fun( + ArrayType(size, ArrayType(size, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(size - 2, ArrayType(size - 2, i16)))((pic, hw, vw) => + gap8Run(8)( + hw |> copyToL1 |> allocL1 |> letf(l1hw => + vw |> copyToL1 |> allocL1 |> letf(l1vw => + pic |> copyToL1 |> allocL1 |> letf(l1pic => + gap8hwConv3x3(0)(l1pic, l1hw) |> allocL1 |> letf (hconvres => //hconvres |> copyToL2 + gap8hwConv3x3(0)(l1pic, l1vw) |> allocL1 |> letf (vconvres => + zip(hconvres)(vconvres) |> mapPar(fun(x => + add(fst(x))(snd(x)) + )) |> allocL1 |> copyToL2 + ) + ) + ) + ) + ) + ) + ) + println(translateToString(util.gen.gap8.hosted("doubleconv").fromExpr(simpleNoSlide))) } } From 3e08918015f59a974bc1aa4396a4529e0de66db9 Mon Sep 17 00:00:00 2001 From: Michel Steuwer Date: Thu, 18 May 2023 17:30:13 +0100 Subject: [PATCH 64/86] Fixed bug with updateRanges --- src/main/scala/shine/C/Compilation/CodeGenerator.scala | 1 + .../shine/GAP8/Compilation/AcceleratorCodeGenerator.scala | 3 +++ src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala | 4 ++++ .../scala/shine/OpenCL/Compilation/HostCodeGenerator.scala | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/src/main/scala/shine/C/Compilation/CodeGenerator.scala b/src/main/scala/shine/C/Compilation/CodeGenerator.scala index 2efd4a8a5..759a8d2e7 100644 --- a/src/main/scala/shine/C/Compilation/CodeGenerator.scala +++ b/src/main/scala/shine/C/Compilation/CodeGenerator.scala @@ -67,6 +67,7 @@ class CodeGenerator(val decls: CodeGenerator.Declarations, } + // Must be overridden by every subclass def updatedRanges(key: String, value: arithexpr.arithmetic.Range): CodeGenerator = new CodeGenerator(decls, ranges.updated(key, value)) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 8325c7be6..d6e3bc24c 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -22,6 +22,9 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def translationContext: TranslationContext = super.translationContext + override def updatedRanges(key: String, value: arithexpr.arithmetic.Range): AcceleratorCodeGenerator = + new AcceleratorCodeGenerator(decls, ranges.updated(key, value)) + override def exp(env: Environment, path: List[shine.C.Compilation.CodeGenerator.PathExpr], cont: Expr => Stmt): Phrase[ExpType] => Stmt = { diff --git a/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala index 1035b7bad..67870c187 100644 --- a/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/HostCodeGenerator.scala @@ -30,6 +30,10 @@ case class HostCodeGenerator( ) extends CodeGenerator(decls, ranges){ override def name: String = "GAP8 Host" + override def updatedRanges(key: String, + value: arithexpr.arithmetic.Range): HostCodeGenerator = + new HostCodeGenerator(decls, ranges.updated(key, value), acceleratorFunctions) + override def cmd(env: Environment): Phrase[CommType] => Stmt = { case k@KernelCallCmd(kernelName, numCores, numArgs) => val calledKernel = acceleratorFunctions diff --git a/src/main/scala/shine/OpenCL/Compilation/HostCodeGenerator.scala b/src/main/scala/shine/OpenCL/Compilation/HostCodeGenerator.scala index 857cec97e..b779652f0 100644 --- a/src/main/scala/shine/OpenCL/Compilation/HostCodeGenerator.scala +++ b/src/main/scala/shine/OpenCL/Compilation/HostCodeGenerator.scala @@ -26,6 +26,10 @@ case class HostCodeGenerator(override val decls: C.Compilation.CodeGenerator.Dec { override def name: String = "OpenCL Host" + override def updatedRanges(key: String, + value: arithexpr.arithmetic.Range): HostCodeGenerator = + new HostCodeGenerator(decls, ranges.updated(key, value), kernelModules) + override def cmd(env: Environment): Phrase[CommType] => Stmt = { case k@KernelCallCmd(name, LocalSize(ls), GlobalSize(gs), n) => kernelCallCmd(name, ls, gs, k.output, k.args, env) From a1c27646558354a3ee8d4d30495ba3bca662125f Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 19 May 2023 09:21:02 +0200 Subject: [PATCH 65/86] Changed (fixed) HWCE primitives to conform to row-first 2D array model --- .../rise/GAP8/primitives/gap8hwConv3x3.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv5x5.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv7x4.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv7x7.scala | 2 +- .../rise/GAP8/primitives/primitives.rise | 24 +++++++++---------- .../Compilation/AcceptorTranslation.scala | 2 +- .../shine/DPIA/InferAccessAnnotation.scala | 2 +- src/main/scala/shine/DPIA/fromRise.scala | 2 +- .../AcceleratorCodeGenerator.scala | 6 ++--- .../primitives/functional/FunConv3x3.scala | 4 ++-- .../primitives/functional/FunConv5x5.scala | 4 ++-- .../primitives/functional/FunConv7x4.scala | 6 ++--- .../primitives/functional/FunConv7x7.scala | 4 ++-- .../primitives/functional/primitives.dpia | 18 +++++++------- .../GAP8/primitives/imperative/Conv3x3.scala | 4 ++-- .../GAP8/primitives/imperative/Conv5x5.scala | 2 +- .../GAP8/primitives/imperative/Conv7x4.scala | 4 ++-- .../GAP8/primitives/imperative/Conv7x7.scala | 4 ++-- .../primitives/imperative/primitives.dpia | 14 +++++------ src/test/scala/shine/GAP8/hwce.scala | 2 +- 20 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala index fec7815c8..27d9d6320 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala @@ -13,7 +13,7 @@ object gap8hwConv3x3 extends Builder { override val name: String = "gap8hwConv3x3" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(3, ArrayType(3, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(3, ArrayType(3, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } override def toString: String = "gap8hwConv3x3" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala index b4884472b..c3526f5a9 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala @@ -13,7 +13,7 @@ object gap8hwConv5x5 extends Builder { override val name: String = "gap8hwConv5x5" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(5, ArrayType(5, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(5, ArrayType(5, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } override def toString: String = "gap8hwConv5x5" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala index e4280176b..60816d37a 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala @@ -13,7 +13,7 @@ object gap8hwConv7x4 extends Builder { override val name: String = "gap8hwConv7x4" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(7, ArrayType(4, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(4, ArrayType(7, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } override def toString: String = "gap8hwConv7x4" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala index 7b42053e6..7f073e58e 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala @@ -13,7 +13,7 @@ object gap8hwConv7x7 extends Builder { override val name: String = "gap8hwConv7x7" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (iw: Nat) => impl { (ih: Nat) => impl { (ow: Nat) => impl { (oh: Nat) => impl { (s: DataType) => ArrayType(iw, ArrayType(ih, s)) ->: ArrayType(7, ArrayType(7, s)) ->: ArrayType(ow, ArrayType(oh, s)) } } } } } } + override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(7, ArrayType(7, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } } override def toString: String = "gap8hwConv7x7" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 59323f6a2..56360abf4 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -1,24 +1,24 @@ def gap8RunPrimitive: (cores: nat) -> {t: data} -> t -> t -def gap8hwConv3x3: (bias: nat) -> {iw: nat} -> {ih: nat} -> - {ow: nat} -> {oh: nat} -> +def gap8hwConv3x3: (bias: nat) -> {ih: nat} -> {iw: nat} -> + {oh: nat} -> {ow: nat} -> {s: data} -> - iw.ih.s -> 3.3.s -> ow.oh.s + ih.iw.s -> 3.3.s -> oh.ow.s -def gap8hwConv5x5: (bias: nat) -> {iw: nat} -> {ih: nat} -> - {ow: nat} -> {oh: nat} -> +def gap8hwConv5x5: (bias: nat) -> {ih: nat} -> {iw: nat} -> + {oh: nat} -> {ow: nat} -> {s: data} -> - iw.ih.s -> 5.5.s -> ow.oh.s + ih.iw.s -> 5.5.s -> oh.ow.s -def gap8hwConv7x7: (bias: nat) -> {iw: nat} -> {ih: nat} -> - {ow: nat} -> {oh: nat} -> +def gap8hwConv7x7: (bias: nat) -> {ih: nat} -> {iw: nat} -> + {oh: nat} -> {ow: nat} -> {s: data} -> - iw.ih.s -> 7.7.s -> ow.oh.s + ih.iw.s -> 7.7.s -> oh.ow.s -def gap8hwConv7x4: (bias: nat) -> {iw: nat} -> {ih: nat} -> - {ow: nat} -> {oh: nat} -> +def gap8hwConv7x4: (bias: nat) -> {ih: nat} -> {iw: nat} -> + {oh: nat} -> {ow: nat} -> {s: data} -> - iw.ih.s -> 7.4.s -> ow.oh.s + ih.iw.s -> 4.7.s -> oh.ow.s def copyToL1: {t: data} -> t -> t def copyToL2: {t: data} -> t -> t diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index 23e854997..6f90b49d5 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -430,7 +430,7 @@ object AcceptorTranslation { case gap8.FunConv7x4(w, h, bias, dt, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { val paddedArray = gap8.Cast( - ArrayType(7, ArrayType(4, dt)), + ArrayType(4, ArrayType(7, dt)), ArrayType(28, dt), filter ) diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index 2d42cb2f0..dfa76bb39 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -634,7 +634,7 @@ private class InferAccessAnnotation { case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) - ->: expT(ArrayType(7, ArrayType(4, s)), read) ->: + ->: expT(ArrayType(4, ArrayType(7, s)), read) ->: expT(ArrayType(oh, ArrayType(ow, s)), write) ) } diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index 1c1040f67..a75904688 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -974,7 +974,7 @@ object fromRise { expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => depFun(NatKind, bias)( fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => - fun[ExpType](expT(ArrayType(7, ArrayType(4, s)), read), filter => + fun[ExpType](expT(ArrayType(4, ArrayType(7, s)), read), filter => gap8.FunConv7x4(w, h, bias, s, input, filter) ) ) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index d6e3bc24c..80635db98 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -44,7 +44,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) }) - case Conv5x5(w, h, bias, dt, in, filter: Identifier[ExpType], out) => + case Conv5x5(w, h, bias, dt, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { @@ -52,7 +52,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) }) - case Conv7x7(w, h, bias, dt, in, filter: Identifier[ExpType], out) => + case Conv7x7(w, h, bias, dt, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { @@ -60,7 +60,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D }) }) }) - case Conv7x4(w, h, bias, dt, in, filter: Identifier[ExpType], out) => + case Conv7x4(w, h, bias, dt, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala index 8df7ff9c8..4048bba72 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(3, ArrayType(3, dt)), read) true } - override val t: ExpType = expT(ArrayType(w - 2, ArrayType(h - 2, dt)), write) + override val t: ExpType = expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv3x3 = new FunConv3x3(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala index f8952e35b..2e9c719fe 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(5, ArrayType(5, dt)), read) true } - override val t: ExpType = expT(ArrayType(w - 4, ArrayType(h - 4, dt)), write) + override val t: ExpType = expT(ArrayType(h - 4, ArrayType(w - 4, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv5x5 = new FunConv5x5(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala index 7cb40a040..a253f3a44 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) - filter :: expT(ArrayType(7, ArrayType(4, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) + filter :: expT(ArrayType(4, ArrayType(7, dt)), read) true } - override val t: ExpType = expT(ArrayType(w - 6, ArrayType(h - 3, dt)), write) + override val t: ExpType = expT(ArrayType(h - 3, ArrayType(w - 6, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x4 = new FunConv7x4(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala index b9def4e85..b50c33b8b 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala @@ -11,10 +11,10 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class FunConv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(7, ArrayType(7, dt)), read) true } - override val t: ExpType = expT(ArrayType(w - 6, ArrayType(h - 6, dt)), write) + override val t: ExpType = expT(ArrayType(h - 6, ArrayType(w - 6, dt)), write) override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x7 = new FunConv7x7(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index d6ec00141..568326d67 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -7,36 +7,36 @@ def funConv3x3( h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[3.3.dt, read] -): exp[(w-2).(h-2).dt, write] +): exp[(h-2).(w-2).dt, write] def funConv5x5( w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[5.5.dt, read] -): exp[(w-4).(h-4).dt, write] +): exp[(h-4).(w-4).dt, write] def funConv7x7( w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[7.7.dt, read] -): exp[(w-6).(h-6).dt, write] +): exp[(h-6).(w-6).dt, write] def funConv7x4( w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], - filter: exp[7.4.dt, read] -): exp[(w-6).(h-3).dt, write] + in: exp[h.w.dt, read], + filter: exp[4.7.dt, read] +): exp[(h-3).(w-6).dt, write] def copyToL1(dt: data, input: exp[dt, read]): exp[dt, write] def copyToL2(dt: data, input: exp[dt, read]): exp[dt, write] diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala index e43cffeba..294121c87 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(10, dt), read) - out :: accT(ArrayType(w - 2, ArrayType(h - 2, dt))) + out :: accT(ArrayType(h - 2, ArrayType(w - 2, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala index 88706fe8b..6a87e3c8b 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala @@ -13,7 +13,7 @@ final case class Conv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType assert { in :: expT(ArrayType(w, ArrayType(h, dt)), read) filter :: expT(ArrayType(26, dt), read) - out :: accT(ArrayType(w - 4, ArrayType(h - 4, dt))) + out :: accT(ArrayType(h - 4, ArrayType(w - 4, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala index f8702b79d..2fc925825 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(28, dt), read) - out :: accT(ArrayType(w - 6, ArrayType(h - 3, dt))) + out :: accT(ArrayType(h - 3, ArrayType(w - 6, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala index 39d96b18a..3073fad9f 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala @@ -11,9 +11,9 @@ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ final case class Conv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(56, dt), read) - out :: accT(ArrayType(w - 6, ArrayType(h - 6, dt))) + out :: accT(ArrayType(h - 6, ArrayType(w - 6, dt))) true } override val t: CommType = comm diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index 6dfd9acfb..80d37b5da 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -5,9 +5,9 @@ def conv3x3(w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[10.dt, read], - out: acc[(w-2).(h-2).dt]): comm + out: acc[(h-2).(w-2).dt]): comm def conv5x5(w: nat, h: nat, @@ -15,23 +15,23 @@ def conv5x5(w: nat, dt: data, in: exp[w.h.dt, read], filter: exp[26.dt, read], - out: acc[(w-4).(h-4).dt]): comm + out: acc[(h-4).(w-4).dt]): comm def conv7x7(w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[56.dt, read], - out: acc[(w-6).(h-6).dt]): comm + out: acc[(h-6).(w-6).dt]): comm def conv7x4(w: nat, h: nat, bias: nat, dt: data, - in: exp[w.h.dt, read], + in: exp[h.w.dt, read], filter: exp[28.dt, read], - out: acc[(w-6).(h-3).dt]): comm + out: acc[(h-3).(w-6).dt]): comm def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, read], dst: acc[dt]): comm def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm \ No newline at end of file diff --git a/src/test/scala/shine/GAP8/hwce.scala b/src/test/scala/shine/GAP8/hwce.scala index acb80eaaf..b5d1eb0e7 100644 --- a/src/test/scala/shine/GAP8/hwce.scala +++ b/src/test/scala/shine/GAP8/hwce.scala @@ -239,7 +239,7 @@ class hwce extends test_util.Tests { * HWCE_ProcessOneTile7x4(e1, output, e2, 0, n, m) * */ val expr: ToBeTyped[Rise] = { - fun((w`.`h`.`i16) ->: (7`.`4`.`i16) ->: ((w - 6)`.`(h - 3)`.`i16))((in, filter) => + fun((h`.`w`.`i16) ->: (4`.`7`.`i16) ->: ((h - 3)`.`(w - 6)`.`i16))((in, filter) => gap8Run(8)( gap8hwConv7x4(0)(in)(filter) ) From 7d700167e7d7dd8fec03304c693168109e900563 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 19 May 2023 09:58:17 +0200 Subject: [PATCH 66/86] Dma / Hwce / Tiling WIP --- src/main/scala/apps/GAP8HwceDma.scala | 48 ++++++++++++++++----------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 5480f2a2b..5cf21c89c 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -6,7 +6,7 @@ import rise.core.DSL.HighLevelConstructs.{slide2D, zipND} import rise.core.DSL.Type.TypeConstructors import rise.core.DSL.Type.`.` import rise.core.DSL.{ToBeTyped, TypeAnnotationHelper, depFun, foreignFun, fun, let, letf, li16, lu8} -import rise.core.primitives.{add, cast, fst, join, mapSeq, padCst, slide, snd, zip} +import rise.core.primitives.{add, cast, fst, join, mapSeq, padCst, slide, snd, transpose, zip} import rise.core.types.DataType.{ArrayType, i16, u8} import rise.core.types.Nat import rise.elevate.Rise @@ -80,11 +80,12 @@ object GAP8HwceDma { ) //println(translateToString(util.gen.gap8.hosted("conv").fromExpr(fixSizeDmaHwce))) - val n: Nat = 320 + val n: Nat = 322 val m: Nat = 240 val numStripes: Nat = 12 val stripeSize: Nat = n * (m / numStripes) val tileSize: Nat = 80 * 80 + val stripeHeight: Nat = m / numStripes val tiledFixSizeDmaHwce: ToBeTyped[Rise] = fun( ArrayType(n, ArrayType(m, i16)) ->: @@ -94,26 +95,30 @@ object GAP8HwceDma { gap8Run(8)( hw |> copyToL1 |> allocL1 |> letf(l1hw => vw |> copyToL1 |> allocL1 |> letf(l1vw => - pic |> slide(stripeSize)(stripeSize - 1) |> + // + pic |> slide(18)(16) |> mapSeq(fun(stripe => + //stripe + //stripe is 2D stripe |> copyToL1 |> allocL1 |> letf(l1stripe => - l1stripe |> mapPar(fun(row => row |> padCst(1)(1)(li16(0)))) |> // mapSeq(fun(x => cast(x) :: i16)) |> - letf(l1convstripe => - gap8hwConv3x3(0)(l1convstripe, l1hw) |> letf(hconvres => - gap8hwConv3x3(0)(l1convstripe, l1vw) |> letf(vconvres => - zip(hconvres)(vconvres) |> - mapPar(fun((h, v) => - gapSqrt(add(h * h)(v * v)) - )) |> allocL1 |> copyToL2 - ) + l1stripe |> // |> mapPar(fun(row => row |> padCst(1)(1)(li16(0)))) // |> + letf(l1convstripe => + gap8hwConv3x3(0)(l1convstripe, l1hw) |> allocL1 |> letf(hconvres => + gap8hwConv3x3(0)(l1convstripe, l1vw) |> allocL1 |> letf(vconvres => + zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => + add(fst(elems))(snd(elems)) + ))) |> allocL1 |> copyToL2 ) ) - ))) + ) + ) + ) + ) |> join ) ) ) ) - //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) + println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) val tiledFixSizeDmaHwce2: ToBeTyped[Rise] = fun( @@ -153,11 +158,16 @@ object GAP8HwceDma { hw |> copyToL1 |> allocL1 |> letf(l1hw => vw |> copyToL1 |> allocL1 |> letf(l1vw => pic |> copyToL1 |> allocL1 |> letf(l1pic => - gap8hwConv3x3(0)(l1pic, l1hw) |> allocL1 |> letf (hconvres => //hconvres |> copyToL2 + gap8hwConv3x3(0)(l1pic, l1hw) |> allocL1 |> letf (hconvres => // hconvres |> copyToL2 gap8hwConv3x3(0)(l1pic, l1vw) |> allocL1 |> letf (vconvres => - zip(hconvres)(vconvres) |> mapPar(fun(x => - add(fst(x))(snd(x)) - )) |> allocL1 |> copyToL2 + zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => + add(fst(elems))(snd(elems)) + ))) |> allocL1 |> copyToL2 + /*zip(hconvres)(vconvres) |> mapPar(fun(rows => + zip(fst(rows))(snd(rows)) |> mapPar(fun(elems => + add(fst(elems))(snd(elems)) + )) + )) |> allocL1 |> copyToL2*/ ) ) ) @@ -165,6 +175,6 @@ object GAP8HwceDma { ) ) ) - println(translateToString(util.gen.gap8.hosted("doubleconv").fromExpr(simpleNoSlide))) + //println(translateToString(util.gen.gap8.hosted("doubleconv").fromExpr(simpleNoSlide))) } } From a2e0de4c3d2532d9822d611b411e3fa4ee49708c Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 22 May 2023 10:11:05 +0200 Subject: [PATCH 67/86] Added GAP8-specific part of the syntax checking pipeline (fixes syntax checking failing due to the use of undeclared identifier error --- src/main/scala/util/SyntaxChecker.scala | 10 ++++++++++ src/main/scala/util/gen.scala | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/scala/util/SyntaxChecker.scala b/src/main/scala/util/SyntaxChecker.scala index 60f747329..2f16d9c2d 100644 --- a/src/main/scala/util/SyntaxChecker.scala +++ b/src/main/scala/util/SyntaxChecker.scala @@ -29,6 +29,16 @@ object SyntaxChecker { throw Exception(s"Code: `$code' did not pass syntax check") } } + /** + * TODO: clang emits "error: use of undeclared identifier 'ARCHI_CL_EVT_ACC0'". + * TODO: Think of a better way to make the code pass syntax checking + * */ + + @throws[SyntaxChecker.Exception]("if code does not pass the GAP8-like syntax check") + def checkGAP8(code: String): Unit = { + val mockDefine = "#define ARCHI_CL_EVT_ACC0 12" + apply(mockDefine + "\n" + code) + } @throws[SyntaxChecker.Exception]("if code doesn't pass the OpenCL syntax check") def checkOpenCL(code: String): Unit = { diff --git a/src/main/scala/util/gen.scala b/src/main/scala/util/gen.scala index 84c3e6ea4..5a26c19b2 100644 --- a/src/main/scala/util/gen.scala +++ b/src/main/scala/util/gen.scala @@ -123,7 +123,7 @@ object gen { functionFromExpr(name, gen) andThen GAP8.Module.injectUnpacking andThen C.Module.translateToString andThen - run(SyntaxChecker(_)) + run(SyntaxChecker.checkGAP8(_)) } type HostedModule = GAP8.Module From 4b1d0c62b89dde02a9b4ce8c56e08e724a37466c Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 23 May 2023 08:56:35 +0200 Subject: [PATCH 68/86] WIP: Slide() debug, added more examples --- src/main/scala/apps/GAP8HwceDma.scala | 110 +++++++++++++++++--------- 1 file changed, 71 insertions(+), 39 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 5cf21c89c..8af34ec14 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -80,32 +80,92 @@ object GAP8HwceDma { ) //println(translateToString(util.gen.gap8.hosted("conv").fromExpr(fixSizeDmaHwce))) - val n: Nat = 322 - val m: Nat = 240 + //Passes + val theSmallestSlide: ToBeTyped[Rise] = fun( + ArrayType(5, i16) ->: ArrayType(3, ArrayType(3, i16)) + )(arr => + gap8Run(8)( + arr |> slide(3)(1) |> mapSeq(mapSeq(fun(elem => add(elem)(li16(1))))) + ) + ) + //printf(translateToString(util.gen.gap8.hosted("theSmallest").fromExpr(theSmallestSlide))) + translateToString(util.gen.gap8.hosted("theSmallest").fromExpr(theSmallestSlide)) + println("======================================================================") + + val inBetweenSlideExample: ToBeTyped[Rise] = fun( + ArrayType(5, i16) ->: ArrayType(3, ArrayType(3, i16)) + )(arr => + gap8Run(8)( + arr |> slide(3)(1) |> mapSeq(fun(tile => + tile |> letf(tstletf => + tstletf |> mapSeq(fun(elem => add(elem)(li16(1)))) + ) + )) + ) + ) + println(translateToString(util.gen.gap8.hosted("inBetween").fromExpr(inBetweenSlideExample))) + //translateToString(util.gen.gap8.hosted("inBetween").fromExpr(inBetweenSlideExample)) + println("======================================================================") + //Does not pass + val evenSmallerSlideExample: ToBeTyped[Rise] = fun( + ArrayType(5, i16) ->: ArrayType(3, ArrayType(3, i16)) + )(arr => + gap8Run(8)( + arr |> slide(3)(1) |> mapSeq(fun(tile => + tile |> copyToL1 |> allocL1 |> letf(tilel1 => + tilel1 |> mapSeq(fun(elem => add(elem)(li16(1)))) |> allocL1 |> copyToL2 + ) + )) + ) + ) + //println(translateToString(util.gen.gap8.hosted("evenSmallerSlideExample").fromExpr(evenSmallerSlideExample))) + //translateToString(util.gen.gap8.hosted("evenSmallerSlideExample").fromExpr(evenSmallerSlideExample)) + + //No way + val minSlideExample: ToBeTyped[Rise] = fun( + ArrayType(5, ArrayType(5, i16)) ->: + ArrayType(3, ArrayType(5, i16)) ->: + ArrayType(9, ArrayType(5, i16)))((sth, filter) => + gap8Run(8)( + sth |> slide(3)(1) |> mapSeq(fun(tile => + tile |> copyToL1 |> allocL1 |> letf(tilel1 => + zipND(2)(tilel1, filter) |> mapPar(mapPar(fun(elems => + add(fst(elems))(snd(elems)) + ))) |> allocL1 |> copyToL2 + ) + )) |> join + ) + ) + //println(translateToString(util.gen.gap8.hosted("minSlide").fromExpr(minSlideExample))) + + //old w=322, slide(18)(16) + val w: Nat = 320 + val h: Nat = 240 val numStripes: Nat = 12 - val stripeSize: Nat = n * (m / numStripes) - val tileSize: Nat = 80 * 80 - val stripeHeight: Nat = m / numStripes + val stripeSize: Nat = w * (h / numStripes) + val stripeHeight: Nat = h / numStripes + //Are you serious? val tiledFixSizeDmaHwce: ToBeTyped[Rise] = fun( - ArrayType(n, ArrayType(m, i16)) ->: + ArrayType(h, ArrayType(w, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: - ArrayType(n - 2, ArrayType(m - 2, i16)))((pic, hw, vw) => + ArrayType(h - 2, ArrayType(w - 2, i16)))((pic, hw, vw) => gap8Run(8)( hw |> copyToL1 |> allocL1 |> letf(l1hw => vw |> copyToL1 |> allocL1 |> letf(l1vw => - // - pic |> slide(18)(16) |> + pic |> slide(16)(14) |> mapSeq(fun(stripe => //stripe //stripe is 2D stripe |> copyToL1 |> allocL1 |> letf(l1stripe => - l1stripe |> // |> mapPar(fun(row => row |> padCst(1)(1)(li16(0)))) // |> + l1stripe |> // |> mapPar(fun(row => row |> padCst(1)(1)(li16(0)))) |> letf(l1convstripe => gap8hwConv3x3(0)(l1convstripe, l1hw) |> allocL1 |> letf(hconvres => gap8hwConv3x3(0)(l1convstripe, l1vw) |> allocL1 |> letf(vconvres => zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => + //gapSqrt + //pad left,right somewhere? add(fst(elems))(snd(elems)) ))) |> allocL1 |> copyToL2 ) @@ -118,35 +178,7 @@ object GAP8HwceDma { ) ) ) - println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) - - val tiledFixSizeDmaHwce2: ToBeTyped[Rise] = - fun( - ArrayType(n, ArrayType(m, i16)) ->: - ArrayType(3, ArrayType(3, i16)) ->: - ArrayType(3, ArrayType(3, i16)) ->: - ArrayType(n - 2, ArrayType(m - 2, i16)))((pic, hw, vw) => - gap8Run(8)( - hw |> copyToL1 |> allocL1 |> letf(l1hw => - vw |> copyToL1 |> allocL1 |> letf(l1vw => - pic |> slide(80)(80) |> - mapSeq(fun(tile => - tile |> copyToL1 |> allocL1 |> letf(l1tile => - gap8hwConv3x3(0)(l1tile, l1hw) |> letf(hconvres => - gap8hwConv3x3(0)(l1tile, l1vw) |> letf(vconvres => - zipND(2)(hconvres, vconvres) |> mapPar(fun((h, v) => - gapSqrt(add(h * h)(v * v)) - )) |> allocL1 |> copyToL2 - ) - ) - ) - )) - ) - ) - ) - ) - - //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce2))) + //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) val simpleNoSlide: ToBeTyped[Rise] = fun( From 8a05f1ee62864e7c5dcb1c1f5e3bd41d6d04a256 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 26 May 2023 14:23:35 +0200 Subject: [PATCH 69/86] Adding CIntExpr(0) to path when calling acc / exp (DmaCopy codegen) --- .../shine/GAP8/Compilation/AcceleratorCodeGenerator.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 80635db98..897155ce2 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -3,6 +3,7 @@ package shine.GAP8.Compilation import arithexpr.arithmetic import arithexpr.arithmetic.ArithExpr import rise.core.types.DataType +import shine.C.Compilation.CodeGenerator.CIntExpr import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} import shine.DPIA.Nat import shine.DPIA.Phrases.{Identifier, Lambda, Phrase, PhrasePair} @@ -80,8 +81,8 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D * */ case copy@DmaCopy(transferType) => val size = shine.GAP8.AST.Types.sizeInBytes(copy.dt) - copy.dst |> acc(env, Nil, (dstC: C.AST.Expr) => { - copy.src |> exp(env, Nil, (srcC: C.AST.Expr) => { + copy.dst |> acc(env, List(CIntExpr(0)), (dstC: C.AST.Expr) => { + copy.src |> exp(env, List(CIntExpr(0)), (srcC: C.AST.Expr) => { val (ext, loc) = transferType match { case shine.GAP8.L1toL2 => (dstC, srcC) @@ -92,6 +93,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D C.AST.ExprStmt(C.AST.FunCall( C.AST.DeclRef("rt_dma_memcpy"), Seq( + // TODO: Reference fetch via ampersand might be needed (ext,loc) ext, loc, C.AST.Literal(size.toString), From 1455d3e48a7f08ef5bd6cf06410b379e18a4881c Mon Sep 17 00:00:00 2001 From: bpervan Date: Thu, 1 Jun 2023 14:39:09 +0200 Subject: [PATCH 70/86] WIP --- src/main/scala/apps/GAP8HwceDma.scala | 52 ++++++++++++++------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 8af34ec14..df77963bd 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -2,11 +2,10 @@ package apps import rise.GAP8.DSL.gap8Run import rise.GAP8.primitives.{allocL1, copyToL1, copyToL2, gap8hwConv3x3} -import rise.core.DSL.HighLevelConstructs.{slide2D, zipND} +import rise.core.DSL.HighLevelConstructs.{padCst2D, zipND} import rise.core.DSL.Type.TypeConstructors -import rise.core.DSL.Type.`.` -import rise.core.DSL.{ToBeTyped, TypeAnnotationHelper, depFun, foreignFun, fun, let, letf, li16, lu8} -import rise.core.primitives.{add, cast, fst, join, mapSeq, padCst, slide, snd, transpose, zip} +import rise.core.DSL.{ToBeTyped, depFun, foreignFun, fun, letf, li16} +import rise.core.primitives._ import rise.core.types.DataType.{ArrayType, i16, u8} import rise.core.types.Nat import rise.elevate.Rise @@ -89,7 +88,7 @@ object GAP8HwceDma { ) ) //printf(translateToString(util.gen.gap8.hosted("theSmallest").fromExpr(theSmallestSlide))) - translateToString(util.gen.gap8.hosted("theSmallest").fromExpr(theSmallestSlide)) + //translateToString(util.gen.gap8.hosted("theSmallest").fromExpr(theSmallestSlide)) println("======================================================================") val inBetweenSlideExample: ToBeTyped[Rise] = fun( @@ -97,16 +96,30 @@ object GAP8HwceDma { )(arr => gap8Run(8)( arr |> slide(3)(1) |> mapSeq(fun(tile => - tile |> letf(tstletf => - tstletf |> mapSeq(fun(elem => add(elem)(li16(1)))) + tile |> copyToL1 |> allocL1 |> letf(tstletf => + tstletf |> mapSeq(fun(elem => add(elem)(li16(1)))) |> allocL1 |> copyToL2 ) )) ) ) - println(translateToString(util.gen.gap8.hosted("inBetween").fromExpr(inBetweenSlideExample))) + //println(translateToString(util.gen.gap8.hosted("inBetween").fromExpr(inBetweenSlideExample))) //translateToString(util.gen.gap8.hosted("inBetween").fromExpr(inBetweenSlideExample)) println("======================================================================") + //Does not pass + val thisMaybe: ToBeTyped[Rise] = fun( + ArrayType(5, i16) ->: ArrayType(9, i16) + )(arr => + gap8Run(8)( + arr |> slide(3)(1) |> join |> copyToL1 |> allocL1 |> letf(sth => + sth |> mapSeq(fun(elem => add(elem)(li16(1)))) |> allocL1 |> copyToL2 + ) + ) + ) + //println(translateToString(util.gen.gap8.hosted("thisMaybe").fromExpr(thisMaybe))) + //translateToString(util.gen.gap8.hosted("thisMaybe").fromExpr(thisMaybe)) + + //Does not pass either val evenSmallerSlideExample: ToBeTyped[Rise] = fun( ArrayType(5, i16) ->: ArrayType(3, ArrayType(3, i16)) )(arr => @@ -138,47 +151,38 @@ object GAP8HwceDma { ) //println(translateToString(util.gen.gap8.hosted("minSlide").fromExpr(minSlideExample))) - //old w=322, slide(18)(16) val w: Nat = 320 val h: Nat = 240 - val numStripes: Nat = 12 - val stripeSize: Nat = w * (h / numStripes) - val stripeHeight: Nat = h / numStripes - //Are you serious? val tiledFixSizeDmaHwce: ToBeTyped[Rise] = fun( ArrayType(h, ArrayType(w, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: - ArrayType(h - 2, ArrayType(w - 2, i16)))((pic, hw, vw) => + ArrayType(h - 2, ArrayType(w, i16)))((pic, hw, vw) => gap8Run(8)( hw |> copyToL1 |> allocL1 |> letf(l1hw => vw |> copyToL1 |> allocL1 |> letf(l1vw => - pic |> slide(16)(14) |> + // pic |> padCst2D(1, 1, 0, 0)(li16(0)) |> slide(16)(14) |> + pic |> slide (16)(14) |> mapSeq(fun(stripe => - //stripe - //stripe is 2D stripe |> copyToL1 |> allocL1 |> letf(l1stripe => - l1stripe |> // |> mapPar(fun(row => row |> padCst(1)(1)(li16(0)))) |> + l1stripe |> padCst2D(0, 0, 1, 1)(li16(0)) |> letf(l1convstripe => gap8hwConv3x3(0)(l1convstripe, l1hw) |> allocL1 |> letf(hconvres => gap8hwConv3x3(0)(l1convstripe, l1vw) |> allocL1 |> letf(vconvres => zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => - //gapSqrt - //pad left,right somewhere? - add(fst(elems))(snd(elems)) + gapSqrt(add(mul(fst(elems))(fst(elems)))(mul(snd(elems))(snd(elems)))) ))) |> allocL1 |> copyToL2 ) ) ) ) - ) - ) |> join + )) |> join ) ) ) ) - //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) + println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) val simpleNoSlide: ToBeTyped[Rise] = fun( From 6d67bc7270e124c390f90c671e92ff31d753cefe Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 12 Jun 2023 10:28:04 +0200 Subject: [PATCH 71/86] WIP; Comment --- .../scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 897155ce2..8a02a33fe 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -202,6 +202,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D } } + //TODO: Lazy val private val hwceEnableCall = C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("HWCE_Enable"), Seq())) private val hwceDisableCall = C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("HWCE_Disable"), Seq())) private val hwceSoftResetCall = C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("HwCE_SoftReset"), Seq())) From 12ecfc115833b3ab94139e1db021ced972075a33 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 12 Jun 2023 14:04:24 +0200 Subject: [PATCH 72/86] copy2DOffsetToL1 primitive --- .../GAP8/primitives/copy2DOffsetToL1.scala | 25 +++++++++++++++++++ .../rise/GAP8/primitives/primitives.rise | 4 +++ .../functional/Copy2DOffsetToL1.scala | 19 ++++++++++++++ .../primitives/functional/primitives.dpia | 3 +++ 4 files changed, 51 insertions(+) create mode 100644 src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala create mode 100644 src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala diff --git a/src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala b/src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala new file mode 100644 index 000000000..458bf2d7c --- /dev/null +++ b/src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala @@ -0,0 +1,25 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package rise.GAP8.primitives +import rise.core.DSL._ +import rise.core.DSL.Type._ +import rise.core._ +import rise.core.types._ +import rise.core.types.DataType._ +import arithexpr.arithmetic._ +object copy2DOffsetToL1 extends Builder { + private final case class Primitive()(override val t: ExprType = TypePlaceholder) extends rise.core.Primitive { + override val name: String = "copy2DOffsetToL1" + override def setType(ty: ExprType): Primitive = Primitive()(ty) + override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass + override def typeScheme: ExprType = impl { (t: DataType) => impl { (n: Nat) => impl { (m: Nat) => expl { (offsetX: Nat) => expl { (offsetY: Nat) => ArrayType(n, ArrayType(m, t)) ->: ArrayType(n + 2 * offsetY, ArrayType(m + 2 * offsetX, t)) } } } } } + } + override def toString: String = "copy2DOffsetToL1" + override def primitive: rise.core.Primitive = Primitive()() + override def apply: ToBeTyped[rise.core.Primitive] = toBeTyped(Primitive()()) + override def unapply(arg: Expr): Boolean = arg match { + case _: Primitive => true + case _ => false + } +} diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 56360abf4..2fba5db52 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -23,5 +23,9 @@ def gap8hwConv7x4: (bias: nat) -> {ih: nat} -> {iw: nat} -> def copyToL1: {t: data} -> t -> t def copyToL2: {t: data} -> t -> t +def copy2DOffsetToL1: {t: data} -> {n: nat} -> {m: nat} + -> (offsetX: nat) -> (offsetY: nat) -> (n.m.t) + -> (n + 2 * offsetY).(m + 2 * offsetX).t + def allocL1: {t: data} -> t -> t def allocL2: {t: data} -> t -> t \ No newline at end of file diff --git a/src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala b/src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala new file mode 100644 index 000000000..28c4e0ea8 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala @@ -0,0 +1,19 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.functional +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Copy2DOffsetToL1(val dt: DataType, val n: Nat, val m: Nat, val offsetX: Nat, val offsetY: Nat, val input: Phrase[ExpType]) extends ExpPrimitive { + assert { + input :: expT(ArrayType(n, ArrayType(m, dt)), read) + true + } + override val t: ExpType = expT(ArrayType(n + 2 * offsetY, ArrayType(m + 2 * offsetX, dt)), write) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Copy2DOffsetToL1 = new Copy2DOffsetToL1(v.data(dt), v.nat(n), v.nat(m), v.nat(offsetX), v.nat(offsetY), VisitAndRebuild(input, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index 568326d67..cc346f503 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -41,6 +41,9 @@ def funConv7x4( def copyToL1(dt: data, input: exp[dt, read]): exp[dt, write] def copyToL2(dt: data, input: exp[dt, read]): exp[dt, write] +def copy2DOffsetToL1(dt: data, n: nat, m: nat, + offsetX: nat, offsetY: nat, input: exp[n.m.dt, read]): exp[(n+2*offsetY).(m+2*offsetX).dt, write] + def allocL1(dt: data, input: exp[dt, write]): exp[dt, read] def allocL2(dt: data, input: exp[dt, write]): exp[dt, read] From 1f283d5a5e2a1b71e337e23cee4ca0d2c5705cc8 Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 12 Jun 2023 14:04:51 +0200 Subject: [PATCH 73/86] copy2DOffsetToL1 translation --- .../scala/shine/DPIA/InferAccessAnnotation.scala | 9 +++++++++ src/main/scala/shine/DPIA/fromRise.scala | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index dfa76bb39..17887b136 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -651,8 +651,17 @@ private class InferAccessAnnotation { case _ => error() } + // case n `(Nat)->:` ((dt1: DataType) ->: (dt2: DataType)) => + // nFunT(n, expT(dt1, ai) ->: expT(dt2, ai)) + case rg8p.copy2DOffsetToL1() => p.t match { + case offsetX `(Nat)->:` (offsetY `(Nat)->:` ((ArrayType(n, ArrayType(m, t: DataType))) ->: (_: DataType))) => + nFunT(offsetX, nFunT(offsetY, expT(n`.`m`.`t, read) ->: expT((n + 2 * offsetY)`.`(m + 2 * offsetX)`.`t, write))) + case _ => error() + } + case rg8p.allocL1() => p.t match { case (dt: DataType) ->: (_: DataType) => + println(dt) expT(dt, write) ->: expT(dt, read) case _ => error() } diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index a75904688..15852e4cb 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -990,6 +990,19 @@ object fromRise { case expT(dt, `read`) ->: expT(_, `write`) => fun[ExpType](expT(dt, read), e => gap8.CopyToL2(dt, e)) } + //case nFunT(n, expT(ArrayType(_, t), a) ->: + // expT(ArrayType(m, ArrayType(_, _)), _)) + // => + // depFun(NatKind, n)( + // fun[ExpType](expT({m*n}`.`t, a), e => + // Split(n, m, a, t, e))) + + case rgap8.copy2DOffsetToL1() => fromType { + case nFunT(offsetX, nFunT(offsetY, expT(ArrayType(n, ArrayType(m, t)), `read`) ->: expT(_, `write`))) => + depFun(NatKind, offsetX)(depFun(NatKind, offsetY)(fun[ExpType](expT(n`.`m`.`t, read), input => + gap8.Copy2DOffsetToL1(t, n, m, offsetX, offsetY, input) + ))) + } case rgap8.allocL1() => fromType { case expT(dt, `write`) ->: expT(_, `read`) => From bf5407cf47db38479895720fa5cf80106fc220ba Mon Sep 17 00:00:00 2001 From: bpervan Date: Mon, 12 Jun 2023 14:05:16 +0200 Subject: [PATCH 74/86] WIP tiledFixSizeDmaHwce app --- src/main/scala/apps/GAP8HwceDma.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index df77963bd..c33f6b2ea 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -1,7 +1,7 @@ package apps import rise.GAP8.DSL.gap8Run -import rise.GAP8.primitives.{allocL1, copyToL1, copyToL2, gap8hwConv3x3} +import rise.GAP8.primitives.{allocL1, copy2DOffsetToL1, copyToL1, copyToL2, gap8hwConv3x3} import rise.core.DSL.HighLevelConstructs.{padCst2D, zipND} import rise.core.DSL.Type.TypeConstructors import rise.core.DSL.{ToBeTyped, depFun, foreignFun, fun, letf, li16} @@ -162,11 +162,12 @@ object GAP8HwceDma { gap8Run(8)( hw |> copyToL1 |> allocL1 |> letf(l1hw => vw |> copyToL1 |> allocL1 |> letf(l1vw => - // pic |> padCst2D(1, 1, 0, 0)(li16(0)) |> slide(16)(14) |> - pic |> slide (16)(14) |> + // pic |> padCst2D(1, 1, 0, 0)(li16(0)) |> slide(16)(14) |> + pic |> slide (16)(14) |> mapSeq(fun(stripe => - stripe |> copyToL1 |> allocL1 |> letf(l1stripe => - l1stripe |> padCst2D(0, 0, 1, 1)(li16(0)) |> + stripe |> copy2DOffsetToL1(1)(1) |> allocL1 |> // letf(l1stripe => + // l1stripe |> padCst2D(0, 0, 1, 1)(li16(0)) |> + // mapSeq(mapSeq(fun(x => x))) |> allocL1 |> letf(l1convstripe => gap8hwConv3x3(0)(l1convstripe, l1hw) |> allocL1 |> letf(hconvres => gap8hwConv3x3(0)(l1convstripe, l1vw) |> allocL1 |> letf(vconvres => @@ -175,7 +176,7 @@ object GAP8HwceDma { ))) |> allocL1 |> copyToL2 ) ) - ) + // ) ) )) |> join ) From 3600b73ad27ffef78b603a7b9790704f0a68e708 Mon Sep 17 00:00:00 2001 From: Michel Steuwer Date: Tue, 13 Jun 2023 13:56:00 +0100 Subject: [PATCH 75/86] Added dma2DOffsetCopy and memorySet primitives. --- src/main/scala/apps/GAP8HwceDma.scala | 3 ++- .../GAP8/primitives/copy2DOffsetToL1.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv3x3.scala | 2 +- .../rise/GAP8/primitives/primitives.rise | 13 ++++++------ .../Compilation/AcceptorTranslation.scala | 13 ++++++++++-- .../shine/DPIA/InferAccessAnnotation.scala | 15 +++++++------ src/main/scala/shine/DPIA/fromRise.scala | 16 +++++++------- .../AcceleratorCodeGenerator.scala | 8 ++++++- .../functional/Copy2DOffsetToL1.scala | 8 +++---- .../primitives/functional/FunConv3x3.scala | 4 ++-- .../primitives/functional/primitives.dpia | 8 +++---- .../GAP8/primitives/imperative/Conv3x3.scala | 4 ++-- .../imperative/Dma2DOffsetCopy.scala | 21 +++++++++++++++++++ .../primitives/imperative/MemorySet.scala | 20 ++++++++++++++++++ .../primitives/imperative/primitives.dpia | 13 ++++++++---- 15 files changed, 105 insertions(+), 45 deletions(-) create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala create mode 100644 src/main/scala/shine/GAP8/primitives/imperative/MemorySet.scala diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index c33f6b2ea..3823a0617 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -1,5 +1,6 @@ package apps +import arithexpr.arithmetic.NamedVar import rise.GAP8.DSL.gap8Run import rise.GAP8.primitives.{allocL1, copy2DOffsetToL1, copyToL1, copyToL2, gap8hwConv3x3} import rise.core.DSL.HighLevelConstructs.{padCst2D, zipND} @@ -158,7 +159,7 @@ object GAP8HwceDma { ArrayType(h, ArrayType(w, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: - ArrayType(h - 2, ArrayType(w, i16)))((pic, hw, vw) => + ArrayType(h + NamedVar("rest"), ArrayType(w, i16)))((pic, hw, vw) => gap8Run(8)( hw |> copyToL1 |> allocL1 |> letf(l1hw => vw |> copyToL1 |> allocL1 |> letf(l1vw => diff --git a/src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala b/src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala index 458bf2d7c..091e0d4e3 100644 --- a/src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala +++ b/src/main/scala/rise/GAP8/primitives/copy2DOffsetToL1.scala @@ -13,7 +13,7 @@ object copy2DOffsetToL1 extends Builder { override val name: String = "copy2DOffsetToL1" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = impl { (t: DataType) => impl { (n: Nat) => impl { (m: Nat) => expl { (offsetX: Nat) => expl { (offsetY: Nat) => ArrayType(n, ArrayType(m, t)) ->: ArrayType(n + 2 * offsetY, ArrayType(m + 2 * offsetX, t)) } } } } } + override def typeScheme: ExprType = impl { (t: DataType) => impl { (h: Nat) => impl { (w: Nat) => expl { (offsetH: Nat) => expl { (offsetW: Nat) => ArrayType(h, ArrayType(w, t)) ->: ArrayType(h + 2 * offsetH, ArrayType(w + 2 * offsetW, t)) } } } } } } override def toString: String = "copy2DOffsetToL1" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala index 27d9d6320..c9bef2ad9 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv3x3.scala @@ -13,7 +13,7 @@ object gap8hwConv3x3 extends Builder { override val name: String = "gap8hwConv3x3" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(3, ArrayType(3, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = impl { (h: Nat) => impl { (w: Nat) => impl { (dt: DataType) => expl { (bias: Nat) => ArrayType(h, ArrayType(w, dt)) ->: ArrayType(3, ArrayType(3, dt)) ->: ArrayType(h - 2, ArrayType(w - 2, dt)) } } } } } override def toString: String = "gap8hwConv3x3" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 2fba5db52..913f47542 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -1,9 +1,8 @@ def gap8RunPrimitive: (cores: nat) -> {t: data} -> t -> t -def gap8hwConv3x3: (bias: nat) -> {ih: nat} -> {iw: nat} -> - {oh: nat} -> {ow: nat} -> - {s: data} -> - ih.iw.s -> 3.3.s -> oh.ow.s +def gap8hwConv3x3: {h: nat} -> {w: nat} -> {dt: data} -> + (bias: nat) -> + h.w.dt -> 3.3.dt -> (h-2).(w-2).dt def gap8hwConv5x5: (bias: nat) -> {ih: nat} -> {iw: nat} -> {oh: nat} -> {ow: nat} -> @@ -23,9 +22,9 @@ def gap8hwConv7x4: (bias: nat) -> {ih: nat} -> {iw: nat} -> def copyToL1: {t: data} -> t -> t def copyToL2: {t: data} -> t -> t -def copy2DOffsetToL1: {t: data} -> {n: nat} -> {m: nat} - -> (offsetX: nat) -> (offsetY: nat) -> (n.m.t) - -> (n + 2 * offsetY).(m + 2 * offsetX).t +def copy2DOffsetToL1: {t: data} -> {h: nat} -> {w: nat} + -> (offsetH: nat) -> (offsetW: nat) -> (h.w.t) + -> (h + 2 * offsetH).(w + 2 * offsetW).t def allocL1: {t: data} -> t -> t def allocL2: {t: data} -> t -> t \ No newline at end of file diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index 6f90b49d5..49375fd20 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -392,7 +392,7 @@ object AcceptorTranslation { // GAP8 // TODO: think about generalizing this. This currently only works if the filter is an identifier - case gap8.FunConv3x3(w, h, bias, dt, in, filter: Identifier[ExpType]) => + case gap8.FunConv3x3(h, w, dt, bias, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { // val paddedArray = PadCst(3 * 3, 0, 1, dt, Literal(Unsigned8BitIntData(0)), Join(3, 3, read, dt, filter)) // val paddedArray = shine.DPIA.Phrases.Identifier(filter.name, ExpType(ArrayType(10, dt), read)) @@ -402,7 +402,7 @@ object AcceptorTranslation { filter ) con(paddedArray)(λ(ExpType(ArrayType(10, dt), read))(filterInner => - gap8Imp.Conv3x3(w, h, bias, dt, inInner, filterInner, A) + gap8Imp.Conv3x3(h, w, dt, bias, inInner, filterInner, A) )) })) case gap8.FunConv5x5(w, h, bias, dt, in, filter: Identifier[ExpType]) => @@ -449,6 +449,15 @@ object AcceptorTranslation { gap8Imp.DmaCopy(L1toL2)(dt, i, A) )) + case gap8.Copy2DOffsetToL1(dt, h, w, offsetH, offsetW, input) => + con(input)(λ(ExpType(h`.`w`.`dt, read))(i => + // set larger output to 0 + gap8Imp.MemorySet((h+2*offsetH)`.`(w+2*offsetW)`.`dt, Literal(IntData(0)), A) `;` + // copy smaller input into output with offset + gap8Imp.Dma2DOffsetCopy(L2toL1)(dt, h, w, offsetH, offsetW, i, A) + )) + + case r@shine.GAP8.primitives.functional.Run(cores) => { ??? } diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index 17887b136..48ed0d640 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -604,11 +604,11 @@ private class InferAccessAnnotation { } case rg8p.gap8hwConv3x3() => p.t match { - case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: - ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => - nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) - ->: expT(ArrayType(3, ArrayType(3, s)), read) ->: - expT(ArrayType(oh, ArrayType(ow, s)), write) + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, dt: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(_, ArrayType(_, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), read) + ->: expT(ArrayType(3, ArrayType(3, dt)), read) ->: + expT(ArrayType(h-2, ArrayType(w-2, dt)), write) ) } @@ -654,14 +654,13 @@ private class InferAccessAnnotation { // case n `(Nat)->:` ((dt1: DataType) ->: (dt2: DataType)) => // nFunT(n, expT(dt1, ai) ->: expT(dt2, ai)) case rg8p.copy2DOffsetToL1() => p.t match { - case offsetX `(Nat)->:` (offsetY `(Nat)->:` ((ArrayType(n, ArrayType(m, t: DataType))) ->: (_: DataType))) => - nFunT(offsetX, nFunT(offsetY, expT(n`.`m`.`t, read) ->: expT((n + 2 * offsetY)`.`(m + 2 * offsetX)`.`t, write))) + case offsetH `(Nat)->:` (offsetW `(Nat)->:` ((ArrayType(h, ArrayType(w, dt: DataType))) ->: (_: DataType))) => + nFunT(offsetH, nFunT(offsetW, expT(h`.`w`.`dt, read) ->: expT((h + 2 * offsetH)`.`(w + 2 * offsetW)`.`dt, write))) case _ => error() } case rg8p.allocL1() => p.t match { case (dt: DataType) ->: (_: DataType) => - println(dt) expT(dt, write) ->: expT(dt, read) case _ => error() } diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index 15852e4cb..0368e3a6d 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -930,13 +930,13 @@ object fromRise { } case rgap8.gap8hwConv3x3() => fromType { - case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + case nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), `read`) ->: expT(ArrayType(_, ArrayType(_, _)), `read`) ->: - expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + expT(ArrayType(_, ArrayType(_, _)), `write`)) => depFun(NatKind, bias)( - fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => - fun[ExpType](expT(ArrayType(3, ArrayType(3, s)), read), filter => - gap8.FunConv3x3(w, h, bias, s, input, filter) + fun[ExpType](expT(ArrayType(h, ArrayType(w, dt)), read), input => + fun[ExpType](expT(ArrayType(3, ArrayType(3, dt)), read), filter => + gap8.FunConv3x3(h, w, dt, bias, input, filter) ) ) ) @@ -998,9 +998,9 @@ object fromRise { // Split(n, m, a, t, e))) case rgap8.copy2DOffsetToL1() => fromType { - case nFunT(offsetX, nFunT(offsetY, expT(ArrayType(n, ArrayType(m, t)), `read`) ->: expT(_, `write`))) => - depFun(NatKind, offsetX)(depFun(NatKind, offsetY)(fun[ExpType](expT(n`.`m`.`t, read), input => - gap8.Copy2DOffsetToL1(t, n, m, offsetX, offsetY, input) + case nFunT(offsetH, nFunT(offsetW, expT(ArrayType(h, ArrayType(w, dt)), `read`) ->: expT(_, `write`))) => + depFun(NatKind, offsetH)(depFun(NatKind, offsetW)(fun[ExpType](expT(h`.`w`.`dt, read), input => + gap8.Copy2DOffsetToL1(dt, h, w, offsetH, offsetW, input) ))) } diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 8a02a33fe..eceea4ac7 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -37,7 +37,7 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D override def cmd(env: Environment): Phrase[CommType] => Stmt = { //TODO: Supoort multicycle output for 3x3 - case Conv3x3(w, h, bias, dt, in, filter, out) => + case Conv3x3(h, w, dt, bias, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { @@ -157,6 +157,12 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D } } + case MemorySet(dt, value, array) => + C.AST.Comment("TODO: memset( ... )") + + case copy@Dma2DOffsetCopy(transferType) => + C.AST.Comment("TODO: dma2dOffsetCopy( ... )") + case phrase => phrase |> super.cmd(env) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala b/src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala index 28c4e0ea8..0eff9fecd 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/Copy2DOffsetToL1.scala @@ -9,11 +9,11 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class Copy2DOffsetToL1(val dt: DataType, val n: Nat, val m: Nat, val offsetX: Nat, val offsetY: Nat, val input: Phrase[ExpType]) extends ExpPrimitive { +final case class Copy2DOffsetToL1(val dt: DataType, val h: Nat, val w: Nat, val offsetH: Nat, val offsetW: Nat, val input: Phrase[ExpType]) extends ExpPrimitive { assert { - input :: expT(ArrayType(n, ArrayType(m, dt)), read) + input :: expT(ArrayType(h, ArrayType(w, dt)), read) true } - override val t: ExpType = expT(ArrayType(n + 2 * offsetY, ArrayType(m + 2 * offsetX, dt)), write) - override def visitAndRebuild(v: VisitAndRebuild.Visitor): Copy2DOffsetToL1 = new Copy2DOffsetToL1(v.data(dt), v.nat(n), v.nat(m), v.nat(offsetX), v.nat(offsetY), VisitAndRebuild(input, v)) + override val t: ExpType = expT(ArrayType(h + 2 * offsetH, ArrayType(w + 2 * offsetW, dt)), write) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Copy2DOffsetToL1 = new Copy2DOffsetToL1(v.data(dt), v.nat(h), v.nat(w), v.nat(offsetH), v.nat(offsetW), VisitAndRebuild(input, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala index 4048bba72..2e629a5fd 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv3x3.scala @@ -9,12 +9,12 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class FunConv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { +final case class FunConv3x3(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(3, ArrayType(3, dt)), read) true } override val t: ExpType = expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) - override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv3x3 = new FunConv3x3(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv3x3 = new FunConv3x3(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index cc346f503..fa3123937 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -3,10 +3,10 @@ def kernelCall{name: String, cores: Int, n:Int}(inTs: n*data, outT: data, args: def run{cores: Nat}(dt: data, input: exp[dt, write]): exp[dt, write] def funConv3x3( - w: nat, h: nat, - bias: nat, + w: nat, dt: data, + bias: nat, in: exp[h.w.dt, read], filter: exp[3.3.dt, read] ): exp[(h-2).(w-2).dt, write] @@ -41,8 +41,8 @@ def funConv7x4( def copyToL1(dt: data, input: exp[dt, read]): exp[dt, write] def copyToL2(dt: data, input: exp[dt, read]): exp[dt, write] -def copy2DOffsetToL1(dt: data, n: nat, m: nat, - offsetX: nat, offsetY: nat, input: exp[n.m.dt, read]): exp[(n+2*offsetY).(m+2*offsetX).dt, write] +def copy2DOffsetToL1(dt: data, h: nat, w: nat, + offsetH: nat, offsetW: nat, input: exp[h.w.dt, read]): exp[(h+2*offsetH).(w+2*offsetW).dt, write] def allocL1(dt: data, input: exp[dt, write]): exp[dt, read] def allocL2(dt: data, input: exp[dt, write]): exp[dt, read] diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala index 294121c87..c2e0d32ce 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv3x3.scala @@ -9,7 +9,7 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class Conv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { +final case class Conv3x3(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(10, dt), read) @@ -17,5 +17,5 @@ final case class Conv3x3(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType true } override val t: CommType = comm - override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv3x3 = new Conv3x3(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv3x3 = new Conv3x3(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala b/src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala new file mode 100644 index 000000000..47cbf1a72 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala @@ -0,0 +1,21 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class Dma2DOffsetCopy(tt: shine.GAP8.DMATransferType)(val dt: DataType, val n: Nat, val m: Nat, val offsetY: Nat, val offsetX: Nat, val src: Phrase[ExpType], val dst: Phrase[AccType]) extends CommandPrimitive { + assert { + src :: expT(ArrayType(n, ArrayType(m, dt)), read) + dst :: accT(ArrayType(n + 2 * offsetY, ArrayType(m + 2 * offsetX, dt))) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Dma2DOffsetCopy = new Dma2DOffsetCopy(tt)(v.data(dt), v.nat(n), v.nat(m), v.nat(offsetY), v.nat(offsetX), VisitAndRebuild(src, v), VisitAndRebuild(dst, v)) + def unwrap: (DataType, Nat, Nat, Nat, Nat, Phrase[ExpType], Phrase[AccType]) = (dt, n, m, offsetY, offsetX, src, dst) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/MemorySet.scala b/src/main/scala/shine/GAP8/primitives/imperative/MemorySet.scala new file mode 100644 index 000000000..40b9552a2 --- /dev/null +++ b/src/main/scala/shine/GAP8/primitives/imperative/MemorySet.scala @@ -0,0 +1,20 @@ +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +// This file is automatically generated and should not be changed manually // +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // +package shine.GAP8.primitives.imperative +import arithexpr.arithmetic._ +import shine.DPIA.Phrases._ +import shine.DPIA.Types._ +import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, TypeIdentifier => _, ExprType => _, _ } +import rise.core.types.DataType._ +import rise.core.types.Kind.{ Identifier => _, _ } +import shine.DPIA._ +final case class MemorySet(val dt: DataType, val value: Phrase[ExpType], val array: Phrase[AccType]) extends CommandPrimitive { + assert { + value :: expT(int, read) + array :: accT(dt) + true + } + override val t: CommType = comm + override def visitAndRebuild(v: VisitAndRebuild.Visitor): MemorySet = new MemorySet(v.data(dt), VisitAndRebuild(value, v), VisitAndRebuild(array, v)) +} diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index 80d37b5da..8160b2c18 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -1,10 +1,10 @@ def kernelCallCmd{name: String, cores: Int, n: Int} (inTs: n*data, dt: data, args: n*exp[*inTs, read], output: acc[dt]): comm -def conv3x3(w: nat, - h: nat, - bias: nat, +def conv3x3(h: nat, + w: nat, dt: data, + bias: nat, in: exp[h.w.dt, read], filter: exp[10.dt, read], out: acc[(h-2).(w-2).dt]): comm @@ -34,4 +34,9 @@ def conv7x4(w: nat, out: acc[(h-3).(w-6).dt]): comm def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, read], dst: acc[dt]): comm -def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm \ No newline at end of file +def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm + +def dma2DOffsetCopy{tt: shine.GAP8.DMATransferType}(dt: data, h: nat, w: nat, + offsetH: nat, offsetW: nat, src: exp[n.m.dt, read], dst: acc[(h+2*offsetH).(w+2*offsetW).dt]): comm + +def memorySet(dt: data, value: exp[int, read], array: acc[dt]): comm \ No newline at end of file From 7e49f4da90a0c1d5dd6fc62d4f88b03c883021d4 Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 16 Jun 2023 16:56:31 +0200 Subject: [PATCH 76/86] Refactored GAP8 primitives to make them uniform with other primitives in sense of parameters order etc. --- .../rise/GAP8/primitives/gap8hwConv5x5.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv7x4.scala | 2 +- .../rise/GAP8/primitives/gap8hwConv7x7.scala | 2 +- .../rise/GAP8/primitives/primitives.rise | 21 ++++++------ .../Compilation/AcceptorTranslation.scala | 12 +++---- .../shine/DPIA/InferAccessAnnotation.scala | 32 +++++++++---------- src/main/scala/shine/DPIA/fromRise.scala | 30 ++++++++--------- .../primitives/functional/FunConv5x5.scala | 4 +-- .../primitives/functional/FunConv7x4.scala | 4 +-- .../primitives/functional/FunConv7x7.scala | 4 +-- .../primitives/functional/primitives.dpia | 15 +++++---- .../GAP8/primitives/imperative/Conv5x5.scala | 6 ++-- .../GAP8/primitives/imperative/Conv7x4.scala | 4 +-- .../GAP8/primitives/imperative/Conv7x7.scala | 4 +-- .../imperative/Dma2DOffsetCopy.scala | 10 +++--- .../primitives/imperative/primitives.dpia | 23 ++++++------- 16 files changed, 87 insertions(+), 88 deletions(-) diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala index c3526f5a9..8321e7504 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv5x5.scala @@ -13,7 +13,7 @@ object gap8hwConv5x5 extends Builder { override val name: String = "gap8hwConv5x5" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(5, ArrayType(5, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = impl { (h: Nat) => impl { (w: Nat) => impl { (dt: DataType) => expl { (bias: Nat) => ArrayType(h, ArrayType(w, dt)) ->: ArrayType(5, ArrayType(5, dt)) ->: ArrayType(h - 4, ArrayType(w - 4, dt)) } } } } } override def toString: String = "gap8hwConv5x5" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala index 60816d37a..accbb2a80 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x4.scala @@ -13,7 +13,7 @@ object gap8hwConv7x4 extends Builder { override val name: String = "gap8hwConv7x4" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(4, ArrayType(7, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = impl { (h: Nat) => impl { (w: Nat) => impl { (dt: DataType) => expl { (bias: Nat) => ArrayType(h, ArrayType(w, dt)) ->: ArrayType(4, ArrayType(7, dt)) ->: ArrayType(h - 3, ArrayType(w - 6, dt)) } } } } } override def toString: String = "gap8hwConv7x4" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala index 7f073e58e..f19b282b7 100644 --- a/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala +++ b/src/main/scala/rise/GAP8/primitives/gap8hwConv7x7.scala @@ -13,7 +13,7 @@ object gap8hwConv7x7 extends Builder { override val name: String = "gap8hwConv7x7" override def setType(ty: ExprType): Primitive = Primitive()(ty) override def primEq(obj: rise.core.Primitive): Boolean = obj.getClass == getClass - override def typeScheme: ExprType = expl { (bias: Nat) => impl { (ih: Nat) => impl { (iw: Nat) => impl { (oh: Nat) => impl { (ow: Nat) => impl { (s: DataType) => ArrayType(ih, ArrayType(iw, s)) ->: ArrayType(7, ArrayType(7, s)) ->: ArrayType(oh, ArrayType(ow, s)) } } } } } } + override def typeScheme: ExprType = impl { (h: Nat) => impl { (w: Nat) => impl { (dt: DataType) => expl { (bias: Nat) => ArrayType(h, ArrayType(w, dt)) ->: ArrayType(7, ArrayType(7, dt)) ->: ArrayType(h - 6, ArrayType(w - 6, dt)) } } } } } override def toString: String = "gap8hwConv7x7" override def primitive: rise.core.Primitive = Primitive()() diff --git a/src/main/scala/rise/GAP8/primitives/primitives.rise b/src/main/scala/rise/GAP8/primitives/primitives.rise index 913f47542..5a16374e4 100644 --- a/src/main/scala/rise/GAP8/primitives/primitives.rise +++ b/src/main/scala/rise/GAP8/primitives/primitives.rise @@ -4,20 +4,17 @@ def gap8hwConv3x3: {h: nat} -> {w: nat} -> {dt: data} -> (bias: nat) -> h.w.dt -> 3.3.dt -> (h-2).(w-2).dt -def gap8hwConv5x5: (bias: nat) -> {ih: nat} -> {iw: nat} -> - {oh: nat} -> {ow: nat} -> - {s: data} -> - ih.iw.s -> 5.5.s -> oh.ow.s +def gap8hwConv5x5: {h: nat} -> {w: nat} -> {dt: data} -> + (bias: nat) -> + h.w.dt -> 5.5.dt -> (h-4).(w-4).dt -def gap8hwConv7x7: (bias: nat) -> {ih: nat} -> {iw: nat} -> - {oh: nat} -> {ow: nat} -> - {s: data} -> - ih.iw.s -> 7.7.s -> oh.ow.s +def gap8hwConv7x7: {h: nat} -> {w: nat} -> {dt: data} -> + (bias: nat) -> + h.w.dt -> 7.7.dt -> (h-6).(w-6).dt -def gap8hwConv7x4: (bias: nat) -> {ih: nat} -> {iw: nat} -> - {oh: nat} -> {ow: nat} -> - {s: data} -> - ih.iw.s -> 4.7.s -> oh.ow.s +def gap8hwConv7x4: {h: nat} -> {w: nat} -> {dt: data} -> + (bias: nat) -> + h.w.dt -> 4.7.dt -> (h-3).(w-6).dt def copyToL1: {t: data} -> t -> t def copyToL2: {t: data} -> t -> t diff --git a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala index 49375fd20..fb0130319 100644 --- a/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala +++ b/src/main/scala/shine/DPIA/Compilation/AcceptorTranslation.scala @@ -405,7 +405,7 @@ object AcceptorTranslation { gap8Imp.Conv3x3(h, w, dt, bias, inInner, filterInner, A) )) })) - case gap8.FunConv5x5(w, h, bias, dt, in, filter: Identifier[ExpType]) => + case gap8.FunConv5x5(h, w, dt, bias, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { val paddedArray = gap8.Cast( ArrayType(5, ArrayType(5, dt)), @@ -413,10 +413,10 @@ object AcceptorTranslation { filter ) con(paddedArray)(λ(ExpType(ArrayType(26, dt), read))(filterInner => - gap8Imp.Conv5x5(w, h, bias, dt, inInner, filterInner, A) + gap8Imp.Conv5x5(h, w, dt, bias, inInner, filterInner, A) )) })) - case gap8.FunConv7x7(w, h, bias, dt, in, filter: Identifier[ExpType]) => + case gap8.FunConv7x7(h, w, dt, bias, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { val paddedArray = gap8.Cast( ArrayType(7, ArrayType(7, dt)), @@ -424,10 +424,10 @@ object AcceptorTranslation { filter ) con(paddedArray)(λ(ExpType(ArrayType(56, dt), read))(filterInner => - gap8Imp.Conv7x7(w, h, bias, dt, inInner, filterInner, A) + gap8Imp.Conv7x7(h, w, dt, bias, inInner, filterInner, A) )) })) - case gap8.FunConv7x4(w, h, bias, dt, in, filter: Identifier[ExpType]) => + case gap8.FunConv7x4(h, w, dt, bias, in, filter: Identifier[ExpType]) => con(in)(λ(ExpType(h`.`(w`.`dt), read))(inInner => { val paddedArray = gap8.Cast( ArrayType(4, ArrayType(7, dt)), @@ -435,7 +435,7 @@ object AcceptorTranslation { filter ) con(paddedArray)(λ(ExpType(ArrayType(28, dt), read))(filterInner => - gap8Imp.Conv7x4(w, h, bias, dt, inInner, filterInner, A) + gap8Imp.Conv7x4(h, w, dt, bias, inInner, filterInner, A) )) })) diff --git a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala index 48ed0d640..70d76aa01 100644 --- a/src/main/scala/shine/DPIA/InferAccessAnnotation.scala +++ b/src/main/scala/shine/DPIA/InferAccessAnnotation.scala @@ -608,34 +608,34 @@ private class InferAccessAnnotation { ArrayType(_, ArrayType(_, _)) ->: ArrayType(_, ArrayType(_, _))) => nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), read) ->: expT(ArrayType(3, ArrayType(3, dt)), read) ->: - expT(ArrayType(h-2, ArrayType(w-2, dt)), write) + expT(ArrayType(h - 2, ArrayType(w - 2, dt)), write) ) } case rg8p.gap8hwConv5x5() => p.t match { - case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: - ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => - nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) - ->: expT(ArrayType(5, ArrayType(5, s)), read) ->: - expT(ArrayType(oh, ArrayType(ow, s)), write) + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, dt: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(_, ArrayType(_, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), read) + ->: expT(ArrayType(5, ArrayType(5, dt)), read) ->: + expT(ArrayType(h - 4, ArrayType(w - 4, dt)), write) ) } case rg8p.gap8hwConv7x7() => p.t match { - case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: - ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => - nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) - ->: expT(ArrayType(7, ArrayType(7, s)), read) ->: - expT(ArrayType(oh, ArrayType(ow, s)), write) + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, dt: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(_, ArrayType(_, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), read) + ->: expT(ArrayType(7, ArrayType(7, dt)), read) ->: + expT(ArrayType(h - 6, ArrayType(w - 6, dt)), write) ) } case rg8p.gap8hwConv7x4() => p.t match { - case bias `(Nat)->:` (ArrayType(h, ArrayType(w, s: DataType)) ->: - ArrayType(_, ArrayType(_, _)) ->: ArrayType(oh, ArrayType(ow, _))) => - nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), read) - ->: expT(ArrayType(4, ArrayType(7, s)), read) ->: - expT(ArrayType(oh, ArrayType(ow, s)), write) + case bias `(Nat)->:` (ArrayType(h, ArrayType(w, dt: DataType)) ->: + ArrayType(_, ArrayType(_, _)) ->: ArrayType(_, ArrayType(_, _))) => + nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), read) + ->: expT(ArrayType(4, ArrayType(7, dt)), read) ->: + expT(ArrayType(h - 3, ArrayType(w - 6, dt)), write) ) } diff --git a/src/main/scala/shine/DPIA/fromRise.scala b/src/main/scala/shine/DPIA/fromRise.scala index 0368e3a6d..ebdd2aea7 100644 --- a/src/main/scala/shine/DPIA/fromRise.scala +++ b/src/main/scala/shine/DPIA/fromRise.scala @@ -943,39 +943,39 @@ object fromRise { } case rgap8.gap8hwConv5x5() => fromType { - case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + case nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), `read`) ->: expT(ArrayType(_, ArrayType(_, _)), `read`) ->: - expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + expT(ArrayType(_, ArrayType(_, _)), `write`)) => depFun(NatKind, bias)( - fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => - fun[ExpType](expT(ArrayType(5, ArrayType(5, s)), read), filter => - gap8.FunConv5x5(w, h, bias, s, input, filter) + fun[ExpType](expT(ArrayType(h, ArrayType(w, dt)), read), input => + fun[ExpType](expT(ArrayType(5, ArrayType(5, dt)), read), filter => + gap8.FunConv5x5(h, w, dt, bias, input, filter) ) ) ) } case rgap8.gap8hwConv7x7() => fromType { - case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + case nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), `read`) ->: expT(ArrayType(_, ArrayType(_, _)), `read`) ->: - expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + expT(ArrayType(_, ArrayType(_, _)), `write`)) => depFun(NatKind, bias)( - fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => - fun[ExpType](expT(ArrayType(7, ArrayType(7, s)), read), filter => - gap8.FunConv7x7(w, h, bias, s, input, filter) + fun[ExpType](expT(ArrayType(h, ArrayType(w, dt)), read), input => + fun[ExpType](expT(ArrayType(7, ArrayType(7, dt)), read), filter => + gap8.FunConv7x7(h, w, dt, bias, input, filter) ) ) ) } case rgap8.gap8hwConv7x4() => fromType { - case nFunT(bias, expT(ArrayType(h, ArrayType(w, s)), `read`) ->: + case nFunT(bias, expT(ArrayType(h, ArrayType(w, dt)), `read`) ->: expT(ArrayType(_, ArrayType(_, _)), `read`) ->: - expT(ArrayType(oh, ArrayType(ow, _)), `write`)) => + expT(ArrayType(_, ArrayType(_, _)), `write`)) => depFun(NatKind, bias)( - fun[ExpType](expT(ArrayType(h, ArrayType(w, s)), read), input => - fun[ExpType](expT(ArrayType(4, ArrayType(7, s)), read), filter => - gap8.FunConv7x4(w, h, bias, s, input, filter) + fun[ExpType](expT(ArrayType(h, ArrayType(w, dt)), read), input => + fun[ExpType](expT(ArrayType(4, ArrayType(7, dt)), read), filter => + gap8.FunConv7x4(h, w, dt, bias, input, filter) ) ) ) diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala index 2e9c719fe..5b39efef7 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv5x5.scala @@ -9,12 +9,12 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class FunConv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { +final case class FunConv5x5(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(5, ArrayType(5, dt)), read) true } override val t: ExpType = expT(ArrayType(h - 4, ArrayType(w - 4, dt)), write) - override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv5x5 = new FunConv5x5(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv5x5 = new FunConv5x5(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala index a253f3a44..16d883616 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x4.scala @@ -9,12 +9,12 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class FunConv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { +final case class FunConv7x4(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(4, ArrayType(7, dt)), read) true } override val t: ExpType = expT(ArrayType(h - 3, ArrayType(w - 6, dt)), write) - override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x4 = new FunConv7x4(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x4 = new FunConv7x4(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala index b50c33b8b..aad82c108 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/functional/FunConv7x7.scala @@ -9,12 +9,12 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class FunConv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { +final case class FunConv7x7(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType]) extends ExpPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(7, ArrayType(7, dt)), read) true } override val t: ExpType = expT(ArrayType(h - 6, ArrayType(w - 6, dt)), write) - override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x7 = new FunConv7x7(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): FunConv7x7 = new FunConv7x7(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia index fa3123937..f05df395c 100644 --- a/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/functional/primitives.dpia @@ -12,28 +12,28 @@ def funConv3x3( ): exp[(h-2).(w-2).dt, write] def funConv5x5( - w: nat, h: nat, - bias: nat, + w: nat, dt: data, + bias: nat, in: exp[h.w.dt, read], filter: exp[5.5.dt, read] ): exp[(h-4).(w-4).dt, write] def funConv7x7( - w: nat, h: nat, - bias: nat, + w: nat, dt: data, + bias: nat, in: exp[h.w.dt, read], filter: exp[7.7.dt, read] ): exp[(h-6).(w-6).dt, write] def funConv7x4( - w: nat, h: nat, - bias: nat, + w: nat, dt: data, + bias: nat, in: exp[h.w.dt, read], filter: exp[4.7.dt, read] ): exp[(h-3).(w-6).dt, write] @@ -42,7 +42,8 @@ def copyToL1(dt: data, input: exp[dt, read]): exp[dt, write] def copyToL2(dt: data, input: exp[dt, read]): exp[dt, write] def copy2DOffsetToL1(dt: data, h: nat, w: nat, - offsetH: nat, offsetW: nat, input: exp[h.w.dt, read]): exp[(h+2*offsetH).(w+2*offsetW).dt, write] + offsetH: nat, offsetW: nat, + input: exp[h.w.dt, read]): exp[(h+2*offsetH).(w+2*offsetW).dt, write] def allocL1(dt: data, input: exp[dt, write]): exp[dt, read] def allocL2(dt: data, input: exp[dt, write]): exp[dt, read] diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala index 6a87e3c8b..5d9608b15 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv5x5.scala @@ -9,13 +9,13 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class Conv5x5(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { +final case class Conv5x5(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { - in :: expT(ArrayType(w, ArrayType(h, dt)), read) + in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(26, dt), read) out :: accT(ArrayType(h - 4, ArrayType(w - 4, dt))) true } override val t: CommType = comm - override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv5x5 = new Conv5x5(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv5x5 = new Conv5x5(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala index 2fc925825..a01b13273 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x4.scala @@ -9,7 +9,7 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { +final case class Conv7x4(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(28, dt), read) @@ -17,5 +17,5 @@ final case class Conv7x4(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType true } override val t: CommType = comm - override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv7x4 = new Conv7x4(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv7x4 = new Conv7x4(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala index 3073fad9f..796a6b698 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Conv7x7.scala @@ -9,7 +9,7 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class Conv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { +final case class Conv7x7(val h: Nat, val w: Nat, val dt: DataType, val bias: Nat, val in: Phrase[ExpType], val filter: Phrase[ExpType], val out: Phrase[AccType]) extends CommandPrimitive { assert { in :: expT(ArrayType(h, ArrayType(w, dt)), read) filter :: expT(ArrayType(56, dt), read) @@ -17,5 +17,5 @@ final case class Conv7x7(val w: Nat, val h: Nat, val bias: Nat, val dt: DataType true } override val t: CommType = comm - override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv7x7 = new Conv7x7(v.nat(w), v.nat(h), v.nat(bias), v.data(dt), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Conv7x7 = new Conv7x7(v.nat(h), v.nat(w), v.data(dt), v.nat(bias), VisitAndRebuild(in, v), VisitAndRebuild(filter, v), VisitAndRebuild(out, v)) } diff --git a/src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala b/src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala index 47cbf1a72..e720d1273 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala +++ b/src/main/scala/shine/GAP8/primitives/imperative/Dma2DOffsetCopy.scala @@ -9,13 +9,13 @@ import rise.core.types.{ FunType => _, DepFunType => _, TypePlaceholder => _, Ty import rise.core.types.DataType._ import rise.core.types.Kind.{ Identifier => _, _ } import shine.DPIA._ -final case class Dma2DOffsetCopy(tt: shine.GAP8.DMATransferType)(val dt: DataType, val n: Nat, val m: Nat, val offsetY: Nat, val offsetX: Nat, val src: Phrase[ExpType], val dst: Phrase[AccType]) extends CommandPrimitive { +final case class Dma2DOffsetCopy(tt: shine.GAP8.DMATransferType)(val dt: DataType, val h: Nat, val w: Nat, val offsetH: Nat, val offsetW: Nat, val src: Phrase[ExpType], val dst: Phrase[AccType]) extends CommandPrimitive { assert { - src :: expT(ArrayType(n, ArrayType(m, dt)), read) - dst :: accT(ArrayType(n + 2 * offsetY, ArrayType(m + 2 * offsetX, dt))) + src :: expT(ArrayType(h, ArrayType(w, dt)), read) + dst :: accT(ArrayType(h + 2 * offsetH, ArrayType(w + 2 * offsetW, dt))) true } override val t: CommType = comm - override def visitAndRebuild(v: VisitAndRebuild.Visitor): Dma2DOffsetCopy = new Dma2DOffsetCopy(tt)(v.data(dt), v.nat(n), v.nat(m), v.nat(offsetY), v.nat(offsetX), VisitAndRebuild(src, v), VisitAndRebuild(dst, v)) - def unwrap: (DataType, Nat, Nat, Nat, Nat, Phrase[ExpType], Phrase[AccType]) = (dt, n, m, offsetY, offsetX, src, dst) + override def visitAndRebuild(v: VisitAndRebuild.Visitor): Dma2DOffsetCopy = new Dma2DOffsetCopy(tt)(v.data(dt), v.nat(h), v.nat(w), v.nat(offsetH), v.nat(offsetW), VisitAndRebuild(src, v), VisitAndRebuild(dst, v)) + def unwrap: (DataType, Nat, Nat, Nat, Nat, Phrase[ExpType], Phrase[AccType]) = (dt, h, w, offsetH, offsetW, src, dst) } diff --git a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia index 8160b2c18..d40431c50 100644 --- a/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia +++ b/src/main/scala/shine/GAP8/primitives/imperative/primitives.dpia @@ -9,26 +9,26 @@ def conv3x3(h: nat, filter: exp[10.dt, read], out: acc[(h-2).(w-2).dt]): comm -def conv5x5(w: nat, - h: nat, - bias: nat, +def conv5x5(h: nat, + w: nat, dt: data, - in: exp[w.h.dt, read], + bias: nat, + in: exp[h.w.dt, read], filter: exp[26.dt, read], out: acc[(h-4).(w-4).dt]): comm -def conv7x7(w: nat, - h: nat, - bias: nat, +def conv7x7(h: nat, + w: nat, dt: data, + bias: nat, in: exp[h.w.dt, read], filter: exp[56.dt, read], out: acc[(h-6).(w-6).dt]): comm -def conv7x4(w: nat, - h: nat, - bias: nat, +def conv7x4(h: nat, + w: nat, dt: data, + bias: nat, in: exp[h.w.dt, read], filter: exp[28.dt, read], out: acc[(h-3).(w-6).dt]): comm @@ -37,6 +37,7 @@ def dmaCopy{tt: shine.GAP8.DMATransferType}(dt: data, src: exp[dt, read], dst: a def memoryAlloc{mt: shine.GAP8.MemoryType}(dt: data, f: var[dt] -> comm): comm def dma2DOffsetCopy{tt: shine.GAP8.DMATransferType}(dt: data, h: nat, w: nat, - offsetH: nat, offsetW: nat, src: exp[n.m.dt, read], dst: acc[(h+2*offsetH).(w+2*offsetW).dt]): comm + offsetH: nat, offsetW: nat, + src: exp[h.w.dt, read], dst: acc[(h+2*offsetH).(w+2*offsetW).dt]): comm def memorySet(dt: data, value: exp[int, read], array: acc[dt]): comm \ No newline at end of file From 929b38fc55e05bc100e9faeac76954b658d77dda Mon Sep 17 00:00:00 2001 From: bpervan Date: Fri, 16 Jun 2023 16:57:33 +0200 Subject: [PATCH 77/86] Primitives interface refactor (for conv primitives); MemorySet and Dma2DOffsetCopy translation skeletons --- .../AcceleratorCodeGenerator.scala | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index eceea4ac7..b4c8acc67 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -41,31 +41,31 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { - generateCalls(shine.GAP8._3x3, w, h, bias, inC, filterC, outputC) + generateCalls(shine.GAP8._3x3, h, w, bias, inC, filterC, outputC) }) }) }) - case Conv5x5(w, h, bias, dt, in, filter, out) => + case Conv5x5(h, w, dt, bias, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { - generateCalls(shine.GAP8._5x5, w, h, bias, inC, filterC, outputC) + generateCalls(shine.GAP8._5x5, h, w, bias, inC, filterC, outputC) }) }) }) - case Conv7x7(w, h, bias, dt, in, filter, out) => + case Conv7x7(h, w, dt, bias, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { - generateCalls(shine.GAP8._7x7, w, h, bias, inC, filterC, outputC) + generateCalls(shine.GAP8._7x7, h, w, bias, inC, filterC, outputC) }) }) }) - case Conv7x4(w, h, bias, dt, in, filter, out) => + case Conv7x4(h, w, dt, bias, in, filter, out) => out |> acc(env, Nil, (outputC: C.AST.Expr) => { in |> exp(env, Nil, (inC: C.AST.Expr) => { filter |> exp(env, Nil, (filterC: C.AST.Expr) => { - generateCalls(shine.GAP8._7x4, w, h, bias, inC, filterC, outputC) + generateCalls(shine.GAP8._7x4, h, w, bias, inC, filterC, outputC) }) }) }) @@ -158,26 +158,43 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D } case MemorySet(dt, value, array) => - C.AST.Comment("TODO: memset( ... )") + array |> acc(env, Nil, (arrayC: C.AST.Expr) => { + value |> exp(env, Nil, (valueC: C.AST.Expr) => { + C.AST.Block(Seq( + C.AST.Comment("TODO: memset( ... )"), + C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("memset"), Seq( + + ))) + )) + }) + }) + + case copy@Dma2DOffsetCopy(transferType) => - C.AST.Comment("TODO: dma2dOffsetCopy( ... )") + copy.dst |> acc(env, CIntExpr(0) :: Nil, (dstC: C.AST.Expr) => { + copy.src |> exp(env, CIntExpr(0) :: Nil, (srcC: C.AST.Expr) => { + C.AST.Block(Seq( + C.AST.Comment("TODO: dma2dOffsetCopy( ... )") + )) + }) + }) case phrase => phrase |> super.cmd(env) } - private def generateCalls(fs: ConvolutionFilterSize, w: Nat, h: Nat, bias: Nat, + private def generateCalls(fs: ConvolutionFilterSize, h: Nat, w: Nat, bias: Nat, in: Expr, filter: Expr, output: Expr): Stmt = { C.AST.Block(Seq( hwceEnableCall, hwceGenericInitCall(fs), hwceSetYinModeCall(), - generateHwceCallFunction(fs, w, h, bias, in, filter, output), + generateHwceCallFunction(fs, h, w, bias, in, filter, output), hwceDisableCall )) } - private def generateHwceCallFunction(fs: ConvolutionFilterSize, w: Nat, h: Nat, bias: Nat, + private def generateHwceCallFunction(fs: ConvolutionFilterSize, h: Nat, w: Nat, bias: Nat, in: Expr, filter: Expr, output: Expr): Stmt = { fs match { case shine.GAP8._3x3 => From 57f911bddb01721b32e0fe65943b5de95f285c9a Mon Sep 17 00:00:00 2001 From: bpervan Date: Sat, 17 Jun 2023 14:16:52 +0200 Subject: [PATCH 78/86] Dma2DOffsetCopy codegen implementation --- .../AcceleratorCodeGenerator.scala | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index b4c8acc67..b0cfa54bf 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -2,13 +2,14 @@ package shine.GAP8.Compilation import arithexpr.arithmetic import arithexpr.arithmetic.ArithExpr +import arithexpr.arithmetic.ArithExpr.toInt import rise.core.types.DataType import shine.C.Compilation.CodeGenerator.CIntExpr import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} import shine.DPIA.Nat import shine.DPIA.Phrases.{Identifier, Lambda, Phrase, PhrasePair} import shine.DPIA.Types.{CommType, ExpType} -import shine.GAP8.ConvolutionFilterSize +import shine.GAP8.{ConvolutionFilterSize, DMATransferType} import shine.GAP8.primitives.functional.Cast import shine.GAP8.primitives.imperative._ import shine.{C, OpenMP} @@ -161,21 +162,52 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D array |> acc(env, Nil, (arrayC: C.AST.Expr) => { value |> exp(env, Nil, (valueC: C.AST.Expr) => { C.AST.Block(Seq( - C.AST.Comment("TODO: memset( ... )"), + C.AST.Comment("memset"), C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("memset"), Seq( - + arrayC, + valueC, + C.AST.Literal(shine.GAP8.AST.Types.sizeInBytes(dt).toString) ))) )) }) }) - - + //rt_dma_memcpy_2d(unsigned int ext, + // unsigned int loc, + // unsigned short size, + // unsigned short stride, + // unsigned short length, + // rt_dma_dir_e dir, int merge, rt_dma_copy_t *copy); + // stride 2D stride, which is the number of bytes which are added to the beginning of the current line to switch to the next one. Must fit in 16 bits, i.e. must be less than 65536. + // length 2D length, which is the number of transfered bytes after which the DMA will switch to the next line. Must fit in 16 bits, i.e. must be less than 65536. case copy@Dma2DOffsetCopy(transferType) => copy.dst |> acc(env, CIntExpr(0) :: Nil, (dstC: C.AST.Expr) => { copy.src |> exp(env, CIntExpr(0) :: Nil, (srcC: C.AST.Expr) => { + val (ext, loc) = transferType match { + case shine.GAP8.L1toL2 => + (dstC, srcC) + case shine.GAP8.L2toL1 => + (srcC, dstC) + } + val stride = toInt(copy.offsetH).toString + val length = toInt(copy.offsetW).toString + val size = shine.GAP8.AST.Types.sizeInBytes(copy.dt) * copy.h * copy.w C.AST.Block(Seq( - C.AST.Comment("TODO: dma2dOffsetCopy( ... )") + C.AST.Comment("dma2dOffsetCopy"), + C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("rt_dma_memcpy_2d"), Seq( + ext, + loc, + C.AST.Literal(size.toString), + C.AST.Literal(stride), + C.AST.Literal(length), + C.AST.Literal(transferType.toGAP8string), + C.AST.Literal(0.toString), + C.AST.Literal("&L2toL1") + ))), + C.AST.ExprStmt(C.AST.FunCall( + C.AST.DeclRef("rt_dma_wait"), + Seq(C.AST.Literal("&L2toL1")) + )) )) }) }) From 50b3ce2e1c77a6709ee94332b30522e9dbdfec22 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 4 Jul 2023 23:25:53 +0200 Subject: [PATCH 79/86] Added ampersand unary op and cast to dma transfers; Added (incomplete) for-loop data data transfer --- .../AcceleratorCodeGenerator.scala | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index b0cfa54bf..389300559 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -6,7 +6,7 @@ import arithexpr.arithmetic.ArithExpr.toInt import rise.core.types.DataType import shine.C.Compilation.CodeGenerator.CIntExpr import shine.DPIA.Compilation.{CodeGenerator, TranslationContext} -import shine.DPIA.Nat +import shine.DPIA.{Nat, freshName} import shine.DPIA.Phrases.{Identifier, Lambda, Phrase, PhrasePair} import shine.DPIA.Types.{CommType, ExpType} import shine.GAP8.{ConvolutionFilterSize, DMATransferType} @@ -95,8 +95,8 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D C.AST.DeclRef("rt_dma_memcpy"), Seq( // TODO: Reference fetch via ampersand might be needed (ext,loc) - ext, - loc, + C.AST.Cast(C.AST.Type.u32, C.AST.UnaryExpr(C.AST.UnaryOperator.&, ext)), + C.AST.Cast(C.AST.Type.u32, C.AST.UnaryExpr(C.AST.UnaryOperator.&, loc)), C.AST.Literal(size.toString), C.AST.Literal(transferType.toGAP8string), C.AST.Literal(0.toString), @@ -189,17 +189,17 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D case shine.GAP8.L2toL1 => (srcC, dstC) } - val stride = toInt(copy.offsetH).toString - val length = toInt(copy.offsetW).toString + val stride = toInt(copy.offsetH) * shine.GAP8.AST.Types.sizeInBytes(copy.dt) + val length = toInt(copy.w) * shine.GAP8.AST.Types.sizeInBytes(copy.dt) val size = shine.GAP8.AST.Types.sizeInBytes(copy.dt) * copy.h * copy.w C.AST.Block(Seq( C.AST.Comment("dma2dOffsetCopy"), C.AST.ExprStmt(C.AST.FunCall(C.AST.DeclRef("rt_dma_memcpy_2d"), Seq( - ext, - loc, + C.AST.Cast(C.AST.Type.u32, C.AST.UnaryExpr(C.AST.UnaryOperator.&, ext)), + C.AST.Cast(C.AST.Type.u32, C.AST.UnaryExpr(C.AST.UnaryOperator.&, loc)), C.AST.Literal(size.toString), - C.AST.Literal(stride), - C.AST.Literal(length), + C.AST.Literal(stride.toString), + C.AST.Literal(length.toString), C.AST.Literal(transferType.toGAP8string), C.AST.Literal(0.toString), C.AST.Literal("&L2toL1") @@ -215,6 +215,34 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D case phrase => phrase |> super.cmd(env) } + //*(x401 + (i + 1) * (322) + (j + 1)) = *(e48 + (4480 * i_410) + i * 320 + j); + //TODO: Finish + private def generate2DLoopTransfer( + width: Int, height: Int, + src: C.AST.Expr, dst: C.AST.Expr, + offsetX: Int, offsetY: Int): Stmt = { + val firstVar = freshName("dma2d_") + val secondVar = freshName("dma2d_") + C.AST.ForLoop( + init = C.AST.DeclStmt(C.AST.VarDecl(firstVar, C.AST.Type.int, None)), + cond = C.AST.BinaryExpr(C.AST.Literal(firstVar), C.AST.BinaryOperator.<, C.AST.Literal(width.toString)), + increment = C.AST.Assignment(C.AST.DeclRef(firstVar), C.AST.BinaryExpr(C.AST.DeclRef(firstVar), C.AST.BinaryOperator.+, C.AST.Literal("1"))), + body = C.AST.Block(Seq( + C.AST.ForLoop( + init = C.AST.DeclStmt(C.AST.VarDecl(secondVar, C.AST.Type.int, None)), + cond = C.AST.BinaryExpr(C.AST.Literal(secondVar), C.AST.BinaryOperator.<, C.AST.Literal(height.toString)), + increment = C.AST.Assignment(C.AST.DeclRef(secondVar), C.AST.BinaryExpr(C.AST.DeclRef(secondVar), C.AST.BinaryOperator.+, C.AST.Literal("1"))), + body = C.AST.Block(Seq( + C.AST.ExprStmt(C.AST.Assignment( + C.AST.UnaryExpr(C.AST.UnaryOperator.*, C.AST.ArithmeticExpr(???)), + C.AST.UnaryExpr(C.AST.UnaryOperator.*, C.AST.ArithmeticExpr(???)) + )) + )) + ) + )) + ) + } + private def generateCalls(fs: ConvolutionFilterSize, h: Nat, w: Nat, bias: Nat, in: Expr, filter: Expr, output: Expr): Stmt = { C.AST.Block(Seq( From 1e83ce6d3539923c7ab5e13f610473936229550f Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 4 Jul 2023 23:26:12 +0200 Subject: [PATCH 80/86] WIP: HwceDma apps --- src/main/scala/apps/GAP8HwceDma.scala | 95 ++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 3823a0617..1b2bcd853 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -154,37 +154,126 @@ object GAP8HwceDma { val w: Nat = 320 val h: Nat = 240 + //Padded horizontally val tiledFixSizeDmaHwce: ToBeTyped[Rise] = fun( ArrayType(h, ArrayType(w, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: ArrayType(3, ArrayType(3, i16)) ->: - ArrayType(h + NamedVar("rest"), ArrayType(w, i16)))((pic, hw, vw) => + ArrayType(h - 2, ArrayType(w, i16)))((pic, hw, vw) => gap8Run(8)( hw |> copyToL1 |> allocL1 |> letf(l1hw => vw |> copyToL1 |> allocL1 |> letf(l1vw => // pic |> padCst2D(1, 1, 0, 0)(li16(0)) |> slide(16)(14) |> + // pic: 240.320.i16 pic |> slide (16)(14) |> + // 14*16+16 => 240 (n: 16) + // 17.16.320.i16 mapSeq(fun(stripe => - stripe |> copy2DOffsetToL1(1)(1) |> allocL1 |> // letf(l1stripe => + // stripe: 16.320.i16 + stripe |> copy2DOffsetToL1(0)(1) |> allocL1 |> // letf(l1stripe => + // l1stripe |> padCst2D(0, 0, 1, 1)(li16(0)) |> // mapSeq(mapSeq(fun(x => x))) |> allocL1 |> + // l1convstripe: 18.322.i16 + // if offsetH = 0 -> 16.322.i16 letf(l1convstripe => + // convresult(s): 16.320.i16 + // if offsetH =0 -> 14.320.i16 gap8hwConv3x3(0)(l1convstripe, l1hw) |> allocL1 |> letf(hconvres => gap8hwConv3x3(0)(l1convstripe, l1vw) |> allocL1 |> letf(vconvres => + // zipND: 16.320.(i16, i16) zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => gapSqrt(add(mul(fst(elems))(fst(elems)))(mul(snd(elems))(snd(elems)))) + //copy back 16.320.i16 ))) |> allocL1 |> copyToL2 ) ) // ) ) + //(17*16).320.i16 + //offsetH -> 0 (17*14).320.i16 )) |> join ) ) ) ) - println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) + //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwce))) + + //Padded vertically + val tiledFixSizeDmaHwcePaddedVertically: ToBeTyped[Rise] = + fun( + ArrayType(h, ArrayType(w, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(h - 2, ArrayType(w - 2, i16)))((pic, hw, vw) => + gap8Run(8)( + hw |> copyToL1 |> allocL1 |> letf(l1hw => + vw |> copyToL1 |> allocL1 |> letf(l1vw => + // pic: 240.320.i16 + pic |> slide(16)(14) |> + // 14*16+16 => 240 (n: 16) + // 17.16.320.i16 + mapSeq(fun(stripe => + // stripe: 16.320.i16 + stripe |> copy2DOffsetToL1(1)(0) |> allocL1 |> // letf(l1stripe => + // l1convstripe 18.320.i16 + letf(l1convstripe => + // convresult(s): 16.318.i16 + gap8hwConv3x3(0)(l1convstripe, l1hw) |> allocL1 |> letf(hconvres => + gap8hwConv3x3(0)(l1convstripe, l1vw) |> allocL1 |> letf(vconvres => + // zipND: 16.318.(i16, i16) + zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => + gapSqrt(add(mul(fst(elems))(fst(elems)))(mul(snd(elems))(snd(elems)))) + //copy back 16.318.i16 + ))) |> allocL1 |> take(15) |> drop(1) |> copyToL2 + ) + ) + ) + //(17*16).318.i16 + )) |> join + ) + ) + ) + ) + //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwcePaddedVertically))) + + val tiledFixSizeDmaHwceNoPadding: ToBeTyped[Rise] = + fun( + ArrayType(h, ArrayType(w, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(h - 2, ArrayType(w - 2, i16)))((pic, hw, vw) => + gap8Run(8)( + hw |> copyToL1 |> allocL1 |> letf(l1hw => + vw |> copyToL1 |> allocL1 |> letf(l1vw => + // pic: 240.320.i16 + pic |> slide(16)(14) |> + // 14*16+16 => 240 (n: 16) + // 17.16.320.i16 + mapSeq(fun(stripe => + // stripe: 16.320.i16 + stripe |> copyToL1 |> allocL1 |> // letf(l1stripe => + // l1convstripe 16.320.i16 + letf(l1convstripe => + // convresult(s): 14.318.i16 + gap8hwConv3x3(0)(l1convstripe, l1hw) |> allocL1 |> letf(hconvres => + gap8hwConv3x3(0)(l1convstripe, l1vw) |> allocL1 |> letf(vconvres => + // zipND: 14.318.(i16, i16) + zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => + gapSqrt(add(mul(fst(elems))(fst(elems)))(mul(snd(elems))(snd(elems)))) + //copy back 14.318.i16 + ))) |> allocL1 |> copyToL2 + ) + ) + ) + //(17*14).318.i16 + )) |> join + ) + ) + ) + ) + println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwceNoPadding))) val simpleNoSlide: ToBeTyped[Rise] = fun( From 9257bb6cbd037a68f0a8cac025bf9340982572d5 Mon Sep 17 00:00:00 2001 From: bpervan Date: Sun, 22 Oct 2023 22:46:30 +0200 Subject: [PATCH 81/86] Added collapse rule proto --- src/main/scala/rise/elevate/rules/algorithmic.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/scala/rise/elevate/rules/algorithmic.scala b/src/main/scala/rise/elevate/rules/algorithmic.scala index f70d0b61a..8eda2d3cf 100644 --- a/src/main/scala/rise/elevate/rules/algorithmic.scala +++ b/src/main/scala/rise/elevate/rules/algorithmic.scala @@ -568,6 +568,10 @@ object algorithmic { Success((preserveType(in) |> transpose |> map(sum) |> sum) !: e.t) } + /*@rule def colapseOpenMPfor: Strategy[Rise] = { + ??? + }*/ + /** * TODO: A couple of things to think about: * 1.This is extremely specific. Is there a way to make it more general in any way? From 67200e1a7d3f06fe763d98b59be98f00548f1e22 Mon Sep 17 00:00:00 2001 From: bpervan Date: Sun, 22 Oct 2023 22:47:14 +0200 Subject: [PATCH 82/86] Added DMA-HWCE expressions; Added tester file (to be removed probably later) --- src/main/scala/apps/GAP8HwceDma.scala | 47 +++- src/main/scala/apps/tester.scala | 335 ++++++++++++++++++++++++++ 2 files changed, 378 insertions(+), 4 deletions(-) create mode 100644 src/main/scala/apps/tester.scala diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 1b2bcd853..327f0135c 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -1,15 +1,19 @@ package apps import arithexpr.arithmetic.NamedVar +import elevate.core.Strategy import rise.GAP8.DSL.gap8Run -import rise.GAP8.primitives.{allocL1, copy2DOffsetToL1, copyToL1, copyToL2, gap8hwConv3x3} +import rise.GAP8.primitives.{allocL1, copy2DOffsetToL1, copyToL1, copyToL2, gap8hwConv3x3, gap8hwConv5x5} import rise.core.DSL.HighLevelConstructs.{padCst2D, zipND} import rise.core.DSL.Type.TypeConstructors import rise.core.DSL.{ToBeTyped, depFun, foreignFun, fun, letf, li16} import rise.core.primitives._ -import rise.core.types.DataType.{ArrayType, i16, u8} +import rise.core.types.DataType.{ArrayType, i16, int, u8} import rise.core.types.Nat import rise.elevate.Rise +import rise.elevate.strategies.traversal.everywhere +import rise.elevate.strategies.traversal.AtHelper +import rise.elevate.rules.lowering.`map -> mapPar` import rise.openMP.primitives.mapPar import shine.GAP8.Module.translateToString @@ -267,13 +271,48 @@ object GAP8HwceDma { ) ) ) - //(17*14).318.i16 + // + )) |> join ) ) ) ) - println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwceNoPadding))) + //println(translateToString(util.gen.gap8.hosted("tiledConv").fromExpr(tiledFixSizeDmaHwceNoPadding))) + val ww: Nat = 320 + val hh: Nat = 244 + val tiledFixSizeDmaHwceNoPadding_Gaussian: ToBeTyped[Rise] = + fun( + ArrayType(hh, ArrayType(ww, i16)) ->: + ArrayType(5, ArrayType(5, i16)) ->: + ArrayType(hh - 4, ArrayType(ww - 4, i16)))((pic, filter) => + gap8Run(8)( + filter |> copyToL1 |> allocL1 |> letf(l1filter => + // pic: 240.320.i16 + pic |> slide(16)(12) |> + // step * n + size = 240 + // 17.16.320.i16 + mapSeq(fun(stripe => + //stripe 16.320.i16 + stripe |> copyToL1 |> allocL1 |> + letf(l1stripe => + // convresult (12.316.i16) + gap8hwConv5x5(0)(l1stripe, l1filter) |> allocL1 |> copyToL2 + ) + )) |> join + ) + ) + ) + println(translateToString(util.gen.gap8.hosted("GaussianBlur").fromExpr(tiledFixSizeDmaHwceNoPadding_Gaussian))) + + /*val strategy: Strategy[Rise] = + `map -> mapPar` `@` everywhere + val ex_mapfor: ToBeTyped[Rise] = depFun((n: Nat) => + fun(ArrayType(n, int) ->: ArrayType(n, int))(input => + input |> map(fun(x => x)) + ) + ) + println(util.gen.openmp.function("ex_mapfor").asStringFromExpr(strategy(ex_mapfor).get))*/ val simpleNoSlide: ToBeTyped[Rise] = fun( diff --git a/src/main/scala/apps/tester.scala b/src/main/scala/apps/tester.scala new file mode 100644 index 000000000..ec7bd97d4 --- /dev/null +++ b/src/main/scala/apps/tester.scala @@ -0,0 +1,335 @@ +package apps + +import elevate.core._ +import rise.GAP8.DSL.gap8Run +import rise.GAP8.primitives.{copyToL1, copyToL2, gap8hwConv3x3} +import rise.core.DSL.HighLevelConstructs.zipND +import rise.core.DSL.Type._ +import rise.core.DSL._ +import rise.core._ +import rise.core.primitives.{mapSeq, reduceSeq, let => _, _} +import rise.core.types.DataType.{ArrayType, i16, int, u32, u8} +import rise.core.types._ +import rise.elevate._ +import rise.elevate.rules.algorithmic._ +import rise.elevate.rules.lowering._ +import rise.elevate.strategies.predicate.isPrimitive +import rise.elevate.strategies.traversal._ +import rise.openMP.primitives.mapPar +import shine.GAP8.Module.translateToString + +// scalastyle:off +object tester { + def main(args: Array[String]) = { + + val gapSqrt = foreignFun("gap_sqrt", + Seq("a_nInput"), + """ + | { + | uint32_t op = a_nInput; + | uint32_t res = 0; + | + | uint32_t one = 1uL << 30; + | while (one > op){ + | one >>= 2; + | } + | while (one != 0) { + | if (op >= res + one){ + | op = op - (res + one); + | res = res + 2 * one; + | } + | res >>= 1; + | one >>= 2; + | } + | return res; + | } + |""".stripMargin, + i16 ->: i16 + ) + + //2D Zip + //Merge mapPar + //1D slide + /*val againExpr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => + fun((n `.` m `.` u8) ->: (3 `.` 3 `.` i16) ->: (3 `.` 3 `.` i16) ->: ((n - 2) `.` (m - 2) `.` i16))((pic, h_w, v_w) => + gap8Run(8)( + pic |> + slide(n)(n - 1) |> + mapSeq(fun( + stripe => { + toL1(stripe) |> + mapPar( + fun( + row => { + row |> padCst(1)(1)(cast(l(0)) :: u8) |> mapSeq(fun(x => cast(x) :: i16)) |> + letf(ImageL1_Conv => + gap8hwConv3x3(0)(ImageL1_Conv)(h_w) |> letf(hs => + gap8hwConv3x3(0)(ImageL1_Conv)(v_w)(0) |> letf(vs => + zipND(2)(hs, vs) |> + mapPar(mapPar(fun( + (h, v) => gapSqrt(h * h + v * v) + ))) |> + toL2 + ) + ) + ) + } + ) + ) + } + ) + ) + ) + ) + )*/ + + //2D Zip + //Merge mapPar + //1D slide + /*val againAgainExpr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => + fun(((n * m) `.` u8) ->: (10 `.` i16) ->: (10 `.` i16) ->: (((n - 2) * (m - 2)) `.` i16))((pic, h_w, v_w) => + gap8Run(8)( + pic |> + slide(n)(n - 1) |> + mapSeq(fun( + stripe => { + toL1(stripe) |> + mapPar( + fun( + row => { + row |> padCst(1)(1)(cast(l(0)) :: u8) |> mapSeq(fun(x => cast(x) :: i16)) |> + letf(ImageL1_Conv => + gap8hwConv3x3(0)(ImageL1_Conv)(h_w) |> letf(hs => + gap8hwConv3x3(0)(ImageL1_Conv)(v_w) |> letf(vs => + + zip(hs)(vs) |> + mapPar(fun( + (h, v) => gapSqrt(h * h + v * v) + )) + + + //zipND(2)(hs, vs) |> + // mapPar(mapPar(fun( + // (h, v) => apps.SobelFilter.gapSqrt(h * h + v * v) + // ))) + + ) + ) + ) + } + ) + ) + } + ) + ) + ) + ) + )*/ + + val testL1asdf: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => + fun((n `.` m `.` u8) ->: (n `.` m `.` u8))(in => + gap8Run(8)( + in |> + copyToL1 |> + mapSeq(mapSeq(fun(x => + x * lu8(1) + ))) |> + copyToL2 + ) + ) + ) + + val testL1: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => + fun((n`.`m`.`u8) ->: (n`.`m`.`u8))(in => + //gap8Run(8)( + in |> + //mapSeq(mapSeq(id)) |> + //This determines how the memory will be allocated before + //toL1 |> + + mapSeq(mapSeq(fun(x => + x * lu8(1) + ))) + //) + ) + ) + + //val hostedModule = util.gen.gap8.hosted.fromExpr(testL1) + //val code = shine.GAP8.Module.translateToString(hostedModule) + + //println(code) + + val testSomethingAgain: ToBeTyped[Rise] = depFun((n: Nat) => + fun((n`.`u8) ->: (n`.`u8))(in => + in |> + copyToL1 |> + mapSeq(fun(x => x)) + ) + ) + + val testwhatever: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => + fun( + (n `.` m `.` i16) ->: + (3 `.` 3 `.` i16) ->: + (3 `.` 3 `.` i16) ->: + ((n) `.` (m) `.` i16) + )((in, f1, f2) => + gap8Run(8)( + in |> + copyToL1 |> + mapSeq(fun(x => x)) + ) + )) + + + val testL2: ToBeTyped[Rise] = fun(ArrayType(10, u8) ->: ArrayType(10, u8))(in => + gap8Run(8)( + in |> + mapSeq(fun(x => x)) |> + copyToL1 |> + mapSeq(fun(x => x))// |> + //copyToL2 + //mapSeq(fun(x => x)) + ) + ) + //println(translateToString(util.gen.gap8.hosted.fromExpr(testL2))) + + //println(util.gen.c.function("asdf").asStringFromExpr(testL2)) + + /*val newExpr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => + fun((n `.` m `.` u8) ->: (3 `.` 3 `.` int) ->: (3 `.` 3 `.` int) ->: (n `.` m `.` u8))((pic, h_w, v_w) => + gap8Run(8)( + pic |> + slide(sz = stripe_size, st = stripe_size - 1) |> // create stripes + mapSeq(stripe => // iterate over stripes + toL1(stripe) |> // copy each stripe to L1 + mapPar(row => // pad and convert eafh stripe + row |> padCst(1) |> mapSeq(x => cast(x) :: short_int)) |> + letf(imageL1conv => + hwce3x3(imageL1conv, h_w) |> letf(hs: 2D => // perform horizontal convolution + hwce3x3(imageL1conv, h_v) |> letf(vs: 2D => // perform vertical convolution + zip2D(hs, vs) |> + mapPar(mapPar((h, v) => sqrt(h * h, v * v))) |> // combine horizontal and vertical convolutions + toL2 // copy back to L2 + ) + ) + ) + ) + ) + ) + )*/ + + val expr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat, o: Nat) => + fun((n`.`o`.`u32) ->: (o`.`m`.`u32) ->: (n`.`m`.`u32))((a, b) => + //gap8Run(8)( + a |> mapSeq(fun(rowa => + b |> transpose |> mapSeq(fun(colb => + zip(rowa)(colb) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(cast(l(0)) :: u32) + )) + )) + //) + ) + ) + + val expr123: ToBeTyped[Rise] = depFun((n: Nat, m: Nat, o: Nat) => + fun(ArrayType(n, ArrayType(m, u32)) ->: (o `.` m `.` u32) ->: (n `.` m `.` u32))((a, b) => + //gap8Run(8)( + a |> mapSeq(fun(rowa => + b |> transpose |> mapSeq(fun(colb => + zip(rowa)(colb) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(cast(l(0)) :: u32) + )) + )) + //) + ) + ) + + //println(util.gen.c.function("matmul").asStringFromExpr(expr)) + + //val code = util.gen.openmp.function("matmul").asStringFromExpr(expr) + + + + /*def weights2d(ws: Seq[Seq[Int]]): ToBeTyped[Expr] = + larr(ws.map(r => ArrayData(r.map(x => IntData(x))))) + + val sobelXWeights2d: ToBeTyped[Expr] = weights2d(Seq( + Seq(-1, 0, +1), + Seq(-2, 0, +2), + Seq(-1, 0, +1) + ))*/ + + /*val matAddFixed: ToBeTyped[Expr] = + fun(ArrayType(3, ArrayType(3, int)) ->: ArrayType(3, ArrayType(3, int)) ->: ArrayType(3, ArrayType(3, int)))((x, y) => + //gap8Run(8)( + zip(x)(y) |> + map(fun(pair => zip(fst(pair))(snd(pair)))) |> + mapSeq(mapSeq(fun(pair => fst(pair) + snd(pair)))) + //) + )(sobelXWeights2d)*/ + + val matAdd: ToBeTyped[Expr] = depFun((n: Nat, m: Nat) => + fun(ArrayType(n, ArrayType(m, u32)) ->: ArrayType(n, ArrayType(m, u32)) ->: ArrayType(n, ArrayType(m, u32)))((x, y) => + gap8Run(8)( + zip(x)(y) |> + map(fun(pair => zip(fst(pair))(snd(pair)))) |> + mapPar(mapPar(fun(pair => fst(pair) + snd(pair)))) + ) + ) + ) + + val conv: Strategy[Rise] = + (gap8hwConvMerge `@` everywhere) + + //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(conv(expr).get))) + //println("MatAdd") + //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted("matadd").fromExpr(matAddFixed))) + //println(util.gen.c.function("matadd").asStringFromExpr(matAddFixed)) + + /*val simple: Strategy[Rise] = + (`map -> mapSeq` `@` everywhere)*/ + + + val optimizationStrategy: Strategy[Rise] = + (`map -> mapPar` `@` outermost(isPrimitive(map))) `;` + (`map -> mapSeq` `@` outermost(isPrimitive(map))) `;` + (`reduce -> reduceSeq` `@` everywhere) + +/* + val anotherOptimizationStrategy: Strategy[Rise] = + (`map >> reduce -> reduce` `@` everywhere) `;` + (`map -> mapSeq` `@` everywhere) `;` + (`reduce -> reduceSeq` `@` everywhere) + + val myStrategy: Strategy[Rise] = + (`map >> reduce -> reduce` `@` everywhere) `;` + (`map -> mapPar` `@` outermost(isPrimitive(map))) `;` + (`map -> mapSeq` `@` everywhere) + + val yetAnotherOptimizationStrategy: Strategy[Rise] = + innermost(isAppliedMap)( + `map(f) -> asVector >> map(f_vec) >> asScalar`(4) `;` + (`map -> mapSeq` `@` innermost(isPrimitive(map))) `;` + storeTempAsVectors + ) `;` + optimizationStrategy*/ + + //println(highLevelProgram) + //println(optimizationStrategy(highLevelProgram).get) + //println(myStrategy(highLevelProgram).get) + + //println(util.gen.openmp.function("asdf").asStringFromExpr(optimizationStrategy(expr).get)) + + //println(expr) + //println(optimizationStrategy(expr).get) + + //println(util.gen.openmp.function("asdf").asStringFromExpr(myStrategy(highLevelProgram).get)) + + //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(myStrategy(highLevelProgram).get))) + //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(highLevelProgram))) + + //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(expr))) + + //val sth = u32 ->: i16 ->: u8 + //println(sth) + } +} From e2a899ee078baa9c882e760efb69b7c0d5afb39a Mon Sep 17 00:00:00 2001 From: bpervan Date: Sun, 22 Oct 2023 22:47:48 +0200 Subject: [PATCH 83/86] 2D Loop transfer codegen (proto, unfinished) --- .../GAP8/Compilation/AcceleratorCodeGenerator.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala index 389300559..cdecea538 100644 --- a/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala +++ b/src/main/scala/shine/GAP8/Compilation/AcceleratorCodeGenerator.scala @@ -223,6 +223,18 @@ class AcceleratorCodeGenerator(override val decls: C.Compilation.CodeGenerator.D offsetX: Int, offsetY: Int): Stmt = { val firstVar = freshName("dma2d_") val secondVar = freshName("dma2d_") + + /*C.AST.FunDecl( + name="ex_mapfor", + returnType = C.AST.Type.void, + params = Seq( + C.AST.ParamDecl("output", C.AST.PointerType(C.AST.Type.int)), + C.AST.ParamDecl("n446", C.AST.Type.int), + C.AST.ParamDecl("e447", C.AST.PointerType(C.AST.Type.int)) + ), + body = C.AST.Stmts(C.AST.Code("asdf"), C.AST.ForLoop(???, ???, ???, ???)) + )*/ + C.AST.ForLoop( init = C.AST.DeclStmt(C.AST.VarDecl(firstVar, C.AST.Type.int, None)), cond = C.AST.BinaryExpr(C.AST.Literal(firstVar), C.AST.BinaryOperator.<, C.AST.Literal(width.toString)), From 5cd93e91b234ca050ce0a9cf9882612837f75dd1 Mon Sep 17 00:00:00 2001 From: Branimir Pervan Date: Tue, 24 Oct 2023 13:02:28 +0200 Subject: [PATCH 84/86] Added Sobel without pad --- src/main/scala/apps/tester.scala | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/scala/apps/tester.scala b/src/main/scala/apps/tester.scala index ec7bd97d4..b9b7b1e87 100644 --- a/src/main/scala/apps/tester.scala +++ b/src/main/scala/apps/tester.scala @@ -3,7 +3,7 @@ package apps import elevate.core._ import rise.GAP8.DSL.gap8Run import rise.GAP8.primitives.{copyToL1, copyToL2, gap8hwConv3x3} -import rise.core.DSL.HighLevelConstructs.zipND +import rise.core.DSL.HighLevelConstructs.{slide2D, zipND} import rise.core.DSL.Type._ import rise.core.DSL._ import rise.core._ @@ -44,9 +44,35 @@ object tester { | return res; | } |""".stripMargin, - i16 ->: i16 + u32 ->: u32 ) + val h: Nat = 240 + val w: Nat = 320 + + + //(h`.`w`.`u8) ->: (3`.`3`.`int) ->: (3`.`3`.`int) ->: (h`.`w`.`u8 + val sobelWithoutPad: ToBeTyped[Rise] = + fun( + ArrayType(h, ArrayType(w, u8)) ->: + ArrayType(3, ArrayType(3, u8)) ->: + ArrayType(3, ArrayType(3, u8)) ->: + ArrayType(h - 2, ArrayType(w - 2, u8)) + )((pic, hf, vf) => + gap8Run(8)( + pic |> + slide2D(sz = 3, st = 1) |> + mapSeq(mapSeq(fun(submat => + zip(submat |> join)(hf |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeq(add)(cast(l(0)) :: u32) |> letf(h => + zip(submat |> join)(vf |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeq(add)(cast(l(0)) :: u32) |> letf(v => + cast(gapSqrt(h * h + v * v)) :: u8 + ) + ) + )))) + ) + + println(translateToString(util.gen.gap8.hosted("SobelWOutPad").fromExpr(sobelWithoutPad))) + //2D Zip //Merge mapPar //1D slide From 880db25a6e0cf961447924f478398a122da8d004 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 24 Oct 2023 15:01:17 +0200 Subject: [PATCH 85/86] Added SobelWithoutPadHWCE, slightly changed SobelWithoutPad --- src/main/scala/apps/tester.scala | 39 ++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/scala/apps/tester.scala b/src/main/scala/apps/tester.scala index b9b7b1e87..8805ba641 100644 --- a/src/main/scala/apps/tester.scala +++ b/src/main/scala/apps/tester.scala @@ -2,7 +2,7 @@ package apps import elevate.core._ import rise.GAP8.DSL.gap8Run -import rise.GAP8.primitives.{copyToL1, copyToL2, gap8hwConv3x3} +import rise.GAP8.primitives.{allocL2, copyToL1, copyToL2, gap8hwConv3x3} import rise.core.DSL.HighLevelConstructs.{slide2D, zipND} import rise.core.DSL.Type._ import rise.core.DSL._ @@ -55,23 +55,48 @@ object tester { val sobelWithoutPad: ToBeTyped[Rise] = fun( ArrayType(h, ArrayType(w, u8)) ->: - ArrayType(3, ArrayType(3, u8)) ->: - ArrayType(3, ArrayType(3, u8)) ->: + ArrayType(3, ArrayType(3, int)) ->: + ArrayType(3, ArrayType(3, int)) ->: ArrayType(h - 2, ArrayType(w - 2, u8)) )((pic, hf, vf) => gap8Run(8)( pic |> slide2D(sz = 3, st = 1) |> - mapSeq(mapSeq(fun(submat => - zip(submat |> join)(hf |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeq(add)(cast(l(0)) :: u32) |> letf(h => - zip(submat |> join)(vf |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> reduceSeq(add)(cast(l(0)) :: u32) |> letf(v => + mapPar(mapPar(fun(submat => + zip(submat |> join)(hf |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> rise.core.primitives.reduceSeqUnroll(add)(cast(l(0)) :: u32) |> letf(h => + zip(submat |> join)(vf |> join) |> map(fun(x => (cast(fst(x)) :: u32) * cast(snd(x)) :: u32)) |> rise.core.primitives.reduceSeqUnroll(add)(cast(l(0)) :: u32) |> letf(v => cast(gapSqrt(h * h + v * v)) :: u8 ) ) )))) ) - println(translateToString(util.gen.gap8.hosted("SobelWOutPad").fromExpr(sobelWithoutPad))) + //println(translateToString(util.gen.gap8.hosted("SobelWOutPad").fromExpr(sobelWithoutPad))) + + val sobelWithoutPadHWCE: ToBeTyped[Rise] = { + fun( + ArrayType(h, ArrayType(w, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(3, ArrayType(3, i16)) ->: + ArrayType(h - 2, ArrayType(w - 2, i16)) + )((pic, hf, vf) => + gap8Run(8)( + pic |> + gap8hwConv3x3(0)(pic, hf) |> allocL2 |> letf(hconvres => + gap8hwConv3x3(0)(pic, vf) |> allocL2 |> letf(vconvres => + zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => + cast(gapSqrt( + cast(add + (mul(fst(elems))(fst(elems))) + (mul(snd(elems))(snd(elems)))) :: u32 + )) :: i16 + ))) + ) + ) + ) + ) + } + println(translateToString(util.gen.gap8.hosted("SobelWOutPadHWCE").fromExpr(sobelWithoutPadHWCE))) //2D Zip //Merge mapPar From acd34913cbc72e02bbfc83fb1ceaf6ff25567626 Mon Sep 17 00:00:00 2001 From: bpervan Date: Tue, 24 Oct 2023 23:32:58 +0200 Subject: [PATCH 86/86] tester cleanup; GAP8HwceDma added Gaussian blur variants (plain, HWCE, HWCE + tiling); To be further cleaned and reorganized --- src/main/scala/apps/GAP8HwceDma.scala | 31 ++- src/main/scala/apps/tester.scala | 271 ++------------------------ 2 files changed, 40 insertions(+), 262 deletions(-) diff --git a/src/main/scala/apps/GAP8HwceDma.scala b/src/main/scala/apps/GAP8HwceDma.scala index 327f0135c..04fcb22bb 100644 --- a/src/main/scala/apps/GAP8HwceDma.scala +++ b/src/main/scala/apps/GAP8HwceDma.scala @@ -3,8 +3,8 @@ package apps import arithexpr.arithmetic.NamedVar import elevate.core.Strategy import rise.GAP8.DSL.gap8Run -import rise.GAP8.primitives.{allocL1, copy2DOffsetToL1, copyToL1, copyToL2, gap8hwConv3x3, gap8hwConv5x5} -import rise.core.DSL.HighLevelConstructs.{padCst2D, zipND} +import rise.GAP8.primitives.{allocL1, allocL2, copy2DOffsetToL1, copyToL1, copyToL2, gap8hwConv3x3, gap8hwConv5x5} +import rise.core.DSL.HighLevelConstructs.{padCst2D, slide2D, zipND} import rise.core.DSL.Type.TypeConstructors import rise.core.DSL.{ToBeTyped, depFun, foreignFun, fun, letf, li16} import rise.core.primitives._ @@ -20,6 +20,7 @@ import shine.GAP8.Module.translateToString // scalastyle: off object GAP8HwceDma { def main(args: Array[String]): Unit = { + //24.10.2023. If Type is i16 -> i16, one should be 1u << 14 val gapSqrt = foreignFun("gap_sqrt", Seq("a_nInput"), """ @@ -305,6 +306,32 @@ object GAP8HwceDma { ) println(translateToString(util.gen.gap8.hosted("GaussianBlur").fromExpr(tiledFixSizeDmaHwceNoPadding_Gaussian))) + val gaussianNoPadHWCE: ToBeTyped[Rise] = fun( + ArrayType(hh, ArrayType(ww, i16)) ->: + ArrayType(5, ArrayType(5, i16)) ->: + ArrayType(hh - 4, ArrayType(ww - 4, i16)) + )((pic, filter) => + gap8Run(8)( + gap8hwConv5x5(0)(pic, filter) + ) + ) + println(translateToString(util.gen.gap8.hosted("GaussianBlur_HWCE").fromExpr(gaussianNoPadHWCE))) + + val gaussianBlurPlain: ToBeTyped[Rise] = fun( + ArrayType(hh, ArrayType(ww, i16)) ->: + ArrayType(5, ArrayType(5, i16)) ->: + ArrayType(hh - 4, ArrayType(ww - 4, i16)) + )((pic, filter) => + gap8Run(8)( + pic |> + slide2D(sz = 5, st = 1) |> + mapPar(mapPar(fun(submat => + zip(submat |> join)(filter |> join) |> map(fun(e => fst(e) * snd(e))) |> reduceSeqUnroll(add)(li16(0)) + ))) + ) + ) + println(translateToString(util.gen.gap8.hosted("GaussianBlur_Plain").fromExpr(gaussianBlurPlain))) + /*val strategy: Strategy[Rise] = `map -> mapPar` `@` everywhere val ex_mapfor: ToBeTyped[Rise] = depFun((n: Nat) => diff --git a/src/main/scala/apps/tester.scala b/src/main/scala/apps/tester.scala index 8805ba641..16b3efaa2 100644 --- a/src/main/scala/apps/tester.scala +++ b/src/main/scala/apps/tester.scala @@ -2,14 +2,14 @@ package apps import elevate.core._ import rise.GAP8.DSL.gap8Run -import rise.GAP8.primitives.{allocL2, copyToL1, copyToL2, gap8hwConv3x3} +import rise.GAP8.primitives.{allocL1, allocL2, copyToL1, copyToL2, gap8hwConv3x3} import rise.core.DSL.HighLevelConstructs.{slide2D, zipND} import rise.core.DSL.Type._ import rise.core.DSL._ import rise.core._ import rise.core.primitives.{mapSeq, reduceSeq, let => _, _} import rise.core.types.DataType.{ArrayType, i16, int, u32, u8} -import rise.core.types._ +import rise.core.types.{DataType, _} import rise.elevate._ import rise.elevate.rules.algorithmic._ import rise.elevate.rules.lowering._ @@ -29,7 +29,7 @@ object tester { | uint32_t op = a_nInput; | uint32_t res = 0; | - | uint32_t one = 1uL << 30; + | uint32_t one = 1u << 14; | while (one > op){ | one >>= 2; | } @@ -44,14 +44,12 @@ object tester { | return res; | } |""".stripMargin, - u32 ->: u32 + i16 ->: i16 ) val h: Nat = 240 val w: Nat = 320 - - //(h`.`w`.`u8) ->: (3`.`3`.`int) ->: (3`.`3`.`int) ->: (h`.`w`.`u8 val sobelWithoutPad: ToBeTyped[Rise] = fun( ArrayType(h, ArrayType(w, u8)) ->: @@ -73,6 +71,7 @@ object tester { //println(translateToString(util.gen.gap8.hosted("SobelWOutPad").fromExpr(sobelWithoutPad))) + //TODO: Check gapSqrt type, it's changed above just to fit this expression type val sobelWithoutPadHWCE: ToBeTyped[Rise] = { fun( ArrayType(h, ArrayType(w, i16)) ->: @@ -81,242 +80,21 @@ object tester { ArrayType(h - 2, ArrayType(w - 2, i16)) )((pic, hf, vf) => gap8Run(8)( - pic |> + //pic |> + //pic is 320 x 240 gap8hwConv3x3(0)(pic, hf) |> allocL2 |> letf(hconvres => gap8hwConv3x3(0)(pic, vf) |> allocL2 |> letf(vconvres => + //hconvres and vconvres are 318x238 zipND(2)(hconvres)(vconvres) |> mapPar(mapPar(fun(elems => - cast(gapSqrt( - cast(add - (mul(fst(elems))(fst(elems))) - (mul(snd(elems))(snd(elems)))) :: u32 - )) :: i16 + gapSqrt(add(mul(fst(elems))(fst(elems)))(mul(snd(elems))(snd(elems)))) ))) ) - ) - ) - ) - } - println(translateToString(util.gen.gap8.hosted("SobelWOutPadHWCE").fromExpr(sobelWithoutPadHWCE))) - - //2D Zip - //Merge mapPar - //1D slide - /*val againExpr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => - fun((n `.` m `.` u8) ->: (3 `.` 3 `.` i16) ->: (3 `.` 3 `.` i16) ->: ((n - 2) `.` (m - 2) `.` i16))((pic, h_w, v_w) => - gap8Run(8)( - pic |> - slide(n)(n - 1) |> - mapSeq(fun( - stripe => { - toL1(stripe) |> - mapPar( - fun( - row => { - row |> padCst(1)(1)(cast(l(0)) :: u8) |> mapSeq(fun(x => cast(x) :: i16)) |> - letf(ImageL1_Conv => - gap8hwConv3x3(0)(ImageL1_Conv)(h_w) |> letf(hs => - gap8hwConv3x3(0)(ImageL1_Conv)(v_w)(0) |> letf(vs => - zipND(2)(hs, vs) |> - mapPar(mapPar(fun( - (h, v) => gapSqrt(h * h + v * v) - ))) |> - toL2 - ) - ) - ) - } - ) - ) - } - ) - ) - ) - ) - )*/ - - //2D Zip - //Merge mapPar - //1D slide - /*val againAgainExpr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => - fun(((n * m) `.` u8) ->: (10 `.` i16) ->: (10 `.` i16) ->: (((n - 2) * (m - 2)) `.` i16))((pic, h_w, v_w) => - gap8Run(8)( - pic |> - slide(n)(n - 1) |> - mapSeq(fun( - stripe => { - toL1(stripe) |> - mapPar( - fun( - row => { - row |> padCst(1)(1)(cast(l(0)) :: u8) |> mapSeq(fun(x => cast(x) :: i16)) |> - letf(ImageL1_Conv => - gap8hwConv3x3(0)(ImageL1_Conv)(h_w) |> letf(hs => - gap8hwConv3x3(0)(ImageL1_Conv)(v_w) |> letf(vs => - - zip(hs)(vs) |> - mapPar(fun( - (h, v) => gapSqrt(h * h + v * v) - )) - - - //zipND(2)(hs, vs) |> - // mapPar(mapPar(fun( - // (h, v) => apps.SobelFilter.gapSqrt(h * h + v * v) - // ))) - - ) - ) - ) - } - ) - ) - } - ) - ) - ) - ) - )*/ - - val testL1asdf: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => - fun((n `.` m `.` u8) ->: (n `.` m `.` u8))(in => - gap8Run(8)( - in |> - copyToL1 |> - mapSeq(mapSeq(fun(x => - x * lu8(1) - ))) |> - copyToL2 - ) - ) - ) - - val testL1: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => - fun((n`.`m`.`u8) ->: (n`.`m`.`u8))(in => - //gap8Run(8)( - in |> - //mapSeq(mapSeq(id)) |> - //This determines how the memory will be allocated before - //toL1 |> - - mapSeq(mapSeq(fun(x => - x * lu8(1) - ))) - //) - ) - ) - - //val hostedModule = util.gen.gap8.hosted.fromExpr(testL1) - //val code = shine.GAP8.Module.translateToString(hostedModule) - - //println(code) - - val testSomethingAgain: ToBeTyped[Rise] = depFun((n: Nat) => - fun((n`.`u8) ->: (n`.`u8))(in => - in |> - copyToL1 |> - mapSeq(fun(x => x)) - ) - ) - - val testwhatever: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => - fun( - (n `.` m `.` i16) ->: - (3 `.` 3 `.` i16) ->: - (3 `.` 3 `.` i16) ->: - ((n) `.` (m) `.` i16) - )((in, f1, f2) => - gap8Run(8)( - in |> - copyToL1 |> - mapSeq(fun(x => x)) - ) - )) - - - val testL2: ToBeTyped[Rise] = fun(ArrayType(10, u8) ->: ArrayType(10, u8))(in => - gap8Run(8)( - in |> - mapSeq(fun(x => x)) |> - copyToL1 |> - mapSeq(fun(x => x))// |> - //copyToL2 - //mapSeq(fun(x => x)) - ) - ) - //println(translateToString(util.gen.gap8.hosted.fromExpr(testL2))) - - //println(util.gen.c.function("asdf").asStringFromExpr(testL2)) - - /*val newExpr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat) => - fun((n `.` m `.` u8) ->: (3 `.` 3 `.` int) ->: (3 `.` 3 `.` int) ->: (n `.` m `.` u8))((pic, h_w, v_w) => - gap8Run(8)( - pic |> - slide(sz = stripe_size, st = stripe_size - 1) |> // create stripes - mapSeq(stripe => // iterate over stripes - toL1(stripe) |> // copy each stripe to L1 - mapPar(row => // pad and convert eafh stripe - row |> padCst(1) |> mapSeq(x => cast(x) :: short_int)) |> - letf(imageL1conv => - hwce3x3(imageL1conv, h_w) |> letf(hs: 2D => // perform horizontal convolution - hwce3x3(imageL1conv, h_v) |> letf(vs: 2D => // perform vertical convolution - zip2D(hs, vs) |> - mapPar(mapPar((h, v) => sqrt(h * h, v * v))) |> // combine horizontal and vertical convolutions - toL2 // copy back to L2 - ) ) ) ) - ) - ) - )*/ - - val expr: ToBeTyped[Rise] = depFun((n: Nat, m: Nat, o: Nat) => - fun((n`.`o`.`u32) ->: (o`.`m`.`u32) ->: (n`.`m`.`u32))((a, b) => - //gap8Run(8)( - a |> mapSeq(fun(rowa => - b |> transpose |> mapSeq(fun(colb => - zip(rowa)(colb) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(cast(l(0)) :: u32) - )) - )) - //) - ) - ) - - val expr123: ToBeTyped[Rise] = depFun((n: Nat, m: Nat, o: Nat) => - fun(ArrayType(n, ArrayType(m, u32)) ->: (o `.` m `.` u32) ->: (n `.` m `.` u32))((a, b) => - //gap8Run(8)( - a |> mapSeq(fun(rowa => - b |> transpose |> mapSeq(fun(colb => - zip(rowa)(colb) |> map(fun(x => fst(x) * snd(x))) |> reduceSeq(add)(cast(l(0)) :: u32) - )) - )) - //) - ) - ) - - //println(util.gen.c.function("matmul").asStringFromExpr(expr)) - - //val code = util.gen.openmp.function("matmul").asStringFromExpr(expr) - - - - /*def weights2d(ws: Seq[Seq[Int]]): ToBeTyped[Expr] = - larr(ws.map(r => ArrayData(r.map(x => IntData(x))))) - - val sobelXWeights2d: ToBeTyped[Expr] = weights2d(Seq( - Seq(-1, 0, +1), - Seq(-2, 0, +2), - Seq(-1, 0, +1) - ))*/ + } + //println(translateToString(util.gen.gap8.hosted("SobelWOutPadHWCE").fromExpr(sobelWithoutPadHWCE))) - /*val matAddFixed: ToBeTyped[Expr] = - fun(ArrayType(3, ArrayType(3, int)) ->: ArrayType(3, ArrayType(3, int)) ->: ArrayType(3, ArrayType(3, int)))((x, y) => - //gap8Run(8)( - zip(x)(y) |> - map(fun(pair => zip(fst(pair))(snd(pair)))) |> - mapSeq(mapSeq(fun(pair => fst(pair) + snd(pair)))) - //) - )(sobelXWeights2d)*/ val matAdd: ToBeTyped[Expr] = depFun((n: Nat, m: Nat) => fun(ArrayType(n, ArrayType(m, u32)) ->: ArrayType(n, ArrayType(m, u32)) ->: ArrayType(n, ArrayType(m, u32)))((x, y) => @@ -331,14 +109,6 @@ object tester { val conv: Strategy[Rise] = (gap8hwConvMerge `@` everywhere) - //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(conv(expr).get))) - //println("MatAdd") - //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted("matadd").fromExpr(matAddFixed))) - //println(util.gen.c.function("matadd").asStringFromExpr(matAddFixed)) - - /*val simple: Strategy[Rise] = - (`map -> mapSeq` `@` everywhere)*/ - val optimizationStrategy: Strategy[Rise] = (`map -> mapPar` `@` outermost(isPrimitive(map))) `;` @@ -363,24 +133,5 @@ object tester { storeTempAsVectors ) `;` optimizationStrategy*/ - - //println(highLevelProgram) - //println(optimizationStrategy(highLevelProgram).get) - //println(myStrategy(highLevelProgram).get) - - //println(util.gen.openmp.function("asdf").asStringFromExpr(optimizationStrategy(expr).get)) - - //println(expr) - //println(optimizationStrategy(expr).get) - - //println(util.gen.openmp.function("asdf").asStringFromExpr(myStrategy(highLevelProgram).get)) - - //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(myStrategy(highLevelProgram).get))) - //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(highLevelProgram))) - - //println(shine.GAP8.Module.translateToString(util.gen.gap8.hosted.fromExpr(expr))) - - //val sth = u32 ->: i16 ->: u8 - //println(sth) } }