Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions pkg/cmd/corset/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ func getSchemaStack[F field.Element[F]](cmd *cobra.Command, mode uint, filenames
//
parallel = !GetFlag(cmd, "sequential")
batchSize = GetUint(cmd, "batch")
defensive = GetFlag(cmd, "defensive")
expand = !GetFlag(cmd, "raw")
validate = GetFlag(cmd, "validate")
)
Expand Down Expand Up @@ -160,7 +159,6 @@ func getSchemaStack[F field.Element[F]](cmd *cobra.Command, mode uint, filenames
// Construct trace builder
builder := ir.NewTraceBuilder[F]().
WithValidation(validate).
WithDefensivePadding(defensive).
WithExpansion(expand).
WithParallelism(parallel).
WithBatchSize(batchSize)
Expand Down Expand Up @@ -218,7 +216,6 @@ func init() {
// Trace expansion
rootCmd.PersistentFlags().Bool("raw", false, "assume input trace already expanded")
rootCmd.PersistentFlags().Bool("sequential", false, "perform sequential trace expansion")
rootCmd.PersistentFlags().Bool("defensive", true, "defensively pad modules")
rootCmd.PersistentFlags().Bool("validate", true, "apply trace validation")
rootCmd.PersistentFlags().UintP("batch", "b", 1024, "specify batch size for constraint checking")
}
40 changes: 31 additions & 9 deletions pkg/cmd/corset/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func runTraceCmd[F field.Element[F]](cmd *cobra.Command, args []string) {
} else if builder.Expanding() {
var tp_errors []error
// Expand all the traces
traces, tp_errors = expandLtTraces(traces, stack, builder)
traces, tp_errors = expandTraces(traces, stack, builder)
// Print trace info
for _, tf := range traces {
printTraceInfo(cfg, tf)
Expand Down Expand Up @@ -213,7 +213,7 @@ func constructTraceFilter[F field.Element[F]](cfg TraceConfig, trace tr.Trace[F]
})
}

func expandLtTraces[F field.Element[F]](traceFiles []tr.Trace[F], stack cmd_util.SchemaStack[F],
func expandTraces[F field.Element[F]](traceFiles []tr.Trace[F], stack cmd_util.SchemaStack[F],
bldr ir.TraceBuilder[F]) ([]tr.Trace[F], []error) {
//
var (
Expand Down Expand Up @@ -283,26 +283,48 @@ func printTraceInfo[F field.Element[F]](cfg TraceConfig, trace tr.Trace[F]) {
}
// Print full trace (if requested)
if cfg.trace {
printTrace(cfg, window)
printTrace(window)
}
}

func printTrace(cfg TraceConfig, window view.TraceView) {
// PrintTrace prints out a given trace in tabular form, with one table per
// module. This is the non-interactive counterpart of InspectTrace, and
// produces the same output as "go-corset trace --print". Every module holding
// data is printed, since (unlike the inspector) there is no way to reveal one
// which was hidden.
func PrintTrace[F field.Element[F]](mapping module.LimbsMap, trace tr.Trace[F],
limbs bool, cellWidth, titleWidth uint) {
// Build the viewing window (no source map, so show computed registers).
builder := view.NewBuilder[F](mapping).
WithCellWidth(cellWidth).
WithTitleWidth(titleWidth).
WithLimbs(limbs).
WithComputed(true)
//
printTrace(builder.Build(trace))
}

func printTrace(window view.TraceView) {
// Print all windows
for i := range window.Width() {
var (
ith = window.Module(i)
_, height = ith.Dimensions()
ith = window.Module(i)
width, height = ith.Dimensions()
// Construct & configure printer
tp = widget.NewTable(ith)
//
name = ith.Data().Name()
)
// Print out module name
if height <= 1 {
// Don't bother print empty modules
// NOTE: dimensions include the row / column titles, hence the
// comparisons against one rather than zero.
if height <= 1 || width <= 1 {
// Don't bother printing modules with no columns, or no rows. The
// latter includes static reference tables (e.g. a "$range_uN"
// lookup table), whose contents are fixed by the schema and hence
// carry no trace data at all.
continue
} else if window.Width() > 1 && name != "" {
// Print out module name
fmt.Printf("%s:\n", name)
}
// Print out report
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/corset/util/schema_stacker.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func (p SchemaStacker[F]) Build() SchemaStack[F] {
stack.concreteSchemas = append(stack.concreteSchemas, schema.Any(airSchema))
stack.names = append(stack.names, "AIR")
}
// Assign trace builder with limb map
stack.traceBuilder = p.traceBuilder.WithRegisterMapping(mapping)
// Assign source map used to build the stack
stack.sourceMap = p.sourceMap
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/cmd/zkc/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ func runTraceCmd[F field.Element[F]](cmd *cobra.Command, args []string, field fi
check = GetFlag(cmd, "check")
// show trace statistics
stats = GetFlag(cmd, "stats")
// print entire trace
showTrace = GetFlag(cmd, "print")
// open trace in the interactive inspector
inspect = GetFlag(cmd, "inspect")
// extract sharding config
Expand Down Expand Up @@ -112,6 +114,12 @@ func runTraceCmd[F field.Element[F]](cmd *cobra.Command, args []string, field fi
printTraceStats(trace)
printModuleStats(trace)
}
// print entire trace (if requested). Unlike the inspector, there is no way
// to reveal a module which was hidden, so everything carrying data is shown
// (this excludes, for example, the static range-check tables).
if showTrace && trace != nil {
corset.PrintTrace(binfile.LimbsMap(), trace, false, 32, 128)
}
// write out trace (if requested)
if outputFile != "" {
// Write out trace file
Expand Down Expand Up @@ -153,6 +161,7 @@ func init() {
traceCmd.Flags().String("sharding", "", "specify sharding strategy")
traceCmd.Flags().BoolP("check", "c", false, "check generated trace against constraints")
traceCmd.Flags().Bool("stats", false, "show overall stats for the generated trace")
traceCmd.Flags().BoolP("print", "p", false, "print the generated trace")
traceCmd.Flags().Bool("sequential", false, "force sequential tracing")
traceCmd.Flags().BoolP("inspect", "i", false, "open the generated trace in the interactive inspector")
traceCmd.PersistentFlags().UintP("batch", "b", 1024, "specify batch size for constraint checking")
Expand Down
2 changes: 1 addition & 1 deletion pkg/corset/compiler/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (t *translator) translateModules(circuit *ast.Circuit) {
// Translate the given Corset module into its corresponding HIR module.
func (t *translator) translateModule(name string) {
// Always include module (even if empty).
t.schema.NewModule(name, true, true, false, false, false, false)
t.schema.NewModule(name, true, false, false, false, false)
// Process each register in turn.
for _, regIndex := range t.env.RegistersOf(name) {
var (
Expand Down
2 changes: 1 addition & 1 deletion pkg/ir/air/gadgets/bitwidth.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func (p *BitwidthGadget[F]) applyRecursiveBitwidthGadget(ref register.Ref, bitwi
func (p *BitwidthGadget[F]) constructTypeProof(handle module.Name, bitwidth uint) sc.ModuleId {
var (
// Create new module for this type proof
mid = p.schema.NewModule(handle, false, false, false, true, false, false)
mid = p.schema.NewModule(handle, false, false, true, false, false)
module = p.schema.Module(mid)
// Determine limb widths.
loWidth, hiWidth = determineLimbSplit(bitwidth)
Expand Down
23 changes: 13 additions & 10 deletions pkg/ir/builder/alignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,21 @@ func alignModule[F field.Element[F]](config Config, scMod sc.Module[F], trMod tr
regmap = make(map[string]uint)
seen = make([]bool, trMod.Width())
)
// Initialise column map
// Initialise column map and descriptors. NOTE: every register of the schema
// gets a descriptor, regardless of whether the corresponding column is
// actually present in the trace. This matters for those which are not
// (e.g. a computed column, or a column of a static reference table), since
// they are otherwise left nameless.
for i := range width {
var rid = register.NewId(i)
var r = scMod.Register(register.NewId(i))
//
regmap[scMod.Register(rid).Name()] = i
regmap[r.Name()] = i
//
if r.IsNative() {
descriptors[i] = trace.NewColumnDescriptor(r.Name(), util.None[uint]())
} else {
descriptors[i] = trace.NewColumnDescriptor(r.Name(), util.Some(r.Width()))
}
}
// Align columns one-by-one
for i := range trMod.Width() {
Expand All @@ -148,13 +158,6 @@ func alignModule[F field.Element[F]](config Config, scMod sc.Module[F], trMod tr
} else if ok := seen[cid]; ok {
errs = append(errs, fmt.Errorf("duplicate column '%s' in module '%s' of trace", ith.Name, trMod.Name()))
} else {
var r = scMod.Register(register.NewId(cid))
//
if r.IsNative() {
descriptors[cid] = trace.NewColumnDescriptor(r.Name(), util.None[uint]())
} else {
descriptors[cid] = trace.NewColumnDescriptor(r.Name(), util.Some(r.Width()))
}
// Clone underlying data
columns[cid] = trMod.MutColumn(i)
// Mark column as seen
Expand Down
53 changes: 43 additions & 10 deletions pkg/ir/builder/padding.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ package builder
import (
sc "github.com/LFDT-Lineth/zkc/pkg/schema"
"github.com/LFDT-Lineth/zkc/pkg/trace"
"github.com/LFDT-Lineth/zkc/pkg/util"
"github.com/LFDT-Lineth/zkc/pkg/util/collection/array"
"github.com/LFDT-Lineth/zkc/pkg/util/field"
)
Expand All @@ -34,9 +33,11 @@ import (
func padModules[F field.Element[F]](config Config, schema sc.AnySchema[F], mods []ArrayModule[F],
) ([]ArrayModule[F], []error) {
var (
// Determine the set of minimal trace sizes
minimums = determineMinimumTraceHeight(schema)
columns, errs = flattenTrace(schema, trace.NewArray(mods))
data []array.MutArray[F]
mapfn = paddingMapFn(config, schema, mods)
mapfn = paddingMapFn(config, schema, mods, minimums)
)
//
if config.Parallel {
Expand All @@ -54,11 +55,12 @@ func padModules[F field.Element[F]](config Config, schema sc.AnySchema[F], mods
// assigned (e.g. an unfilled computed column, prior to expansion), are passed
// through unchanged.
func paddingMapFn[F field.Element[F]](config Config, schema sc.AnySchema[F], mods []ArrayModule[F],
) func(uint, util.Pair[uint, uint]) array.MutArray[F] {
return func(_ uint, p util.Pair[uint, uint]) array.MutArray[F] {
minimums []uint) func(uint, trace.ColumnRef) array.MutArray[F] {
//
return func(_ uint, p trace.ColumnRef) array.MutArray[F] {
var (
mid = p.Left
col = mods[mid].MutColumn(p.Right)
mid = p.Module()
col = mods[mid].MutColumn(p.Column().Unwrap())
scMod = schema.Module(mid)
)
//
Expand All @@ -69,7 +71,8 @@ func paddingMapFn[F field.Element[F]](config Config, schema sc.AnySchema[F], mod
var (
zero F
height = mods[mid].Height()
target = config.Padding(height, 1)
// calculate taget height, whilst ensuring minimum enforced.
target = config.Padding(max(minimums[mid], height), 1)
front uint
)
// Only pad when the module falls short of its target.
Expand All @@ -81,25 +84,55 @@ func paddingMapFn[F field.Element[F]](config Config, schema sc.AnySchema[F], mod
}
}

// Determine the minimum trace height for each module in the given schema. The
// minimum height is determined by the "shift schedule". Specifically, if the
// maximum negative shift is N and the maximum positive shift is M, then we must
// have N+M+1 minimum rows. Thus, for a module with no shifted columns, the
// minimum height is 1. Whilst for a module with -1 and +2 shifts, the minimum
// height is 4.
func determineMinimumTraceHeight[F field.Element[F]](schema sc.AnySchema[F]) []uint {
var (
minimums = make([]uint, schema.Width())
)
// Iterate each module
for i, m := range schema.Modules().Collect() {
var (
mid = uint(i)
front, back uint
)
// Iterate each constraint of each module
for c := m.Constraints(); c.HasNext(); {
bounds := c.Next().Bounds(mid)
//
front = max(front, bounds.Start)
back = max(back, bounds.End)
}
// Calculate minimum trace size
minimums[i] = front + back + 1
}
//
return minimums
}

// rebuildModules regroups a flat array of (possibly padded) columns -- as
// produced by mapping over the (module,column) pairs from flattenTrace --
// back into their enclosing modules, using each module's original descriptor
// (which padding never changes).
func rebuildModules[F field.Element[F]](mods []ArrayModule[F], columns []util.Pair[uint, uint],
func rebuildModules[F field.Element[F]](mods []ArrayModule[F], columns []trace.ColumnRef,
padded []array.MutArray[F]) []ArrayModule[F] {
var (
result = make([]ArrayModule[F], len(mods))
buffers = make([][]array.MutArray[F], len(mods))
)
// Regroup padded columns by their enclosing module.
for i, p := range columns {
var mid = p.Left
var mid = p.Module()
//
if buffers[mid] == nil {
buffers[mid] = make([]array.MutArray[F], mods[mid].Width())
}
//
buffers[mid][p.Right] = padded[i]
buffers[mid][p.Column().Unwrap()] = padded[i]
}
// Reconstruct each module using its original descriptor.
for mid, mod := range mods {
Expand Down
22 changes: 11 additions & 11 deletions pkg/ir/builder/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ import (
// TraceValidation validates that values held in trace columns match the
// expected type. This is really a sanity check that the trace is not
// malformed.
func TraceValidation[F field.Element[F]](config Config, schema sc.AnySchema[F], trace trace.Trace[F]) []error {
func TraceValidation[F field.Element[F]](config Config, schema sc.AnySchema[F], tr trace.Trace[F]) []error {
var (
errors []error
// Start timer
stats = util.NewPerfStats()
// Flatten all columns
columns, errs = flattenTrace(schema, trace)
columns, errs = flattenTrace(schema, tr)
// Mapping function
mapfn = func(_ uint, p util.Pair[uint, uint]) error {
mapfn = func(_ uint, c trace.ColumnRef) error {
var (
smod = schema.Module(p.Left)
tmod = trace.Module(p.Left)
rid = register.NewId(p.Right)
smod = schema.Module(c.Module())
tmod = tr.Module(c.Module())
rid = c.Column()
)

return validateColumnBitWidth(rid, smod, tmod)
Expand All @@ -60,11 +60,11 @@ func TraceValidation[F field.Element[F]](config Config, schema sc.AnySchema[F],
return append(errs, errors...)
}

func flattenTrace[F field.Element[F]](schema sc.AnySchema[F], tr trace.Trace[F]) ([]util.Pair[uint, uint], []error) {
func flattenTrace[F field.Element[F]](schema sc.AnySchema[F], tr trace.Trace[F]) ([]trace.ColumnRef, []error) {
var (
errors []error
//
columns []util.Pair[uint, uint]
columns []trace.ColumnRef
)
//
for i := uint(0); i < max(schema.Width(), tr.Width()); i++ {
Expand All @@ -87,13 +87,13 @@ func flattenTrace[F field.Element[F]](schema sc.AnySchema[F], tr trace.Trace[F])
}

func flattenColumns[F field.Element[F]](mid uint, scMod sc.Module[F], trMod trace.Module[F],
) ([]util.Pair[uint, uint], []error) {
) ([]trace.ColumnRef, []error) {
var (
errors []error
// Extract module registers
registers = scMod.Registers()
//
columns []util.Pair[uint, uint]
columns []trace.ColumnRef
)
// Sanity check
if scMod.Name() != trMod.Name() {
Expand All @@ -109,7 +109,7 @@ func flattenColumns[F field.Element[F]](mid uint, scMod sc.Module[F], trMod trac
err := fmt.Errorf("unknown column %s.%s in trace", trMod.Name(), trMod.Descriptor().Columns[i].Name)
errors = append(errors, err)
} else {
columns = append(columns, util.NewPair(mid, i))
columns = append(columns, trace.NewColumnRef(mid, register.NewId(i)))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/ir/mir/concretize.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func concretizeModule[F1 Element[F1], F2 Element[F2]](m Module[F1]) Module[F2] {
constraints = concretizeConstraints[F1, F2](m.RawConstraints())
)
// Initialise new module
r = r.Init(m.Name(), m.AllowPadding(), m.IsPublicOutput(), m.IsPrivateOutput(), m.IsSynthetic(), m.IsNative(),
r = r.Init(m.Name(), m.IsPublicOutput(), m.IsPrivateOutput(), m.IsSynthetic(), m.IsNative(),
m.IsStatic())
// Add concretized components
r.AddRegisters(m.Registers()...)
Expand Down
2 changes: 1 addition & 1 deletion pkg/ir/mir/lower.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func NewAirLowering[F field.Element[F]](fieldBandwidth uint, mirSchema Schema[F]
)
// Initialise AIR modules
for _, m := range mirSchema.RawModules() {
airSchema.NewModule(m.Name(), m.AllowPadding(), m.IsPublicOutput(), m.IsPrivateOutput(), m.IsSynthetic(),
airSchema.NewModule(m.Name(), m.IsPublicOutput(), m.IsPrivateOutput(), m.IsSynthetic(),
m.IsStatic(), m.IsNative())
}
//
Expand Down
Loading