Skip to content

Commit

Permalink
Separate LibconfigGenerator into valid/random
Browse files Browse the repository at this point in the history
  • Loading branch information
jaeho committed Mar 12, 2024
1 parent 15d194d commit e53ba27
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 72 deletions.
48 changes: 27 additions & 21 deletions src/main/scala/fhetest/Generate/AbsProgramGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,45 @@ enum Strategy:
case Exhaustive, Random

extension (s: Strategy)
def getGenerator: AbsProgramGenerator = s match {
case Strategy.Exhaustive => ExhaustiveGenerator
case Strategy.Random => RandomGenerator
def getGenerator(
encType: ENC_TYPE,
validCheck: Boolean,
): AbsProgramGenerator = s match {
case Strategy.Exhaustive =>
ExhaustiveGenerator(encType: ENC_TYPE, validCheck: Boolean)
case Strategy.Random =>
RandomGenerator(encType: ENC_TYPE, validCheck: Boolean)
}

// AbsProgram Generator
trait AbsProgramGenerator {
def generateAbsPrograms(
encType: ENC_TYPE,
validCheck: Boolean,
): LazyList[AbsProgram]
trait AbsProgramGenerator(encType: ENC_TYPE, validCheck: Boolean) {
def generateAbsPrograms(): LazyList[AbsProgram]
val lcGen =
if validCheck then ValidLibConfigGenerator(encType)
else RandomLibConfigGenerator(encType)
}

object ExhaustiveGenerator extends AbsProgramGenerator {
def generateAbsPrograms(
encType: ENC_TYPE,
validCheck: Boolean,
): LazyList[AbsProgram] = {
case class ExhaustiveGenerator(encType: ENC_TYPE, validCheck: Boolean)
extends AbsProgramGenerator(encType: ENC_TYPE, validCheck: Boolean) {
def generateAbsPrograms(): LazyList[AbsProgram] = {
def allAbsProgramsOfSize(n: Int): LazyList[AbsProgram] = {
n match {
case 1 =>
allAbsStmts
.map(stmt => List(stmt))
.map(AbsProgram(_, generateLibConfig(encType, validCheck)))
.map(
AbsProgram(
_,
lcGen.generateLibConfig(),
),
)
case _ =>
for {
stmt <- allAbsStmts
program <- allAbsProgramsOfSize(n - 1)
} yield AbsProgram(
stmt :: program.absStmts,
generateLibConfig(encType, validCheck),
lcGen.generateLibConfig(),
)
}
}
Expand All @@ -48,14 +56,12 @@ object ExhaustiveGenerator extends AbsProgramGenerator {

}

object RandomGenerator extends AbsProgramGenerator {
def generateAbsPrograms(
encType: ENC_TYPE,
validCheck: Boolean,
): LazyList[AbsProgram] = {
case class RandomGenerator(encType: ENC_TYPE, validCheck: Boolean)
extends AbsProgramGenerator(encType: ENC_TYPE, validCheck: Boolean) {
def generateAbsPrograms(): LazyList[AbsProgram] = {
def randomAbsProgramOfSize(n: Int): AbsProgram = {
val absStmts = (1 to n).map(_ => Random.shuffle(allAbsStmts).head).toList
AbsProgram(absStmts, generateLibConfig(encType, validCheck))
AbsProgram(absStmts, lcGen.generateLibConfig())
}
// Generate Lengths from 1 to inf
// LazyList.from(1)
Expand Down
135 changes: 86 additions & 49 deletions src/main/scala/fhetest/Generate/LibConfigGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,37 @@ import fhetest.LibConfig
import fhetest.Utils.*
import scala.util.Random

def generateLibConfig(encType: ENC_TYPE, valid: Boolean): LibConfig = {
lazy val randomScheme =
if encType == ENC_TYPE.ENC_INT then Scheme.values(Random.nextInt(2))
else Scheme.CKKS
trait LibConfigGenerator(encType: ENC_TYPE) {
def generateLibConfig(): LibConfig
}

lazy val randomEncParams = {
// TODO: Currently only MultDepth is random
val randomRingDim = 32768
val randomMultDepth =
if valid then Random.nextInt(10 + 1)
else Random.between(-10, 10 + 1)
val randomPlainMod = 65537
EncParams(randomRingDim, randomMultDepth, randomPlainMod)
}
// modSizeIsUpto60bits
lazy val randomFirstModSize: Int =
if valid then
case class ValidLibConfigGenerator(encType: ENC_TYPE)
extends LibConfigGenerator(encType) {
def generateLibConfig(): LibConfig = {
val randomScheme =
if encType == ENC_TYPE.ENC_INT then Scheme.values(Random.nextInt(2))
else Scheme.CKKS
val randomEncParams = {
// TODO: Currently only MultDepth is random
val randomRingDim = 32768
val randomMultDepth =
Random.nextInt(10 + 1)
val randomPlainMod = 65537
EncParams(randomRingDim, randomMultDepth, randomPlainMod)
}
// modSizeIsUpto60bits
val randomFirstModSize: Int =
if randomScheme == Scheme.BFV then Random.between(30, 60 + 1)
else Random.nextInt(60 + 1)
else Random.between(-100, 100 + 1)
// firstModSizeIsLargest
// openFHEBFVModuli
lazy val randomScalingModSize: Int =
if valid then
// firstModSizeIsLargest
// openFHEBFVModuli
val randomScalingModSize: Int =
if randomScheme == Scheme.BFV then
Random.between(30, randomFirstModSize + 1)
else Random.nextInt(randomFirstModSize + 1)
else Random.between(-100, 100 + 1)
lazy val randomSecurityLevel =
SecurityLevel.values(Random.nextInt(SecurityLevel.values.length))
lazy val randomScalingTechnique =
if valid then
val randomSecurityLevel =
SecurityLevel.values(Random.nextInt(SecurityLevel.values.length))
val randomScalingTechnique =
// Currently, exclude FLEXIBLEAUTOEXT in valid testing because of the following issue
// https://openfhe.discourse.group/t/unexpected-behavior-with-setscalingmodsize-and-flexibleautoext-in-bgv-scheme/1111
// And, exclude NORESCALE in CKKS scheme because it is not supported
Expand All @@ -58,43 +57,81 @@ def generateLibConfig(encType: ENC_TYPE, valid: Boolean): LibConfig = {
scalingTechs(
Random.nextInt(scalingTechs.length),
)
else ScalingTechnique.values(Random.nextInt(ScalingTechnique.values.length))
// len must be larger than 0
// lenIsLessThanRingDim
lazy val randomLenOpt: Option[Int] =
if valid then
// len must be larger than 0
// lenIsLessThanRingDim
val randomLenOpt: Option[Int] =
val upper = randomScheme match {
case Scheme.CKKS => (randomEncParams.ringDim / 2)
case _ => randomEncParams.ringDim
}
Some(Random.between(1, upper + 1))
else Some(Random.between(1, 100000 + 1))
lazy val randomBoundOpt: Option[Int | Double] =
if valid then
val randomBoundOpt: Option[Int | Double] =
randomScheme match {
case Scheme.BFV | Scheme.BGV =>
Some(Random.between(1, randomEncParams.plainMod + 1))
case Scheme.CKKS =>
Some(Random.between(1, math.pow(2, randomFirstModSize) + 1))
}
else
val randomRotateBoundOpt: Option[Int] =
Some(Random.between(0, 20 + 1))
LibConfig(
randomScheme,
randomEncParams,
randomFirstModSize,
randomScalingModSize,
randomSecurityLevel,
randomScalingTechnique,
randomLenOpt,
randomBoundOpt,
randomRotateBoundOpt,
)
}
}

case class RandomLibConfigGenerator(encType: ENC_TYPE)
extends LibConfigGenerator(encType) {
def generateLibConfig(): LibConfig = {
val randomScheme =
if encType == ENC_TYPE.ENC_INT then Scheme.values(Random.nextInt(2))
else Scheme.CKKS

val randomEncParams = {
// TODO: Currently only MultDepth is random
val randomRingDim = 32768
val randomMultDepth =
Random.between(-10, 10 + 1)
val randomPlainMod = 65537
EncParams(randomRingDim, randomMultDepth, randomPlainMod)
}
val randomFirstModSize: Int =
Random.between(-100, 100 + 1)
val randomScalingModSize: Int =
Random.between(-100, 100 + 1)
val randomSecurityLevel =
SecurityLevel.values(Random.nextInt(SecurityLevel.values.length))
val randomScalingTechnique =
ScalingTechnique.values(Random.nextInt(ScalingTechnique.values.length))
// len must be larger than 0
val randomLenOpt: Option[Int] =
Some(Random.between(1, 100000 + 1))
val randomBoundOpt: Option[Int | Double] =
randomScheme match {
case Scheme.BFV | Scheme.BGV =>
Some(Random.between(1, 1000 + 1))
case Scheme.CKKS => Some(Random.between(1, math.pow(2, 64) + 1))
}
lazy val randomRotateBoundOpt: Option[Int] =
if valid then Some(Random.between(0, 20 + 1))
else Some(Random.between(0, 40 + 1))
LibConfig(
randomScheme,
randomEncParams,
randomFirstModSize,
randomScalingModSize,
randomSecurityLevel,
randomScalingTechnique,
randomLenOpt,
randomBoundOpt,
randomRotateBoundOpt,
)
val randomRotateBoundOpt: Option[Int] =
Some(Random.between(0, 40 + 1))
LibConfig(
randomScheme,
randomEncParams,
randomFirstModSize,
randomScalingModSize,
randomSecurityLevel,
randomScalingTechnique,
randomLenOpt,
randomBoundOpt,
randomRotateBoundOpt,
)
}
}
4 changes: 2 additions & 2 deletions src/main/scala/fhetest/Phase/Generate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ case class Generate(

val symbolTable = boilerplate()._2

val absProgGen = strategy.getGenerator
val absProgGen = strategy.getGenerator(encType, checkValid)

val allAbsPrograms = absProgGen.generateAbsPrograms(encType, checkValid)
val allAbsPrograms = absProgGen.generateAbsPrograms()

def apply(nOpt: Option[Int]): LazyList[T2Program] = {
println(s"Genrating Strategy: $strategy")
Expand Down

0 comments on commit e53ba27

Please sign in to comment.