Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: chore enable exp and mmu tests #510

Merged
merged 2 commits into from
Jan 8, 2025
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
60 changes: 60 additions & 0 deletions pkg/corset/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package corset
import (
"fmt"
"math"
"slices"
"strings"

"github.com/consensys/go-corset/pkg/schema"
Expand Down Expand Up @@ -105,6 +106,54 @@ func (p *RegisterSource) Perspective() string {
return p.name.Parent().Slice(p.context.Depth()).String()
}

// RegisterAllocationView provides a view of an environment for the purposes of
// register allocation, such that only registers in this view will be considered
// for allocation. This is necessary because we must not attempt to allocate
// registers across different modules (indeed, contexts) together. Instead, we
// must allocate registers on a module-by-module basis, etc.
type RegisterAllocationView struct {
// View of registers available for register allocation.
registers []uint
// Parent pointer for register merging.
env *GlobalEnvironment
}

// Len returns the number of allocated registers.
func (p *RegisterAllocationView) Len() uint {
return uint(len(p.registers))
}

// Registers returns an iterator over the set of registers in this local
// allocation.
func (p *RegisterAllocationView) Registers() util.Iterator[uint] {
return util.NewArrayIterator(p.registers)
}

// Register accesses information about a specific register in this window.
func (p *RegisterAllocationView) Register(index uint) *Register {
return &p.env.registers[index]
}

// Merge one register (src) into another (dst). This will remove the src
// register, and automatically update all column assignments. Therefore, any
// register identifier can be potenitally invalided by this operation. This
// will panic if the registers are incompatible (i.e. have different contexts).
func (p *RegisterAllocationView) Merge(dst uint, src uint) {
target := &p.env.registers[dst]
source := &p.env.registers[src]
// Sanity check
if target.Context != source.Context {
// Should be unreachable.
panic("attempting to merge incompatible registers")
}
// Update column map
for _, col := range p.env.ColumnsOf(src) {
p.env.columns[col] = dst
}
//
target.Merge(source)
}

// RegisterAllocation is a generic interface to support different "regsiter
// allocation" algorithms. More specifically, register allocation is the
// process of allocating columns to their underlying HIR columns (a.k.a
Expand Down Expand Up @@ -143,6 +192,7 @@ var DEFAULT_ALLOCATOR func(RegisterAllocation) = originalAllocator
// The original register allocation algorithm used in Corset. This is retained
// for backwards compatibility reasons, but should eventually be dropped.
func originalAllocator(allocation RegisterAllocation) {
sortRegisters(allocation.(*RegisterAllocationView))
allocator := NewRegisterAllocator(allocation)
allocator.CompactBy(identicalType)
allocator.Finalise()
Expand All @@ -159,6 +209,16 @@ func identicalType(lhs *RegisterGroup, rhs *RegisterGroup) bool {
return lIntType == rIntType
}

// Sort the registers into alphabetical order.
func sortRegisters(view *RegisterAllocationView) {
slices.SortFunc(view.registers, func(l, r uint) int {
lhs := view.Register(l)
rhs := view.Register(r)
// Compare them alphabetically
return strings.Compare(lhs.Name, rhs.Name)
})
}

// ============================================================================
// GreedyAllocator
// ============================================================================
Expand Down
54 changes: 1 addition & 53 deletions pkg/corset/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ func (p *GlobalEnvironment) applyRegisterAllocation(allocator func(RegisterAlloc
// Determine register subset for this module
view := p.RegistersOf(m)
// Apply allocation to this subset
allocator(&localRegisterAllocation{view, p})
allocator(&RegisterAllocationView{view, p})
}
// Remove inactive registers. This is necessary because register allocation
// marks a register as inactive when they its merged into another, but does
Expand Down Expand Up @@ -293,55 +293,3 @@ func (p *GlobalEnvironment) applyRegisterAllocation(allocator func(RegisterAlloc
// Copy over new register set, whilst slicing off inactive ones.
p.registers = nregisters[0:j]
}

// ===========================================================================
// RegisterAllocation impl
// ===========================================================================

// LocalRegisterAllocation provides a view of the environment for the purposes
// of register allocation, such that only registers in this view will be
// considered for allocation. This is necessary because we must not attempt to
// allocate registers across different modules (indeed, contexts) together.
// Instead, we must allocate registers on a module-by-module basis, etc.
type localRegisterAllocation struct {
// View of registers available for register allocation.
registers []uint
// Parent pointer for register merging.
env *GlobalEnvironment
}

// Len returns the number of allocated registers.
func (p *localRegisterAllocation) Len() uint {
return uint(len(p.registers))
}

// Registers returns an iterator over the set of registers in this local
// allocation.
func (p *localRegisterAllocation) Registers() util.Iterator[uint] {
return util.NewArrayIterator(p.registers)
}

// Access information about a specific register in this window.
func (p *localRegisterAllocation) Register(index uint) *Register {
return &p.env.registers[index]
}

// Merge one register (src) into another (dst). This will remove the src
// register, and automatically update all column assignments. Therefore, any
// register identifier can be potenitally invalided by this operation. This
// will panic if the registers are incompatible (i.e. have different contexts).
func (p *localRegisterAllocation) Merge(dst uint, src uint) {
target := &p.env.registers[dst]
source := &p.env.registers[src]
// Sanity check
if target.Context != source.Context {
// Should be unreachable.
panic("attempting to merge incompatible registers")
}
// Update column map
for _, col := range p.env.ColumnsOf(src) {
p.env.columns[col] = dst
}
//
target.Merge(source)
}
12 changes: 7 additions & 5 deletions pkg/test/valid_corset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,10 @@ func Test_Perspective_27(t *testing.T) {
Check(t, false, "perspective_27")
}

func Test_Perspective_28(t *testing.T) {
Check(t, false, "perspective_28")
}

// ===================================================================
// Complex Tests
// ===================================================================
Expand Down Expand Up @@ -955,19 +959,17 @@ func TestSlow_Rom(t *testing.T) {
Check(t, true, "rom")
}

/*
func TestSlow_Mmu(t *testing.T) {
Check(t, true, "mmu")
} */
}

func TestSlow_Gas(t *testing.T) {
Check(t, true, "gas")
}

/* #396
func TestSlow_Exp(t *testing.T) {
func TestSlow_Exp(t *testing.T) {
Check(t, true, "exp")
} */
}

func TestSlow_Mul(t *testing.T) {
Check(t, true, "mul")
Expand Down
9 changes: 9 additions & 0 deletions testdata/exp.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@
CT_MAX_MACRO_MODEXP_LOG 0
CT_MAX_PRPRC_MODEXP_LOG 3)

(defconst
EVM_INST_LT 0x10
EVM_INST_ISZERO 0x15
;;
EXP_INST_EXPLOG 0xEE0A
EXP_INST_MODEXPLOG 0xEE05
;;
GAS_CONST_G_EXP_BYTE 50)


(module exp)

Expand Down
20 changes: 10 additions & 10 deletions testdata/mmu.accepts

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions testdata/mmu.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,25 @@
NB_MICRO_ROWS_TOT_MODEXP_DATA 32
NB_MICRO_ROWS_TOT_BLAKE 2)

(defconst
EVM_INST_LT 0x10
EVM_INST_EQ 0x14
EVM_INST_ISZERO 0x15
;;
MMU_INST_MLOAD 0xfe01
MMU_INST_MSTORE 0xfe02
MMU_INST_MSTORE8 0xfe03
MMU_INST_INVALID_CODE_PREFIX 0xfe00
MMU_INST_RIGHT_PADDED_WORD_EXTRACTION 0xfe10
MMU_INST_RAM_TO_EXO_WITH_PADDING 0xfe20
MMU_INST_EXO_TO_RAM_TRANSPLANTS 0xfe30
MMU_INST_RAM_TO_RAM_SANS_PADDING 0xfe40
MMU_INST_ANY_TO_RAM_WITH_PADDING 0xfe50
;;MMU_INST_ANY_TO_RAM_WITH_PADDING_SOME_DATA 0xfe51
;;MMU_INST_ANY_TO_RAM_WITH_PADDING_PURE_PADDING 0xfe52
MMU_INST_MODEXP_ZERO 0xfe60
MMU_INST_MODEXP_DATA 0xfe70
MMU_INST_BLAKE 0xfe80)

(module mmu)

Expand Down
Loading
Loading