Skip to content

Commit

Permalink
Merge pull request #191 from Consensys/188-support-json-to-lt-trace-c…
Browse files Browse the repository at this point in the history
…onversion

feat: Support JSON to LT Trace Conversion
  • Loading branch information
DavePearce authored Jun 26, 2024
2 parents c00e1cc + 5588872 commit 61ff183
Show file tree
Hide file tree
Showing 25 changed files with 178 additions and 131 deletions.
2 changes: 1 addition & 1 deletion pkg/air/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// value at that row of the column in question or nil is that row is
// out-of-bounds.
func (e *ColumnAccess) EvalAt(k int, tr trace.Trace) *fr.Element {
val := tr.ColumnByIndex(e.Column).Get(k + e.Shift)
val := tr.Column(e.Column).Get(k + e.Shift)

var clone fr.Element
// Clone original value
Expand Down
49 changes: 46 additions & 3 deletions pkg/cmd/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"math"
"os"
"strings"

Expand All @@ -25,19 +26,31 @@ var traceCmd = &cobra.Command{
// Parse trace
trace := readTraceFile(args[0])
list := getFlag(cmd, "list")
print := getFlag(cmd, "print")
padding := getUint(cmd, "pad")
start := getUint(cmd, "start")
end := getUint(cmd, "end")
max_width := getUint(cmd, "max-width")
filter := getString(cmd, "filter")
output := getString(cmd, "out")
//
if filter != "" {
trace = filterColumns(trace, filter)
}
if padding != 0 {
trace.Pad(padding)
}
if list {
listColumns(trace)
}
//
if output != "" {
writeTraceFile(output, trace)
}

if print {
printTrace(start, end, max_width, trace)
}
},
}

