Skip to content

Commit

Permalink
More accessible machine learning functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkskeller committed Feb 16, 2023
1 parent 7266f3b commit 5153c63
Show file tree
Hide file tree
Showing 119 changed files with 3,857 additions and 969 deletions.
2 changes: 2 additions & 0 deletions BMR/Register.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ class ProgramRegister : public Phase, public Register
static void andm(GC::Processor<U>&, const BaseInstruction&)
{ throw runtime_error("andm not implemented"); }

static void run_tapes(const vector<int>&) { throw not_implemented(); }

// most BMR phases don't need actual input
template<class T>
static T get_input(GC::Processor<T>& processor, const InputArgs& args)
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
The changelog explains changes pulled through from the private development repository. Bug fixes and small enhancements are committed between releases and not documented here.

## 0.3.5 (Feb 16, 2023)

- Easier-to-use machine learning interface
- Integrated compilation-execution facility
- Import/export sequential models and parameters from/to PyTorch
- Binary-format input files
- Less aggressive round optimization for faster compilation by default
- Multithreading with client interface
- Functionality to protect order of specific memory accesses
- Oblivious transfer works again on older (pre-2011) x86 CPUs
- clang is used by default

## 0.3.4 (Nov 9, 2022)

- Decision tree learning
Expand Down
2 changes: 1 addition & 1 deletion CONFIG
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ endif
USE_KOS = 0

# allow to set compiler in CONFIG.mine
CXX = g++
CXX = clang++

# use CONFIG.mine to overwrite DIR settings
-include CONFIG.mine
Expand Down
35 changes: 21 additions & 14 deletions Compiler/GC/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,23 +711,31 @@ def n_elements():
def mem_size():
return n
@classmethod
def get_input_from(cls, player):
def get_input_from(cls, player, size=1, f=0):
""" Secret input from :py:obj:`player`. The input is decomposed
into bits.
:param: player (int)
"""
v = [0] * n
sbits._check_input_player(player)
res = cls.from_vec(sbit() for i in range(n))
inst.inputbvec(n + 3, 0, player, *res.v)
return res
instructions_base.check_vector_size(size)
for i in range(size):
vv = [sbit() for i in range(n)]
inst.inputbvec(n + 3, f, player, *vv)
for j in range(n):
tmp = vv[j] << i
v[j] = tmp ^ v[j]
sbits._check_input_player(player)
return cls.from_vec(v)
get_raw_input_from = get_input_from
@classmethod
def from_vec(cls, vector):
res = cls()
res.v = _complement_two_extend(list(vector), n)[:n]
return res
def __init__(self, other=None, size=None):
instructions_base.check_vector_size(size)
if other is not None:
if util.is_constant(other):
t = sbits.get_type(size or 1)
Expand Down Expand Up @@ -1148,6 +1156,9 @@ class sbitint(_bitint, _number, sbits, _sbitintbase):
mul: 15
lt: 0
This class is retained for compatibility, but development now
focuses on :py:class:`sbitintvec`.
"""
n_bits = None
bin_type = None
Expand Down Expand Up @@ -1347,9 +1358,12 @@ def output(self):
cbits(0), cbits(0))

class sbitfix(_fix):
""" Secret signed integer in one binary register.
""" Secret signed fixed-point number in one binary register.
Use :py:obj:`set_precision()` to change the precision.
This class is retained for compatibility, but development now
focuses on :py:class:`sbitfixvec`.
Example::
print_ln('add: %s', (sbitfix(0.5) + sbitfix(0.3)).reveal())
Expand Down Expand Up @@ -1453,15 +1467,8 @@ def get_input_from(cls, player, size=1):
:param: player (int)
"""
v = [0] * sbitfix.k
sbits._check_input_player(player)
for i in range(size):
vv = [sbit() for i in range(sbitfix.k)]
inst.inputbvec(len(v) + 3, sbitfix.f, player, *vv)
for j in range(sbitfix.k):
tmp = vv[j] << i
v[j] = tmp ^ v[j]
return cls._new(cls.int_type.from_vec(v))
return cls._new(cls.int_type.get_input_from(player, size=size,
f=sbitfix.f))
def __init__(self, value=None, *args, **kwargs):
if isinstance(value, (list, tuple)):
self.v = self.int_type.from_vec(sbitvec([x.v for x in value]))
Expand Down
39 changes: 25 additions & 14 deletions Compiler/allocator.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,6 @@ def dependency_graph(self, merge_classes):
last_def = defaultdict_by_id(lambda: -1)
last_mem_write = []
last_mem_read = []
warned_about_mem = []
last_mem_write_of = defaultdict(list)
last_mem_read_of = defaultdict(list)
last_print_str = None
Expand Down Expand Up @@ -364,20 +363,22 @@ def mem_access(n, instr, last_access_this_kind, last_access_other_kind):
addr_i = addr + i
handle_mem_access(addr_i, reg_type, last_access_this_kind,
last_access_other_kind)
if block.warn_about_mem and not warned_about_mem and \
(instr.get_size() > 100):
if block.warn_about_mem and \
not block.parent.warned_about_mem and \
(instr.get_size() > 100) and not instr._protect:
print('WARNING: Order of memory instructions ' \
'not preserved due to long vector, errors possible')
warned_about_mem.append(True)
block.parent.warned_about_mem = True
else:
handle_mem_access(addr, reg_type, last_access_this_kind,
last_access_other_kind)
if block.warn_about_mem and not warned_about_mem and \
not isinstance(instr, DirectMemoryInstruction):
if block.warn_about_mem and \
not block.parent.warned_about_mem and \
not isinstance(instr, DirectMemoryInstruction) and \
not instr._protect:
print('WARNING: Order of memory instructions ' \
'not preserved, errors possible')
# hack
warned_about_mem.append(True)
block.parent.warned_about_mem = True

