Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.0] Global.deserializeTo[] method #979

Merged
merged 1 commit into from
Nov 22, 2024
Merged

[6.0] Global.deserializeTo[] method #979

merged 1 commit into from
Nov 22, 2024

Conversation

kushti
Copy link
Member

@kushti kushti commented May 13, 2024

This PR is introducing new Global.deserializeRaw method which is allowing to deserialize a typed object from underlying bytes. It is compatible (has roundtrip with) Global.serialize from #989 .

example:

{
     val src = getVar[Coll[Short]](21).get
     val ba = serialize(src)
     val restored = deserializeTo[Coll[Short]](ba)
     src == restored
}

@kushti kushti changed the base branch from develop to v6.0.0 May 13, 2024 09:24
@kushti kushti changed the title [6.0] Global.deserialize method [6.0] Global.deserializeRaw method May 13, 2024
@kushti kushti modified the milestone: v6.0 May 13, 2024
* @param votes - votes for changing system parameters
* @param _bytes - serialized bytes of the header when not `null`
*/
class ErgoHeader(override val version: ErgoHeader.Version,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the motivation for having this class. Why sigma.data.CHeader is not enough?
I think it is better to have unification of domain types if possible.


override def parse(r: SigmaByteReader): Long = {
readUint32BE(r.getBytes(4))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array allocation can be avoided.

lazy val checkPowMethod = SMethod(
this, "checkPow", SFunc(Array(SHeader), SBoolean), 16, GroupGenerator.costKind) // todo: cost
.withIRInfo(MethodCallIrBuilder)
.withInfo(Xor, "Check PoW of this header") // todo: desc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use .withInfo overload without opDesc. Note, opDesc should point to the operation this Method can be lowered to. In this case there is no such operation.

lazy val deserializeRawMethod = SMethod(
this, "deserializeRaw", SFunc(Array(SGlobal, SByteArray), tT, Array(paramT)), 3, Xor.costKind) // todo: cost
.copy(irInfo = MethodIRInfo(None, Some(desJava), None))
.withInfo(Xor, "Byte-wise XOR of two collections of bytes", // todo: desc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use different .withInfo overload.

@@ -23,6 +25,9 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S
w.putValue(mc.obj, objInfo)
assert(mc.args.nonEmpty)
w.putValues(mc.args, argsInfo, argsItemInfo)
if(mc.method.name == SGlobalMethods.deserializeRawMethod.name){
w.putType(mc.tpe, typeInfo)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better leave MethodCall unchanged and use PolyMethodCall as described in #980
This will also give both simplicity of code and efficiency of execution, because specialization will happen at compile time and most of the method calls are simple method calls.


an[SerializerException] should be thrownBy (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For negative cases there is assertExceptionThrown which allows testing not only exception type but also the message. See other usages of it as an example.

@@ -19,6 +20,25 @@ import sigma.serialization.OpCodes

import scala.collection.mutable.ArrayBuffer


case class DeserializeRawBytes[V <: SType](bytes: Value[SByteArray], tpe: V) extends NotReadyValue[V] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary to introduce new operation with opcode for each method, MethodCall is enough and can be translated to MethodCall from GraphBuilding.

@@ -536,6 +556,9 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext =>
val e = stypeToElem(optTpe.elemType)
ctx.getVar(id)(e)

case DeserializeRawBytes(bytes, tpe) =>
sigmaDslBuilder.deserializeRaw(asRep[Coll[Byte]](eval(bytes)))(stypeToElem(tpe))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary.

}
case _ =>
error(s"Cannot find Global method: $n", bound.sourceContext)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary.

Copy link
Member

@aslesarenko aslesarenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, see also 1 comment

@@ -1824,6 +1825,16 @@ case object SGlobalMethods extends MonoTypeMethods {
.withInfo(Xor, "Byte-wise XOR of two collections of bytes",
ArgInfo("left", "left operand"), ArgInfo("right", "right operand"))

private val deserializeCostKind = PerItemCost(
baseCost = JitCost(20), perChunkCost = JitCost(7), chunkSize = 128)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like two big chunkSize (or small perChunkCost) considering that deserialization is many allocations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, raised cost to
baseCost = JitCost(30), perChunkCost = JitCost(20), chunkSize = 32

@kushti kushti merged commit 47b5558 into v6.0.0 Nov 22, 2024
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants