Skip to content

Commit 79b5339

Browse files
committed
another version
1 parent f52c785 commit 79b5339

File tree

16 files changed

+231
-103
lines changed

16 files changed

+231
-103
lines changed
Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
package io.computenode.cyfra.core
22

3+
import io.computenode.cyfra.core.layout.{Layout, LayoutStruct}
34
import io.computenode.cyfra.dsl.Value
5+
import io.computenode.cyfra.dsl.Value.FromExpr
46
import io.computenode.cyfra.dsl.binding.GBuffer
7+
import izumi.reflect.Tag
58

69
import java.nio.ByteBuffer
710

811
trait Allocation:
912
extension [R, T <: Value](buffer: GBuffer[T])
10-
def read(bb: ByteBuffer): Unit =
11-
()
13+
def read(bb: ByteBuffer): Unit
14+
15+
def write(bb: ByteBuffer): Unit
16+
17+
extension [Params, L <: Layout, RL <: Layout : LayoutStruct](execution: GExecution[Params, L, RL])
18+
def execute(params: Params, layout: L): RL
1219

13-
def write(bb: ByteBuffer): Unit =
14-
()
20+
object Allocation:
21+
22+
trait InitAlloc:
23+
extension (buffers: GBuffer.type)
24+
def apply[T <: Value : Tag : FromExpr](size: Int): GBuffer[T]
25+
26+
def apply[T <: Value : Tag : FromExpr](buff: ByteBuffer): GBuffer[T]
27+
28+
trait FinalizeAlloc:
29+
extension [T <: Value](buffer: GBuffer[T])
30+
def readTo(bb: ByteBuffer): Unit
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.computenode.cyfra.core
2+
3+
import io.computenode.cyfra.core.Allocation.{FinalizeAlloc, InitAlloc}
4+
5+
trait CyfraRuntime:
6+
7+
def allocation(): Allocation
8+
9+
def initAlloc(allocation: Allocation): InitAlloc
10+
11+
def finalizeAlloc(allocation: Allocation): FinalizeAlloc
12+
13+
Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,20 @@
11
package io.computenode.cyfra.core
22

3+
import io.computenode.cyfra.core.Allocation.{FinalizeAlloc, InitAlloc}
34
import io.computenode.cyfra.core.GProgram.BufferSizeSpec
45
import io.computenode.cyfra.core.layout.{Layout, LayoutStruct}
56
import io.computenode.cyfra.dsl.Value
7+
import io.computenode.cyfra.dsl.Value.FromExpr
68
import io.computenode.cyfra.dsl.binding.GBuffer
9+
import izumi.reflect.Tag
710

811
import java.nio.ByteBuffer
912

1013
sealed trait GBufferRegion[ReqAlloc <: Layout: LayoutStruct, ResAlloc <: Layout: LayoutStruct]:
1114
val initAlloc: ReqAlloc
1215

1316
object GBufferRegion:
14-
15-
private[cyfra] case class ZeroedBuffer[T <: Value](size: Int) extends GBuffer[T]
16-
17-
private[cyfra] case class BufferFromRam[T <: Value](buff: ByteBuffer) extends GBuffer[T]
18-
19-
trait InitAlloc:
20-
extension (buffers: GBuffer.type)
21-
def apply[T <: Value](size: Int): GBuffer[T] =
22-
ZeroedBuffer[T](size)
23-
24-
def apply[T <: Value](buff: ByteBuffer): GBuffer[T] =
25-
BufferFromRam[T](buff)
26-
27-
trait FinalizeAlloc:
28-
extension [T <: Value](buffer: GBuffer[T])
29-
def readTo(bb: ByteBuffer): Unit =
30-
()
31-
17+
3218
def allocate[Alloc <: Layout: LayoutStruct]: GBufferRegion[Alloc, Alloc] =
3319
AllocRegion(summon[LayoutStruct[Alloc]].layoutRef)
3420

@@ -45,17 +31,18 @@ object GBufferRegion:
4531
def map[NewAlloc <: Layout: LayoutStruct](f: Allocation ?=> ResAlloc => NewAlloc): GBufferRegion[ReqAlloc, NewAlloc] =
4632
MapRegion(region, (alloc: Allocation) => (resAlloc: ResAlloc) => f(using alloc)(resAlloc))
4733

48-
def runUnsafe(init: InitAlloc ?=> ReqAlloc, onDone: FinalizeAlloc ?=> ResAlloc => Unit): Unit =
49-
val initAlloc = new InitAlloc {}
34+
def runUnsafe(init: InitAlloc ?=> ReqAlloc, onDone: FinalizeAlloc ?=> ResAlloc => Unit)(using cyfraRuntime: CyfraRuntime): Unit =
35+
val allocation = cyfraRuntime.allocation()
36+
val initAlloc = cyfraRuntime.initAlloc(allocation)
5037
init(using initAlloc)
51-
val alloc = new Allocation {}
38+
5239
val steps: Seq[Allocation => Layout => Layout] = Seq.unfold(region: GBufferRegion[?, ?]):
5340
case _: AllocRegion[?] => None
5441
case MapRegion(req, f) =>
5542
Some((f.asInstanceOf[Allocation => Layout => Layout], req))
5643

5744
val bodyAlloc = steps.foldLeft[Layout](region.initAlloc): (acc, step) =>
58-
step(alloc)(acc)
45+
step(allocation)(acc)
5946

60-
val finalizeAlloc = new FinalizeAlloc {}
47+
val finalizeAlloc = cyfraRuntime.finalizeAlloc(allocation)
6148
onDone(using finalizeAlloc)(bodyAlloc.asInstanceOf[ResAlloc])

cyfra-core/src/main/scala/io/computenode/cyfra/core/GExecution.scala

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@ import izumi.reflect.Tag
1111
import GExecution.*
1212

1313
trait GExecution[-Params, -L <: Layout, +RL <: Layout]:
14-
def execute(layout: L, params: Params)(using Allocation): RL =
15-
println("Executing GExecution...")
16-
???
1714

1815
def flatMap[NRL <: Layout, NP <: Params, NL <: L](f: RL => GExecution[NP, NL, NRL]): GExecution[NP, NL, NRL] =
19-
FlatMap(this, f)
16+
FlatMap(this, (p, r) => f(r))
2017

2118
def mapResult[NRL <: Layout](f: RL => NRL): GExecution[Params, L, NRL] =
2219
Map(this, f, identity, identity)
@@ -36,16 +33,26 @@ trait GExecution[-Params, -L <: Layout, +RL <: Layout]:
3633

3734
object GExecution:
3835

