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

New evaluation and costing #639

Closed
wants to merge 67 commits into from
Closed

New evaluation and costing #639

wants to merge 67 commits into from

Conversation

aslesarenko
Copy link
Member

@aslesarenko aslesarenko commented Jan 31, 2020

This new implementation of ErgoTree v2 is based on #637, #697
The code of this PR can be merged into v3.x/v4.0 branches, BUT NOT ACTIVATED.
The actual activation should be done in v5.0 release as it is described in https://github.com/ScorexFoundation/sigmastate-interpreter/blob/develop/docs/aot-jit-switch.md.
That said, this PR MUST NOT introduce consensus breaking changes in the existing (AOT based) implementation of the interpreter.

Motivation

ErgoTree is simple declarative intermediate representation for Ergo contracts.
It is designed to be compact in serialized form and directly executable, i.e. no additional transformation is necessary before it can be efficiently executed.

This PR implements big-step recursive ErgoTreeEvaluator that works directly with ErgoTree.
Because of this the evaluator is very simple and follows denotational semantics of ErgoTree.
Or, the other way around, this implementation of ErgoTreeEvaluator is purely functional with immutable data structures and can be used as definition of ErgoTree's semantics.

Implementation

ErgoTreeEvaluator takes ErgoTree directly as it is deserialized as part of a transaction.
No additional transformations is performed.
ErgoTree is interpreted directly and all intermediate data are stored in runtime types.
Runtime types are such types as Coll, SigmaProp, AvlTree, BigInt, etc.
It also use immutable Map to keep current DataEnv of computed ValDefs, as a result only the addition operation is used from the map, and the deletion is essentially done by the garbage collection.

Performance

Since this interpreter directly works with SigmaDsl types (Coll, BigInt, SigmaProp etc), it turns out to be fast.
Since it also does JIT style costing instead of AOT style, it is 5-6x faster then existing implementation.

Milestone

New evaluation of ErgoTree required changes in how isProven handled.
In particular isProven is not supported in ErgoTree that is passed to prove/verify methods.
This required changes in tests and also in the coverage report.
Unfortunately those changes may break the consensus, because isProven can be serialized and present in ErgoTree.
This prevents ErgoTreeEvaluator to be used in v3.x

@coveralls
Copy link

coveralls commented Jan 31, 2020

Pull Request Test Coverage Report for Build 5222

  • 209 of 781 (26.76%) changed or added relevant lines in 24 files are covered.
  • 2864 unchanged lines in 194 files lost coverage.
  • Overall coverage decreased (-0.8%) to 33.918%

Changes Missing Coverage Covered Lines Changed/Added Lines %
sigma-api/src/main/scala/special/sigma/SigmaDsl.scala 0 1 0.0%
sigma-impl/src/main/scala/special/sigma/SigmaDslOverArrays.scala 0 1 0.0%
sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala 0 1 0.0%
sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala 0 1 0.0%
sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala 0 1 0.0%
sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala 0 1 0.0%
sigmastate/src/main/scala/sigmastate/interpreter/ProverResult.scala 0 1 0.0%
sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala 0 1 0.0%
sigmastate/src/main/scala/sigmastate/eval/BigIntegerOps.scala 1 4 25.0%
sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala 1 5 20.0%
Files with Coverage Reduction New Missed Lines %
common/src/main/scala/scalan/ExactIntegral.scala 1 20.0%
common/src/main/scala/scalan/ExactNumeric.scala 1 53.85%
common/src/main/scala/scalan/OverloadHack.scala 1 28.57%
core/src/main/scala/scalan/Modules.scala 1 33.33%
core/src/main/scala/scalan/staged/ProgramGraphs.scala 1 11.11%
library-api/src/main/scala/special/collection/package.scala 1 20.0%
library-api/src/main/scala/special/SpecialPredef.scala 1 14.29%
library/src/main/scala/wrappers/special/impl/WSpecialPredefsImpl.scala 1 24.32%
sigma-api/src/main/scala/special/sigma/SigmaDsl.scala 1 16.22%
sigma-impl/src/main/scala/special/sigma/Extensions.scala 1 33.33%
Totals Coverage Status
Change from base Build 5219: -0.8%
Covered Lines: 5836
Relevant Lines: 17206

💛 - Coveralls

@aslesarenko aslesarenko self-assigned this Jun 9, 2020
val argsV = args.map(a => a.evalTo[Any](E, env))
f(argsV)
}
// TODO JITC
Copy link
Member Author

@aslesarenko aslesarenko Jun 17, 2020

Choose a reason for hiding this comment

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

TO REVIEWER: I added a separate issue #662 to implement all TODO JITC in a separate PR

import sigmastate.lang.SigmaParser
import sigmastate.lang.Terms.OperationId

