Skip to content

Commit

Permalink
Merge pull request #214 from zkFold/eitan-structured-i/o
Browse files Browse the repository at this point in the history
Structured i/o
  • Loading branch information
vlasin authored Aug 28, 2024
2 parents e34614b + 85258e5 commit 96d4f0e
Show file tree
Hide file tree
Showing 33 changed files with 598 additions and 525 deletions.
41 changes: 22 additions & 19 deletions bench/BenchCompiler.hs
Original file line number Diff line number Diff line change
@@ -1,39 +1,42 @@
{-# LANGUAGE TypeOperators #-}
module Main where

import Control.DeepSeq (NFData, force)
import Control.Monad (return)
import Data.ByteString.Lazy (ByteString)
import Data.Function (($))
import Data.Map (Map, fromAscList)
import Data.Semigroup ((<>))
import Data.String (String, fromString)
import Numeric.Natural (Natural)
import System.IO (IO)
import Control.DeepSeq (NFData, force)
import Control.Monad (return)
import Data.ByteString.Lazy (ByteString)
import Data.Function (const, ($))
import Data.Functor.Rep (Representable (..))
import Data.Semigroup ((<>))
import Data.String (String, fromString)
import Data.Type.Equality (type (~))
import GHC.TypeNats (KnownNat)
import System.IO (IO)
import Test.Tasty.Bench
import Test.Tasty.Golden (goldenVsString)
import Text.Show (show)
import Test.Tasty.Golden (goldenVsString)
import Text.Show (show)

import ZkFold.Base.Algebra.Basic.Class (AdditiveMonoid, zero)
import ZkFold.Base.Algebra.Basic.Class (AdditiveMonoid, zero)
import ZkFold.Base.Data.Vector (Vector)
import ZkFold.Symbolic.Compiler
import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal (Var)
import ZkFold.Symbolic.Examples

inputMap :: AdditiveMonoid a => ArithmeticCircuit a o -> Map Natural a
inputMap circuit = fromAscList [ (i, zero) | i <- acInput circuit ]

metrics :: String -> ArithmeticCircuit a o -> ByteString
metrics :: String -> ArithmeticCircuit a i o -> ByteString
metrics name circuit =
fromString name
<> "\nNumber of constraints: " <> fromString (show $ acSizeN circuit)
<> "\nNumber of variables: " <> fromString (show $ acSizeM circuit)
<> "\nNumber of range lookups: " <> fromString (show $ acSizeR circuit)


benchmark ::
(NFData a, AdditiveMonoid a, NFData (o Natural)) =>
String -> (() -> ArithmeticCircuit a o) -> Benchmark
(NFData a, AdditiveMonoid a, NFData (o (Var i)), NFData (Rep i), i ~ Vector n_i, KnownNat n_i) =>
String -> (() -> ArithmeticCircuit a i o) -> Benchmark
benchmark name circuit = bgroup name
[ bench "compilation" $ nf circuit ()
, env (return $ force $ circuit ()) $ \c ->
let input = inputMap c
let
input = tabulate (const zero)
path = "stats/" <> name
in bgroup "on compilation"
[ bench "evaluation" $ nf (witnessGenerator c) input
Expand Down
28 changes: 16 additions & 12 deletions examples/ZkFold/Symbolic/Examples.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

module ZkFold.Symbolic.Examples (ExampleOutput (..), examples) where

import Control.DeepSeq (NFData)
import Data.Function (const, ($), (.))
import Data.Proxy (Proxy)
import Data.String (String)
Expand All @@ -19,7 +18,7 @@ import Examples.ReverseList (exampleReverseList
import Examples.UInt

import ZkFold.Base.Algebra.Basic.Field (Zp)
import ZkFold.Base.Algebra.Basic.Number (KnownNat, Natural)
import ZkFold.Base.Algebra.Basic.Number (KnownNat)
import ZkFold.Base.Algebra.EllipticCurve.BLS12_381 (BLS12_381_Scalar)
import ZkFold.Base.Data.Vector (Vector)
import ZkFold.Symbolic.Compiler (ArithmeticCircuit, compile)
Expand All @@ -30,19 +29,24 @@ import ZkFold.Symbolic.Data.Combinators (RegisterSize (Auto
type C = ArithmeticCircuit (Zp BLS12_381_Scalar)

data ExampleOutput where
ExampleOutput :: forall o. NFData (o Natural) => (() -> C o) -> ExampleOutput
ExampleOutput
:: forall i_n o_n. KnownNat i_n
=> (() -> C (Vector i_n) (Vector o_n))
-> ExampleOutput

exampleOutput ::
forall n f.
( SymbolicData f
, Context f ~ C
, TypeSize f ~ n
forall i_n o_n c f.
( KnownNat i_n
, i_n ~ TypeSize (Support f)
, SymbolicData f
, c ~ C (Vector i_n)
, Context f ~ c
, TypeSize f ~ o_n
, SymbolicData (Support f)
, Context (Support f) ~ C
, Support (Support f) ~ Proxy C
, KnownNat (TypeSize (Support f))
, Context (Support f) ~ c
, Support (Support f) ~ Proxy c
) => f -> ExampleOutput
exampleOutput = ExampleOutput @(Vector n) . const . compile
exampleOutput = ExampleOutput @i_n @o_n . const . compile

examples :: [(String, ExampleOutput)]
examples =
Expand All @@ -57,7 +61,7 @@ examples =
, ("UInt.StrictAdd.256.Auto", exampleOutput $ exampleUIntStrictAdd @256 @Auto)
, ("UInt.StrictMul.512.Auto", exampleOutput $ exampleUIntStrictMul @512 @Auto)
, ("UInt.DivMod.32.Auto", exampleOutput $ exampleUIntDivMod @32 @Auto)
, ("Reverse.32.3000", exampleOutput $ exampleReverseList @32 @(ByteString 3000 C))
, ("Reverse.32.3000", exampleOutput $ exampleReverseList @32 @(ByteString 3000 (C (Vector _))))
, ("Fibonacci.100", exampleOutput $ exampleFibonacci 100)
, ("MiMCHash", exampleOutput exampleMiMC)
, ("SHA256.32", exampleOutput $ exampleSHA @32)
Expand Down
4 changes: 4 additions & 0 deletions src/ZkFold/Base/Algebra/Basic/Class.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module ZkFold.Base.Algebra.Basic.Class where
import Data.Bool (bool)
import Data.Foldable (foldl')
import Data.Kind (Type)
import Data.Void (Void, absurd)
import GHC.Natural (naturalFromInteger)
import Prelude hiding (Num (..), div, divMod, length, mod, negate, product,
replicate, sum, (/), (^))
Expand Down Expand Up @@ -43,6 +44,9 @@ class ToConstant a b where
instance ToConstant a a where
toConstant = id

instance ToConstant Void b where
toConstant = absurd

--------------------------------------------------------------------------------

{- | A class of types with a binary associative operation with a multiplicative
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ evalPolynomial
-> b
evalPolynomial e f (P p) = foldr (\(c, m) x -> x + scale c (e f m)) zero p

variables :: forall c .
MultiplicativeMonoid c =>
Poly c Natural Natural -> Set Natural
variables :: forall c v .
(Ord v, MultiplicativeMonoid c) =>
Poly c v Natural -> Set v
variables = runSources . evalPolynomial evalMonomial (Sources @c . singleton)

mapVarPolynomial :: Variable i => Map i i-> Poly c i j -> Poly c i j
Expand Down
12 changes: 12 additions & 0 deletions src/ZkFold/Base/Data/Vector.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import qualified Control.Monad as M
import Control.Parallel.Strategies (parMap, rpar)
import Data.Aeson (ToJSON (..))
import Data.Bifunctor (first)
import Data.Distributive (Distributive (..))
import Data.Functor.Rep (Representable (..), collectRep, distributeRep)
import qualified Data.List as List
import Data.List.Split (chunksOf)
import Data.These (These (..))
Expand All @@ -21,6 +23,7 @@ import System.Random (Random (..))
import Test.QuickCheck (Arbitrary (..))

import ZkFold.Base.Algebra.Basic.Class
import ZkFold.Base.Algebra.Basic.Field
import ZkFold.Base.Algebra.Basic.Number
import ZkFold.Base.Data.ByteString (Binary (..))
import qualified ZkFold.Prelude as ZP
Expand All @@ -29,6 +32,15 @@ import ZkFold.Prelude (length, replicate)
newtype Vector (size :: Natural) a = Vector [a]
deriving (Show, Eq, Functor, Foldable, Traversable, Generic, NFData)

instance KnownNat size => Representable (Vector size) where
type Rep (Vector size) = Zp size
index (Vector v) ix = v Prelude.!! (fromIntegral (fromZp ix))
tabulate f = Vector [f (toZp ix) | ix <- [0 .. fromIntegral (value @size) Prelude.- 1]]

instance KnownNat size => Distributive (Vector size) where
distribute = distributeRep
collect = collectRep

parFmap :: (a -> b) -> Vector size a -> Vector size b
parFmap f (Vector lst) = Vector $ parMap rpar f lst

Expand Down
Loading

0 comments on commit 96d4f0e

Please sign in to comment.