39-
def forParams[Params, L <: Layout, LR <: Layout, NP](fn: Params => GExecution[NP, L, LR]): GExecution[Params & NP, L, LR] =
40-
???
41-
42-
private case class FlatMap[Params, L <: Layout, RL <: Layout, NRL <: Layout](
36+
def apply[Params, L <: Layout]() =
37+
Pure[Params, L, L]()
38+
39+
def forParams[Params, L <: Layout, RL <: Layout](
40+
f: Params => GExecution[Params, L, RL],
41+
): GExecution[Params, L, RL] =
42+
FlatMap[Params, L, RL, RL](
43+
Pure[Params, L, RL](),
44+
(params: Params, _: RL) => f(params),
45+
)
46+
47+
case class Pure[Params, L <: Layout, RL <: Layout]() extends GExecution[Params, L, RL]
48+
49+
case class FlatMap[Params, L <: Layout, RL <: Layout, NRL <: Layout](
4350
execution: GExecution[Params, L, RL],
44-
f: RL => GExecution[Params, L, NRL],
51+
f: (Params, RL) => GExecution[Params, L, NRL],
4552
) extends GExecution[Params, L, NRL]
4653

4754

48-
private case class Map[P, NP, L <: Layout, NL <: Layout, RL <: Layout, NRL <: Layout](
55+
case class Map[P, NP, L <: Layout, NL <: Layout, RL <: Layout, NRL <: Layout](
4956
execution: GExecution[P, L, RL],
5057
mapResult: RL => NRL,
5158
contramapLayout: NL => L,
@@ -60,9 +67,3 @@ object GExecution:
6067

6168
override def contramapLayout[NNL <: Layout](f: NNL => NL): GExecution[NP, NNL, NRL] =
6269
Map(execution, mapResult, f andThen contramapLayout, contramapParams)
63-
64-
case class BoundProgram[LParams, Params, L <: Layout](
65-
layout: L,
66-
paramsMapping: LParams => Params,
67-
program: GProgram[Params, L],
68-
)

cyfra-core/src/main/scala/io/computenode/cyfra/core/GProgram.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import io.computenode.cyfra.core.layout.Layout
77
import java.nio.ByteBuffer
88
import GProgram.*
99
import io.computenode.cyfra.dsl.Value
10+
import io.computenode.cyfra.dsl.Value.FromExpr
1011
import io.computenode.cyfra.dsl.binding.{GBuffer, GUniform}
1112
import io.computenode.cyfra.dsl.struct.GStruct
1213
import io.computenode.cyfra.dsl.struct.GStruct.Empty
@@ -30,22 +31,22 @@ object GProgram:
3031

3132
case class StaticDispatch(size: WorkDimensions) extends ProgramDispatch
3233

33-
private[cyfra] case class BufferSizeSpec[T <: Value](size: Int) extends GBuffer[T]
34+
private[cyfra] case class BufferSizeSpec[T <: Value: Tag: FromExpr](size: Int) extends GBuffer[T]
3435

35-
private[cyfra] case class ParamUniform[T <: GStruct[T]: Tag](value: T) extends GUniform[T]
36+
private[cyfra] case class ParamUniform[T <: GStruct[T]: Tag: FromExpr](value: T) extends GUniform[T]
3637

37-
private[cyfra] case class DynamicUniform[T <: GStruct[T]: Tag]() extends GUniform[T]
38+
private[cyfra] case class DynamicUniform[T <: GStruct[T]: Tag: FromExpr]() extends GUniform[T]
3839

3940
trait InitProgramLayout:
4041
extension (buffers: GBuffer.type)
41-
def apply[T <: Value](size: Int): GBuffer[T] =
42+
def apply[T <: Value: Tag: FromExpr](size: Int): GBuffer[T] =
4243
BufferSizeSpec[T](size)
4344

4445
extension (uniforms: GUniform.type)
45-
def apply[T <: GStruct[T]: Tag](value: T): GUniform[T] =
46+
def apply[T <: GStruct[T]: Tag: FromExpr](value: T): GUniform[T] =
4647
ParamUniform[T](value)
4748

48-
def apply[T <: GStruct[T]: Tag](): GUniform[T] =
49+
def apply[T <: GStruct[T]: Tag: FromExpr](): GUniform[T] =
4950
DynamicUniform[T]()
5051

5152
def apply[Params, L <: Layout: LayoutStruct](
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package io.computenode.cyfra.core.binding
22

33
import io.computenode.cyfra.dsl.Value
4+
import io.computenode.cyfra.dsl.Value.FromExpr
45
import io.computenode.cyfra.dsl.binding.GBuffer
56
import izumi.reflect.Tag
67
import izumi.reflect.macrortti.LightTypeTag
78

8-
case class BufferRef[T <: Value](layoutOffset: Int, valueTag: Tag[T]) extends GBuffer[T]
9+
case class BufferRef[T <: Value: Tag: FromExpr](layoutOffset: Int, valueTag: Tag[T]) extends GBuffer[T]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.computenode.cyfra.core.binding
2+
3+
import io.computenode.cyfra.dsl.Value
4+
import io.computenode.cyfra.dsl.Value.FromExpr
5+
import io.computenode.cyfra.dsl.binding.{GBuffer, GUniform}
6+
import io.computenode.cyfra.dsl.struct.GStruct
7+
import izumi.reflect.Tag
8+
import izumi.reflect.macrortti.LightTypeTag
9+
10+
case class UniformRef[T <: Value: Tag: FromExpr](layoutOffset: Int, valueTag: Tag[T]) extends GUniform[T]

cyfra-core/src/main/scala/io/computenode/cyfra/core/layout/LayoutStruct.scala

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package io.computenode.cyfra.core.layout
22

3-
import io.computenode.cyfra.core.binding.BufferRef
3+
import io.computenode.cyfra.core.binding.{BufferRef, UniformRef}
44
import io.computenode.cyfra.dsl.Value
5-
import io.computenode.cyfra.dsl.binding.GBuffer
5+
import io.computenode.cyfra.dsl.Value.FromExpr
6+
import io.computenode.cyfra.dsl.binding.{GBinding, GBuffer, GUniform}
67
import izumi.reflect.Tag
78
import izumi.reflect.macrortti.LightTypeTag
89

@@ -30,37 +31,49 @@ object LayoutStruct:
3031
case ValDef(_, tpt, _) => tpt.tpe
3132
case _ => report.errorAndAbort("Unexpected field type in case class")
3233

33-
if !fieldTypes.forall(_ <:< TypeRepr.of[GBuffer[?]]) then
34-
report.errorAndAbort("LayoutStruct can only be derived for case classes with GBuffer elements")
34+
if !fieldTypes.forall(_ <:< TypeRepr.of[GBinding]) then
35+
report.errorAndAbort("LayoutStruct can only be derived for case classes with GBinding elements")
3536

36-
val valueTypes = fieldTypes.map(_.typeArgs.headOption.getOrElse(report.errorAndAbort("GBuffer must have a value type")))
37+
val valueTypes = fieldTypes.map:
38+
ftype => (ftype, ftype.typeArgs.headOption.getOrElse(report.errorAndAbort("GBuffer must have a value type")))
3739

3840
// summon izumi tags
39-
val tags = valueTypes.map: tpe =>
40-
tpe.asType match
41-
case '[t] =>
42-
(
43-
tpe.asType,
44-
Expr.summon[Tag[t]] match
45-
case Some(tagExpr) => tagExpr
46-
case None => report.errorAndAbort(s"Cannot summon Tag for type ${tpe.show}"),
47-
)
48-
49-
val buffers = tags.zipWithIndex.map:
50-
case ((tpe, tag), i) =>
41+
val typeGivens = valueTypes.map:
42+
case (ftype, farg) =>
43+
farg.asType match
44+
case '[type t <: Value; t] =>
45+
(
46+
ftype.asType,
47+
farg.asType,
48+
Expr.summon[Tag[t]] match
49+
case Some(tagExpr) => tagExpr
50+
case None => report.errorAndAbort(s"Cannot summon Tag for type ${tpe.show}"),
51+
Expr.summon[FromExpr[t]] match
52+
case Some(fromExpr) => fromExpr
53+
case None => report.errorAndAbort(s"Cannot summon FromExpr for type ${tpe.show}")
54+
)
55+
56+
val buffers = typeGivens.zipWithIndex.map:
57+
case ((ftype, tpe, tag, fromExpr), i) =>
5158
tpe match
5259
case '[type t <: Value; t] =>
53-
'{
54-
BufferRef[t](${ Expr(i) }, ${ tag.asExprOf[Tag[t]] })
55-
}
60+
ftype match
61+
case '[type tg <: GBuffer[?]; tg] =>
62+
'{
63+
BufferRef[t](${ Expr(i) }, ${ tag.asExprOf[Tag[t]] })(using summon[Tag[t]], ${ fromExpr.asExprOf[FromExpr[t]] })
64+
}
65+
case '[type tg <: GUniform[?]; tg] =>
66+
'{
67+
UniformRef[t](${ Expr(i) }, ${ tag.asExprOf[Tag[t]] })(using summon[Tag[t]], ${ fromExpr.asExprOf[FromExpr[t]] })
68+
}
5669

5770
val constructor = sym.primaryConstructor
5871

5972
val layoutInstance = Apply(Select(New(TypeIdent(sym)), constructor), buffers.map(_.asTerm))
6073

6174
val layoutRef = layoutInstance.asExprOf[T]
6275

63-
val soleTags = tags.map(_._2.asExprOf[Tag[? <: Value]]).toList
76+
val soleTags = typeGivens.map(_._3.asExprOf[Tag[? <: Value]]).toList
6477

6578
'{
6679
LayoutStruct[T]($layoutRef, ${ Expr.ofList(soleTags) })
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package io.computenode.cyfra.dsl.binding
22

33
import io.computenode.cyfra.dsl.Value
4+
import io.computenode.cyfra.dsl.Value.{FromExpr, Int32}
5+
import io.computenode.cyfra.dsl.gio.GIO
6+
import izumi.reflect.Tag
47

5-
trait GBuffer[T <: Value] extends GBinding
8+
trait GBuffer[T <: Value: FromExpr: Tag] extends GBinding:
9+
def read(index: Int32): T = FromExpr.fromExpr(ReadBuffer(this, index))
10+
11+
def write(index: Int32, value: T): GIO[Unit] = GIO.write(this, index, value)
612

713
object GBuffer
Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
package io.computenode.cyfra.dsl.binding
22

3+
import io.computenode.cyfra.dsl.Value
4+
import io.computenode.cyfra.dsl.Value.FromExpr
5+
import io.computenode.cyfra.dsl.Value.FromExpr.fromExpr
6+
import io.computenode.cyfra.dsl.gio.GIO
37
import io.computenode.cyfra.dsl.struct.GStruct
8+
import izumi.reflect.Tag
49

5-
trait GUniform[T <: GStruct[T]] extends GBinding
6-
def read: ReadUniform[T]
10+
trait GUniform[T <: Value: Tag: FromExpr] extends GBinding:
11+
def read: T = fromExpr(ReadUniform(this))
12+
13+
def write(value: T): GIO[Unit] = WriteUniform(this, value)
714

8-
object GUniform
15+
object GUniform:
16+
17+
case class ParamUniform[T <: GStruct[T]: Tag: FromExpr]() extends GUniform[T]
18+
19+
def fromParams[T <: GStruct[T]: Tag: FromExpr] = ParamUniform[T]()

0 commit comments

Comments
 (0)