case class JitCostTable(operCosts: Map[OperationId, Int]) extends (OperationId => Int) {
Copy link
Member Author

Choose a reason for hiding this comment

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

To reviewer:
This is version is mostly the same as the old CostTable, but the plan is to make completely new Cost Model which better reflect JIT costs.
The main invariant which will be guaranteed is that always JIT cost < AOT cost for all non spam scripts.
This shouldn't be hard to do since existing op costs are very conservative and new costs may be reduced proportional to new JIT interpreter speedup. (e.g. 2-3x)

import sigmastate.utxo.CostTable._
import special.sigma.{SigmaTestingData, AvlTree}

class JitCostingSpecification extends SigmaTestingData {
Copy link
Member Author

Choose a reason for hiding this comment

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

To reviewer:
This spec will be further updated (in separate PR as part of implementing #665)
The old CostingSpecification remains unchanged since the AOT version should remain unchanged.

@@ -3,9 +3,12 @@ package org.ergoplatform
import sigmastate.SCollection.SByteArray
import sigmastate.Values._
import sigmastate.eval.IRContext
import sigmastate.interpreter.Interpreter
import sigmastate.interpreter.{Interpreter, ErgoTreeEvaluator}
import sigmastate.interpreter.Interpreter.{ScriptEnv, ReductionResult}
Copy link
Member

Choose a reason for hiding this comment

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

unused imports added

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

import sigmastate.utxo._

import scala.util.Try
Copy link
Member

Choose a reason for hiding this comment

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

unused import added

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

trait BigIntIsIntegral extends Integral[BigInt] {
def quot(x: BigInt, y: BigInt): BigInt = x.divide(y)
def rem(x: BigInt, y: BigInt): BigInt = x.remainder(y)
def rem(x: BigInt, y: BigInt): BigInt = x.mod(y)
Copy link
Member

Choose a reason for hiding this comment

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

Looks like consensus-breaking change (however, mod is more proper operation, so should be added to 4.0).

Copy link
Member Author

Choose a reason for hiding this comment

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

added comment

exp.evalTo[Any](this, env)
}

def addCostOf(opName: String, opType: SFunc) = {
Copy link
Member

Choose a reason for hiding this comment

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

please do ScalaDoc for all the public methods

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@@ -97,10 +118,21 @@ trait Interpreter extends ScorexLogging {
(res, currContext.value)
}

// TODO after HF: merge with old version (`applyDeserializeContext`)
def applyDeserializeContextJITC(context: CTX, exp: Value[SType]): (SigmaPropValue, CTX) = {
Copy link
Member

Choose a reason for hiding this comment

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

ScalaDoc

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@@ -83,6 +97,13 @@ trait Interpreter extends ScorexLogging {
case x => throw new Error(s"Context-dependent pre-processing should produce tree of type Boolean or SigmaProp but was $x")
}

// TODO after HF: merge with old version (`toValidScriptType`)
def toValidScriptTypeJITC(exp: SValue): SigmaPropValue = exp match {
Copy link
Member

Choose a reason for hiding this comment

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

ScalaDoc

Copy link
Member Author

Choose a reason for hiding this comment

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

this is helper, made it private.

import sigmastate.lang.SigmaParser
import sigmastate.lang.Terms.OperationId

case class JitCostTable(operCosts: Map[OperationId, Int]) extends (OperationId => Int) {
Copy link
Member

Choose a reason for hiding this comment

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

ScalaDoc

Copy link
Member Author

Choose a reason for hiding this comment

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

class removed


import sigmastate.utxo.JitCostTable

def costOf(opName: String, opType: SFunc): Int = {
Copy link
Member

Choose a reason for hiding this comment

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

Please do ScalaDoc for all the public methods

Copy link
Member Author

Choose a reason for hiding this comment

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

methods removed

@aslesarenko aslesarenko modified the milestones: v3.x, v5.0, v4.0 Sep 10, 2020
@aslesarenko aslesarenko added the 40h Approximately 40 hours or work (1 week) label Sep 16, 2020
@aslesarenko aslesarenko removed the S-ready-for-merge Status: This PR is ready for merge label Nov 5, 2020
# Conflicts:
#	build.sbt
#	sigma-api/src/main/scala/special/sigma/SigmaDsl.scala
#	sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala
#	sigmastate/src/main/scala/sigmastate/Values.scala
#	sigmastate/src/main/scala/sigmastate/eval/BigIntegerOps.scala
#	sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala
#	sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala
#	sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala
#	sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala
#	sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala
#	sigmastate/src/main/scala/sigmastate/lang/Terms.scala
#	sigmastate/src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala
#	sigmastate/src/main/scala/sigmastate/trees.scala
#	sigmastate/src/main/scala/sigmastate/types.scala
#	sigmastate/src/main/scala/sigmastate/utxo/transformers.scala
#	sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala
#	sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala
#	sigmastate/src/test/scala/special/sigma/SigmaDslTest.scala
@aslesarenko aslesarenko changed the base branch from develop to i664-todo-coverage November 5, 2020 12:01
@aslesarenko
Copy link
Member Author

The work continues in #699, as the approach to costing will be slightly different.
All comments are addressed there.

@aslesarenko aslesarenko deleted the new-eval branch March 12, 2022 09:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
40h Approximately 40 hours or work (1 week)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants