MP-SPDZ开源库——while_do的研究

今天记录下一个spdz开源库里的while_do函数的用法

测试版本0.3.0

while_do函数的介绍

在这里插入图片描述

一句一句解释一下

While-do loop. :函数是用来做while循环的。

The decorator requires an initialization, :解释器需要一个初始化,可以理解为在这里为循环赋初始状态(值)
and the loop body function must return a suitable input for condition.:loop body也是一个函数,它被while_do函数修饰,可以理解为循环体也作为一个参数被传入while_do函数里执行。如果不懂可以百度下python中@函数修饰符的作用

Parameters
condition – function returning public integer (regint/cint/int):字面翻译是条件的意思,实际应该是一个函数,这个函数执行的是某个条件的判断。(不要疑惑,我们在小学二年级就学过,python的函数的传参也可以传函数。)
args – arguments given to condition and loop body:一些参数,这些参数被用在条件函数和循环体。可以用来给解释器初始化。

函数的实现源代码
def while_do(condition, *args):
    def decorator(loop_body):
        while_loop(loop_body, condition, *args)
        return loop_body
    return decorator

源代码不多说了。

官方给的实例:
@while_do(lambda x: x < 10, regint(0))
def f(i):
    ...
    return i + 1

lambda:是python内置的一个表达式语法,不熟悉的同学可以百度下。在这个例子中就是判断传入的参数x是否小于10
regint(0):表示初始值为0。也就是一开始i=0。regint是spdz库定义的一个类型,没看过可以暂时放一放,可以把它看作int
def f(i):定义了一个循环体函数
return i+1:循环体函数返回了i+1
实例代码的运行流程:

  • i被赋予初值i=0
  • ...做了某些操作
  • 返回了i+1
  • 判断i+1是否<10
  • 若小于10,继续执行循环体函数
  • 若大于等于10跳出循环,结束
    等价代码:
while i<10:
	...
	i = i + 1
上手实例:快速排序

原始的python语法实现:

def insertsort(a, low, high):
    for i in range(low + 1, high):
        j = i
        while j > 0 and a[j] < a[j - 1]:
            a[j], a[j - 1] = a[j - 1], a[j]
            j -= 1

我们根据上面的代码,转换成按照spdz库语法写的代码。

def insertsort(a,low,high):
    @for_range(low+1,high)
    def _(i):
        @while_do(lambda j:j>0, i)
        def _(j):
            a[j],a[j-1] = cond_swap(a[j],a[j-1])
            return j-1

for_range就是for循环,没见过的小伙伴可以跳过,我们这里主要讲while_do的用法。
直接看最里面的while层。

  • 为循环体的j赋初值j=i
  • a[j],a[j-1] = cond_swap(a[j],a[j-1]) 这个是spdz定义的函数,如果aj<aj-1就交换两个元素;否则,不交换两个元素的值。
  • return j-1:让j的值减一
  • 判断j是否大于0,不满足则跳出循环。
    另一个版本: 将lambda替换成了函数
def insertsort1(a,low,high):
    @for_range(low+1,high)
    def _(i):
        def jian(k):
            return k>0
        @while_do(jian, i)
        def _(j):
            a[j],a[j-1] = cond_swap(a[j],a[j-1])
            return j-1

完整的测试代码:test.mpc

a = Array(10,sint)
a.assign([45,65,1,427,11,54,154,254,96,47])
print_ln("a = %s",a.reveal())
low = 0
high = 10
def insertsort(a,low,high):
    @for_range(low+1,high)
    def _(i):
        @while_do(lambda j:j>0, i)
        def _(j):
            a[j],a[j-1] = cond_swap(a[j],a[j-1])
            return j-1
def insertsort1(a,low,high):
    @for_range(low+1,high)
    def _(i):
        def jian(k):
            return k>0
        @while_do(jian, i)
        def _(j):
            a[j],a[j-1] = cond_swap(a[j],a[j-1])
            return j-1
insertsort1(a,low,high)
print_ln("a = %s",a.reveal())
a.sort()
print_ln("a = %s",a.reveal())

编译./compile.py -F 64 test
执行Scripts/run-online.sh test
运行结果

Running /home/spdz030/Scripts/../Player-Online.x 0 test -pn 16118 -h localhost -N 2
Running /home/spdz030/Scripts/../Player-Online.x 1 test -pn 16118 -h localhost -N 2
a = [45, 65, 1, 427, 11, 54, 154, 254, 96, 47]
a = [427, 254, 154, 96, 65, 54, 47, 45, 11, 1]
REWINDING - ONLY FOR BENCHMARKING
a = [1, 11, 45, 47, 54, 65, 96, 154, 254, 427]
The following timing is exclusive preprocessing.
Time = 0.0522126 seconds 
Data sent = 0.423992 MB in ~892 rounds (party 0)
Global data sent = 0.847968 MB (all parties)
This program might benefit from some protocol options.
Consider adding the following at the beginning of 'test.mpc':
	program.use_edabit(True)

更新

传两个参数

def jian(i):
    return (i[0]<10).bit_and(i[1]<10) 
@while_do(jian, [regint(0),regint(0)])
def f(k):
    print_ln("%s,%s",k[0],k[1])
    return k+1
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值