Skip to content

Commit

Permalink
Add replay option in order to run given json
Browse files Browse the repository at this point in the history
  • Loading branch information
jaeho committed Mar 7, 2024
1 parent a1786ca commit 705fc8b
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 7 deletions.
69 changes: 66 additions & 3 deletions src/main/scala/fhetest/Checker/Utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import fhetest.LibConfig
import io.circe._
import io.circe.generic.semiauto._
import io.circe.syntax._
import io.circe.parser._

import scala.io.Source

import java.io.{File, PrintWriter}
import java.nio.file.{Files, Path, Paths, StandardCopyOption}
Expand Down Expand Up @@ -72,9 +75,49 @@ implicit val scalingTechniqueDecoder: Decoder[ScalingTechnique] =
case other => Left(s"Unknown scaling technique: $other")
}
implicit val encParamsEncoder: Encoder[EncParams] = deriveEncoder
implicit val encParamsDecoder: Decoder[EncParams] = deriveDecoder
implicit val libConfigEncoder: Encoder[LibConfig] = deriveEncoder
implicit val libConfigDecoder: Decoder[LibConfig] = Decoder.instance { cursor =>
for {
scheme <- cursor.downField("scheme").as[Scheme]
encParams <- cursor.downField("encParams").as[EncParams]
firstModSize <- cursor.downField("firstModSize").as[Int]
scalingModSize <- cursor.downField("scalingModSize").as[Int]
securityLevel <- cursor
.downField("securityLevel")
.as[SecurityLevel]
scalingTechnique <- cursor
.downField("scalingTechnique")
.as[ScalingTechnique]
lenOpt <- cursor.downField("lenOpt").as[Option[Int]]
boundOpt <- scheme match {
case Scheme.BGV | Scheme.BFV =>
cursor
.downField("boundOpt")
.as[Option[Int]]
.map(_.map(_.asInstanceOf[Int | Double]))
case Scheme.CKKS =>
cursor
.downField("boundOpt")
.as[Option[Double]]
.map(_.map(_.asInstanceOf[Int | Double]))
}
} yield LibConfig(
scheme,
encParams,
firstModSize,
scalingModSize,
securityLevel,
scalingTechnique,
lenOpt,
boundOpt,
)
}
implicit val t2ProgramEncoder: Encoder[T2Program] = deriveEncoder
implicit val t2ProgramDecoder: Decoder[T2Program] = deriveDecoder
implicit val failureEncoder: Encoder[Failure] = deriveEncoder
implicit val failureDecoder: Decoder[Failure] = deriveDecoder

implicit val resultInfoEncoder: Encoder[ResultInfo] = Encoder.forProduct7(
"programId",
"program",
Expand All @@ -94,22 +137,33 @@ implicit val resultInfoEncoder: Encoder[ResultInfo] = Encoder.forProduct7(
ri.OpenFHE,
),
)
implicit val resultInfoDecoder: Decoder[ResultInfo] = Decoder.forProduct7(
"programId",
"program",
"result",
"failures",
"expected",
"SEAL",
"OpenFHE",
)(ResultInfo.apply)

implicit val encodeIntOrDouble: Encoder[Int | Double] = Encoder.instance {
case i: Int => Json.fromInt(i)
case d: Double => Json.fromDoubleOrNull(d)
}