def strict_mem_access(n, last_this_kind, last_other_kind):
if last_other_kind and last_this_kind and \
Expand Down Expand Up @@ -473,14 +474,14 @@ def keep_text_order(inst, n):
depths[n] = depth

if isinstance(instr, ReadMemoryInstruction):
if options.preserve_mem_order:
if options.preserve_mem_order or instr._protect:
strict_mem_access(n, last_mem_read, last_mem_write)
else:
elif not options.preserve_mem_order:
mem_access(n, instr, last_mem_read_of, last_mem_write_of)
elif isinstance(instr, WriteMemoryInstruction):
if options.preserve_mem_order:
if options.preserve_mem_order or instr._protect:
strict_mem_access(n, last_mem_write, last_mem_read)
else:
elif not options.preserve_mem_order:
mem_access(n, instr, last_mem_write_of, last_mem_read_of)
elif isinstance(instr, matmulsm):
if options.preserve_mem_order:
Expand All @@ -495,7 +496,7 @@ def keep_text_order(inst, n):
add_edge(last_print_str, n)
last_print_str = n
elif isinstance(instr, PublicFileIOInstruction):
keep_order(instr, n, instr.__class__)
keep_order(instr, n, PublicFileIOInstruction)
elif isinstance(instr, prep_class):
keep_order(instr, n, instr.args[0])
elif isinstance(instr, StackInstruction):
Expand Down Expand Up @@ -586,7 +587,7 @@ class RegintOptimizer:
def __init__(self):
self.cache = util.dict_by_id()

def run(self, instructions):
def run(self, instructions, program):
for i, inst in enumerate(instructions):
if isinstance(inst, ldint_class):
self.cache[inst.args[0]] = inst.args[1]
Expand All @@ -601,6 +602,7 @@ def run(self, instructions):
elif isinstance(inst, IndirectMemoryInstruction):
if inst.args[1] in self.cache:
instructions[i] = inst.get_direct(self.cache[inst.args[1]])
instructions[i]._protect = inst._protect
elif type(inst) == convint_class:
if inst.args[1] in self.cache:
res = self.cache[inst.args[1]]
Expand All @@ -614,4 +616,13 @@ def run(self, instructions):
if op == 0:
instructions[i] = ldsi(inst.args[0], 0,
add_to_prog=False)
elif isinstance(inst, (crash, cond_print_str, cond_print_plain)):
if inst.args[0] in self.cache:
cond = self.cache[inst.args[0]]
if not cond:
instructions[i] = None
pre = len(instructions)
instructions[:] = list(filter(lambda x: x is not None, instructions))
post = len(instructions)
if pre != post and program.options.verbose:
print('regint optimizer removed %d instructions' % (pre - post))
Loading

0 comments on commit 5153c63

Please sign in to comment.