Expand All @@ -47,7 +60,7 @@ func filterColumns(tr trace.Trace, prefix string) trace.Trace {
ntr := trace.EmptyArrayTrace()
//
for i := uint(0); i < tr.Width(); i++ {
ith := tr.ColumnByIndex(i)
ith := tr.Column(i)
if strings.HasPrefix(ith.Name(), prefix) {
ntr.Add(ith)
}
Expand All @@ -60,7 +73,7 @@ func listColumns(tr trace.Trace) {
tbl := util.NewTablePrinter(3, tr.Width())

for i := uint(0); i < tr.Width(); i++ {
ith := tr.ColumnByIndex(i)
ith := tr.Column(i)
elems := fmt.Sprintf("%d rows", ith.Height())
bytes := fmt.Sprintf("%d bytes", ith.Width()*ith.Height())
tbl.SetRow(i, ith.Name(), elems, bytes)
Expand All @@ -71,9 +84,39 @@ func listColumns(tr trace.Trace) {
tbl.Print()
}

func printTrace(start uint, end uint, max_width uint, tr trace.Trace) {
height := min(tr.Height(), end) - start
tbl := util.NewTablePrinter(1+height, 1+tr.Width())

for j := uint(0); j < height; j++ {
tbl.Set(j+1, 0, fmt.Sprintf("#%d", j+start))
}

for i := uint(0); i < tr.Width(); i++ {
ith := tr.Column(i)
tbl.Set(0, i+1, ith.Name())

if start < ith.Height() {
ith_height := min(ith.Height(), end) - start
for j := uint(0); j < ith_height; j++ {
tbl.Set(j+1, i+1, ith.Get(int(j+start)).String())
}
}
}

//
tbl.SetMaxWidth(max_width)
tbl.Print()
}

func init() {
rootCmd.AddCommand(traceCmd)
traceCmd.Flags().BoolP("list", "l", false, "detail the columns in the trace file")
traceCmd.Flags().BoolP("list", "l", false, "list only the columns in the trace file")
traceCmd.Flags().BoolP("print", "p", false, "print entire trace file")
traceCmd.Flags().Uint("pad", 0, "add a given number of padding rows (to each module)")
traceCmd.Flags().UintP("start", "s", 0, "filter out rows below this")
traceCmd.Flags().UintP("end", "e", math.MaxUint, "filter out this and all following rows")
traceCmd.Flags().Uint("max-width", 32, "specify maximum display width for a column")
traceCmd.Flags().StringP("out", "o", "", "Specify output file to write trace")
traceCmd.Flags().StringP("filter", "f", "", "Filter columns beginning with prefix")
}
2 changes: 1 addition & 1 deletion pkg/cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func readTraceFile(filename string) trace.Trace {
//
switch ext {
case ".json":
tr, err = trace.ParseJsonTrace(bytes)
tr, err = json.FromBytes(bytes)
if err == nil {
return tr
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/hir/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// value at that row of the column in question or nil is that row is
// out-of-bounds.
func (e *ColumnAccess) EvalAllAt(k int, tr trace.Trace) []*fr.Element {
val := tr.ColumnByIndex(e.Column).Get(k + e.Shift)
val := tr.Column(e.Column).Get(k + e.Shift)

var clone fr.Element
// Clone original value
Expand Down
2 changes: 1 addition & 1 deletion pkg/mir/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// value at that row of the column in question or nil is that row is
// out-of-bounds.
func (e *ColumnAccess) EvalAt(k int, tr trace.Trace) *fr.Element {
val := tr.ColumnByIndex(e.Column).Get(k + e.Shift)
val := tr.Column(e.Column).Get(k + e.Shift)

var clone fr.Element
// Clone original value
Expand Down
4 changes: 2 additions & 2 deletions pkg/schema/alignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func alignWith(expand bool, p tr.Trace, schema Schema) error {
return fmt.Errorf("trace missing column %s", schemaName)
}

traceName := p.ColumnByIndex(index).Name()
traceName := p.Column(index).Name()
// Check alignment
if traceName != schemaName {
// Not aligned --- so fix
Expand All @@ -74,7 +74,7 @@ func alignWith(expand bool, p tr.Trace, schema Schema) error {
unknowns := make([]string, n)
// Determine names of unknown columns.
for i := index; i < ncols; i++ {
unknowns[i-index] = p.ColumnByIndex(i).Name()
unknowns[i-index] = p.Column(i).Name()
}
//
return fmt.Errorf("trace contains unknown columns: %v", unknowns)
Expand Down
10 changes: 5 additions & 5 deletions pkg/schema/assignment/byte_decomposition.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/consensys/gnark-crypto/ecc/bls12-377/fr"
"github.com/consensys/go-corset/pkg/schema"
tr "github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/util"
)

Expand Down Expand Up @@ -62,13 +62,13 @@ func (p *ByteDecomposition) IsComputed() bool {
// ExpandTrace expands a given trace to include the columns specified by a given
// ByteDecomposition. This requires computing the value of each byte column in
// the decomposition.
func (p *ByteDecomposition) ExpandTrace(tr tr.Trace) error {
func (p *ByteDecomposition) ExpandTrace(tr trace.Trace) error {
// Calculate how many bytes required.
n := len(p.targets)
// Identify target column
target := tr.ColumnByIndex(p.source)
target := tr.Column(p.source)
// Extract column data to decompose
data := tr.ColumnByIndex(p.source).Data()
data := tr.Column(p.source).Data()
// Construct byte column data
cols := make([][]*fr.Element, n)
// Initialise columns
Expand All @@ -86,7 +86,7 @@ func (p *ByteDecomposition) ExpandTrace(tr tr.Trace) error {
padding := decomposeIntoBytes(target.Padding(), n)
// Finally, add byte columns to trace
for i := 0; i < n; i++ {
tr.AddColumn(p.targets[i].Name(), cols[i], padding[i])
tr.Add(trace.NewFieldColumn(p.targets[i].Name(), cols[i], padding[i]))
}
// Done
return nil
Expand Down
6 changes: 3 additions & 3 deletions pkg/schema/assignment/computed.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr"
"github.com/consensys/go-corset/pkg/schema"
sc "github.com/consensys/go-corset/pkg/schema"
tr "github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/util"
)

Expand Down Expand Up @@ -75,7 +75,7 @@ func (p *ComputedColumn[E]) RequiredSpillage() uint {
// ExpandTrace attempts to a new column to the trace which contains the result
// of evaluating a given expression on each row. If the column already exists,
// then an error is flagged.
func (p *ComputedColumn[E]) ExpandTrace(tr tr.Trace) error {
func (p *ComputedColumn[E]) ExpandTrace(tr trace.Trace) error {
if tr.HasColumn(p.name) {
return fmt.Errorf("Computed column already exists ({%s})", p.name)
}
Expand All @@ -96,7 +96,7 @@ func (p *ComputedColumn[E]) ExpandTrace(tr tr.Trace) error {
// the padding value for *this* column.
padding := p.expr.EvalAt(-1, tr)
// Colunm needs to be expanded.
tr.AddColumn(p.name, data, padding)
tr.Add(trace.NewFieldColumn(p.name, data, padding))
// Done
return nil
}
8 changes: 4 additions & 4 deletions pkg/schema/assignment/lexicographic_sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func (p *LexicographicSort) ExpandTrace(tr trace.Trace) error {
delta[i] = &zero
// Decide which row is the winner (if any)
for j := 0; j < ncols; j++ {
prev := tr.ColumnByIndex(p.sources[j]).Get(i - 1)
curr := tr.ColumnByIndex(p.sources[j]).Get(i)
prev := tr.Column(p.sources[j]).Get(i - 1)
curr := tr.Column(p.sources[j]).Get(i)

if !set && prev != nil && prev.Cmp(curr) != 0 {
var diff fr.Element
Expand All @@ -108,11 +108,11 @@ func (p *LexicographicSort) ExpandTrace(tr trace.Trace) error {
}
}
// Add delta column data
tr.AddColumn(p.targets[0].Name(), delta, &zero)
tr.Add(trace.NewFieldColumn(p.targets[0].Name(), delta, &zero))
// Add bit column data
for i := 0; i < ncols; i++ {
bitName := p.targets[1+i].Name()
tr.AddColumn(bitName, bit[i], &zero)
tr.Add(trace.NewFieldColumn(bitName, bit[i], &zero))
}
// Done.
return nil
Expand Down
7 changes: 4 additions & 3 deletions pkg/schema/assignment/sorted_permutation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/consensys/gnark-crypto/ecc/bls12-377/fr"
"github.com/consensys/go-corset/pkg/schema"
"github.com/consensys/go-corset/pkg/trace"
tr "github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/util"
)
Expand Down Expand Up @@ -119,7 +120,7 @@ func (p *SortedPermutation) ExpandTrace(tr tr.Trace) error {
for i := 0; i < len(p.sources); i++ {
src := p.sources[i]
// Read column data to initialise permutation.
data := tr.ColumnByIndex(src).Data()
data := tr.Column(src).Data()
// Copy column data to initialise permutation.
cols[i] = make([]*fr.Element, len(data))
copy(cols[i], data)
Expand All @@ -131,8 +132,8 @@ func (p *SortedPermutation) ExpandTrace(tr tr.Trace) error {

for i := p.Columns(); i.HasNext(); {
dstColName := i.Next().Name()
srcCol := tr.ColumnByIndex(p.sources[index])
tr.AddColumn(dstColName, cols[index], srcCol.Padding())
srcCol := tr.Column(p.sources[index])
tr.Add(trace.NewFieldColumn(dstColName, cols[index], srcCol.Padding()))

index++
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/schema/constraint/permutation.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func sliceColumns(columns []uint, tr trace.Trace) [][]*fr.Element {
cols := make([][]*fr.Element, len(columns))
// Slice out the data
for i, n := range columns {
nth := tr.ColumnByIndex(n)
nth := tr.Column(n)
cols[i] = nth.Data()
}
// Done
Expand Down
2 changes: 1 addition & 1 deletion pkg/schema/constraint/range.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func NewRangeConstraint(column uint, bound *fr.Element) *RangeConstraint {
// Accepts checks whether a range constraint evaluates to zero on
// every row of a table. If so, return nil otherwise return an error.
func (p *RangeConstraint) Accepts(tr trace.Trace) error {
column := tr.ColumnByIndex(p.column)
column := tr.Column(p.column)
for k := 0; k < int(tr.Height()); k++ {
// Get the value on the kth row
kth := column.Get(k)
Expand Down
2 changes: 1 addition & 1 deletion pkg/schema/constraint/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (p *TypeConstraint) Type() schema.Type {
// Accepts checks whether a range constraint evaluates to zero on
// every row of a table. If so, return nil otherwise return an error.
func (p *TypeConstraint) Accepts(tr trace.Trace) error {
column := tr.ColumnByIndex(p.column)
column := tr.Column(p.column)
for k := 0; k < int(tr.Height()); k++ {
// Get the value on the kth row
kth := column.Get(k)
Expand Down
25 changes: 0 additions & 25 deletions pkg/schema/schemas.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package schema

import (
"fmt"

tr "github.com/consensys/go-corset/pkg/trace"
)

Expand Down Expand Up @@ -69,26 +67,3 @@ func ColumnIndexOf(schema Schema, name string) (uint, bool) {
return c.Name() == name
})
}

// ColumnByName returns the column with the matching name, or panics if no such
// column exists.
func ColumnByName(schema Schema, name string) Column {
var col Column
// Attempt to determine the index of this column
_, ok := schema.Columns().Find(func(c Column) bool {
col = c
return c.Name() == name
})
// If we found it, then done.
if ok {
return col
}
// Otherwise panic.
panic(fmt.Sprintf("unknown column %s", name))
}

// HasColumn checks whether a column of the given name is declared within the schema.
func HasColumn(schema Schema, name string) bool {
_, ok := ColumnIndexOf(schema, name)
return ok
}
3 changes: 2 additions & 1 deletion pkg/test/ir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/consensys/go-corset/pkg/schema"
sc "github.com/consensys/go-corset/pkg/schema"
"github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/trace/json"
)

// Determines the (relative) location of the test directory. That is
Expand Down Expand Up @@ -469,7 +470,7 @@ func ReadTracesFile(name string, ext string) []*trace.ArrayTrace {
for i, line := range lines {
// Parse input line as JSON
if line != "" && !strings.HasPrefix(line, ";;") {
tr, err := trace.ParseJsonTrace([]byte(line))
tr, err := json.FromBytes([]byte(line))
if err != nil {
msg := fmt.Sprintf("%s.%s:%d: %s", name, ext, i+1, err)
panic(msg)
Expand Down
30 changes: 3 additions & 27 deletions pkg/trace/array_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,11 @@ func (p *ArrayTrace) Columns() []Column {
return p.columns
}

// ColumnByIndex looks up a column based on its index.
func (p *ArrayTrace) ColumnByIndex(index uint) Column {
// Column looks up a column based on its index.
func (p *ArrayTrace) Column(index uint) Column {
return p.columns[index]
}

// ColumnByName looks up a column based on its name. If the column doesn't
// exist, then nil is returned.
func (p *ArrayTrace) ColumnByName(name string) Column {
for _, c := range p.columns {
if name == c.Name() {
// Matched column
return c
}
}

return nil
}

// HasColumn checks whether the trace has a given named column (or not).
func (p *ArrayTrace) HasColumn(name string) bool {
_, ok := p.ColumnIndex(name)
Expand Down Expand Up @@ -120,18 +107,7 @@ func (p *ArrayTrace) Add(column Column) {

// AddColumn adds a new column of data to this trace.
func (p *ArrayTrace) AddColumn(name string, data []*fr.Element, padding *fr.Element) {
// Sanity check the column does not already exist.
if p.HasColumn(name) {
panic("column already exists")
}
// Construct new column
column := FieldColumn{name, data, padding}
// Append it
p.columns = append(p.columns, &column)
// Update maximum height
if uint(len(data)) > p.height {
p.height = uint(len(data))
}
p.Add(&FieldColumn{name, data, padding})
}

// Height determines the maximum height of any column within this trace.
Expand Down
Loading

0 comments on commit 61ff183

Please sign in to comment.