object DumpUtil {
// 파일에 문자열 데이터 쓰기 함수
def dumpFile(data: String, filename: String): Unit = {
val writer = new PrintWriter(filename)
try writer.write(data)
finally writer.close()
}

// dumpResult 함수 구현
def readFile(filePath: String): String =
Source.fromFile(filePath).getLines.mkString

def dumpResult(
program: T2Program, // 가정: 이미 정의되어 있음
program: T2Program,
i: Int,
res: CheckResult,
sealVersion: String,
Expand Down Expand Up @@ -155,6 +209,15 @@ object DumpUtil {
case ParserError(_) => s"$psrErrDir/$i.json"
dumpFile(resultInfo.asJson.spaces2, filename)
}

def readResult(filePath: String): ResultInfo = {
val fileContents = readFile(filePath)
val resultInfo = decode[ResultInfo](fileContents)
resultInfo match {
case Right(info) => info
case Left(error) => throw new Exception(s"Error: $error")
}
}
}

val testDir = s"$TEST_DIR-$formattedDateTime"
Expand Down
39 changes: 39 additions & 0 deletions src/main/scala/fhetest/Command.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fhetest
import fhetest.Utils.*
import fhetest.Generate.*
import fhetest.Phase.{Parse, Interp, Print, Execute, Generate, Check}
import fhetest.Checker.DumpUtil

sealed abstract class Command(
/** command name */
Expand Down Expand Up @@ -244,3 +245,41 @@ case object CmdTest extends BackendCommand("test") {
println("=" * 80)
}
}

case object CmdReplay extends BackendCommand("replay") {
val help = "Replay the given json."
val examples = List(
"fhetest replay -fromjson:logs/test/success/2.json",
"fhetest replay -fromjson:logs/test/success/2.json -b:OpenFHE",
)
def runJob(config: Config): Unit =
val jsonFileName = config.fromJson.getOrElseThrow("No json file given.")
val resultInfo = DumpUtil.readResult(jsonFileName)
val sealVersion = resultInfo.SEAL
val openfheVersion = resultInfo.OpenFHE
val t2Program = resultInfo.program
val libConfig = t2Program.libConfig
val encParams = libConfig.encParams
updateBackendVersion(Backend.SEAL, sealVersion)
updateBackendVersion(Backend.OpenFHE, openfheVersion)
config.backend match {
case Some(backend) =>
given DirName = getWorkspaceDir(backend)
val (ast, symbolTable, encType) = Parse(t2Program)
Print(
ast,
symbolTable,
encType,
backend,
None,
Some(encParams),
Some(libConfig),
)
val result = Execute(backend)
print(result)
case None =>
val (ast, _, _) = Parse(t2Program)
val result = Interp(ast, encParams.ringDim, encParams.plainMod)
print(result)
}
}
10 changes: 6 additions & 4 deletions src/main/scala/fhetest/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Config(
var sealVersion: String = SEAL_VERSIONS.head,
var openfheVersion: String = OPENFHE_VERSIONS.head,
var libConfigOpt: Option[LibConfig] = None,
var fromJson: Option[String] = None,
var filter: Boolean = true,
var silent: Boolean = false,
var debug: Boolean = false,
Expand Down Expand Up @@ -56,10 +57,11 @@ object Config {
// FIXME: temperalily added
case "libconfig" =>
config.libConfigOpt = Some(LibConfig())
case "filter" => config.filter = value.toBoolean
case "silent" => config.silent = value.toBoolean
case "debug" => config.debug = value.toBoolean
case _ => throw new Error(s"Unknown option: $key")
case "fromjson" => config.fromJson = Some(value)
case "filter" => config.filter = value.toBoolean
case "silent" => config.silent = value.toBoolean
case "debug" => config.debug = value.toBoolean
case _ => throw new Error(s"Unknown option: $key")
}
case _ => // 잘못된 형식의 인자 처리
}
Expand Down
9 changes: 9 additions & 0 deletions src/main/scala/fhetest/Phase/Parse.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@ import org.twc.terminator.t2dsl_compiler.T2DSLsyntaxtree.Goal;
import org.twc.terminator.SymbolTable;

import java.io.*;
import fhetest.Generate.T2Program

case object Parse {
def apply(file: String): (Goal, SymbolTable, ENC_TYPE) = {
val input_stream: InputStream = new FileInputStream(file);
apply(input_stream)
}

def apply(t2Program: T2Program): (Goal, SymbolTable, ENC_TYPE) = {
val input_stream: InputStream = new ByteArrayInputStream(
t2Program.content.getBytes(),
);
apply(input_stream)
}

def apply(input_stream: InputStream): (Goal, SymbolTable, ENC_TYPE) = {
// TODO: Refactor this ENC_TYPE
val t2ast = T2DSLParser(input_stream).Goal()
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/fhetest/fhetest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ object FHETest {
CmdCheck,
// Check after Generate random T2 programs.
CmdTest,
// Replay the given json
CmdReplay,
)
val cmdMap = commands.foldLeft[Map[String, Command]](Map()) {
case (map, cmd) => map + (cmd.name -> cmd)
Expand Down

0 comments on commit 705fc8b

Please sign in to comment.