1. 姚氏百万富翁问题
除了三方协议ABY3之外,我们还可以通过配置cluster_def中的protocol更换不同的协议。
import spu
import secretflow as sfsf.shutdown()
sf.init(['alice', 'bob', 'carol', 'dave'], address='local')
# 生成一个环境
cheetah_config = sf.utils.testing.cluster_def(parties=['alice', 'bob'],runtime_config={'protocol': spu.spu_pb2.CHEETAH,'field': spu.spu_pb2.FM64,},
)
# 创建一个基于alice和bob的SPU设备
spu_device2 = sf.SPU(cheetah_config)
# 获取carol的资产,只要最后可以返回一个值即可
def get_carol_assets():return 1000000
# 获取dave的资产,只要最后可以返回一个值即可
def get_dave_assets():return 1000002
# 创建两个PYU设备
carol, dave = sf.PYU('carol'), sf.PYU('dave')
# 生成两个PYUObject
carol_assets = carol(get_carol_assets)()
dave_assets = dave(get_dave_assets)()
# 设置比较函数
def get_winner(carol, dave):return carol > dave
# 将函数和相应的参数放入SPU设备执行
winner = spu_device2(get_winner)(carol_assets, dave_assets)
sf.reveal(winner)
2.从SPU计算得到多个返回值
在大多数情况下,我们从 SPU 设备执行的函数中获得多个返回值。
博主个人比较喜欢第二种
def get_multiple_outputs(x, y):return x + y, x - y
# 方式一:默认情况下会将其包装成元组的形式
# (array(2000002, dtype=int32), array(-2, dtype=int32))
single_output = spu_device2(get_multiple_outputs)(carol_assets, dave_assets)# 方式二:指示 SPU 为我们根据编译结果决定返回值数量。(推荐这一种)
# 返回对象的列表
multiple_outputs = spu_device2(get_multiple_outputs, num_returns_policy=SPUCompilerNumReturnsPolicy.FROM_COMPILER
)(carol_assets, dave_assets)
# 方式三:手动确定返回值数量
user_multiple_outputs = spu_device2(get_multiple_outputs,num_returns_policy=SPUCompilerNumReturnsPolicy.FROM_USER,user_specified_num_returns=2,
)(carol_assets, dave_assets)user_multiple_outputs
3. 总结一下
- 默认情况下,SPU 将所有返回值视为单个返回值。
- 由于 SPU 编译器生成 SPU 可执行文件,它可以计算出返回值数量。 但是,这个选项会导致一些延迟,因为我们必须使编译工作阻塞。
- 如果您想避免延迟,我们可以手动提供返回值数量。 但是你必须确保你提供了正确的数字,否则程序会报错!