Skip to content

Commit

Permalink
Fix and test the integral propery with np_vstack (#69)
Browse files Browse the repository at this point in the history
* Unit test the integral property for atomic SecFxp

* Start unit testing integral for SecFxp arrays

* Fix integral property for np_vstack

* Shortened syntax for tests, mixed in extra cases.

---------

Co-authored-by: Berry Schoenmakers <[email protected]>
  • Loading branch information
MarcT0K and lschoe committed Sep 6, 2023
1 parent 1636d55 commit cd1a0a8
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
9 changes: 8 additions & 1 deletion mpyc/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -2640,9 +2640,16 @@ def block_shape(a):
@mpc_coro_no_pc
async def np_vstack(self, tup):
a = tup[0]
stype = type(a)
shape = list(a.shape) if a.ndim >= 2 else [1, a.shape[0]]
shape[0] = sum(a.shape[0] if a.shape[1:] else 1 for a in tup)
await self.returnType((type(a), tuple(shape)))

shape = tuple(shape)
if issubclass(stype, self.SecureFixedPointArray):
integral = all(a.integral if isinstance(a, stype) else stype(a).integral for a in tup)
await self.returnType((stype, integral, shape))
else:
await self.returnType((stype, shape))
tup = await self.gather(tup)
return np.vstack(tup)

Expand Down
39 changes: 39 additions & 0 deletions tests/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,33 @@ def test_secfxp_array(self):
u = mpc.np_unit_vector(secfxp(3), 7)
self.assertEqual(mpc.run(mpc.output(np.argmax(u))), 3)

# Test the integral property
a1 = np.array([[-1.5, 2.5], [4.5, -8.5]])
a2 = np.array([[-1, 2], [4, -8]])
c1 = secfxp.array(a1)
c2 = secfxp.array(a2)
self.assertEqual(c1.integral, False)
self.assertEqual(c2.integral, True)
self.assertEqual((c1 + c2).integral, False)
self.assertEqual(np.add(c2, c2).integral, True)
self.assertEqual((c1 * c2).integral, False)
self.assertEqual(np.multiply(c2, c2).integral, True)
self.assertEqual(np.matmul(c1, c2).integral, False)
self.assertEqual((c2 @ c2).integral, True)

self.assertEqual(np.hstack((c1, c2)).integral, False)
self.assertEqual(np.hstack((c1, c1)).integral, False)
self.assertEqual(np.hstack((c2, c2)).integral, True)
self.assertEqual(np.column_stack((c1, c2)).integral, False)
self.assertEqual(np.column_stack((c1, a1)).integral, False)
self.assertEqual(np.column_stack((c2, c2)).integral, True)
self.assertEqual(np.stack((c1, c2)).integral, False)
self.assertEqual(np.stack((c2, a1)).integral, False)
self.assertEqual(np.stack((c2, c2, a2)).integral, True)
self.assertEqual(np.vstack((c1, a2)).integral, False)
self.assertEqual(np.vstack((c1, c1)).integral, False)
self.assertEqual(np.vstack((c2, c2)).integral, True)

@unittest.skipIf(not np, 'NumPy not available or inside MPyC disabled')
def test_secfld_array(self):
np.assertEqual = np.testing.assert_array_equal
Expand Down Expand Up @@ -605,6 +632,18 @@ def test_secfxp(self):
c = mpc.run(mpc.output(mpc.to_bits(secfxp(-2**15))))
self.assertEqual(c, [0]*31 + [1])

# Test integral property
c1 = secfxp(8)
self.assertEqual(c1.integral, True)
self.assertEqual((c1*0.5).integral, False)
c2 = secfxp(1.5)
self.assertEqual(c2.integral, False)
self.assertEqual((c1*c2).integral, False)
self.assertEqual((c1+c2).integral, False)
c2 = secfxp(1)
self.assertEqual((c1*c2).integral, True)
self.assertEqual((c1+c2).integral, True)

for f in [8, 16, 32, 64]:
secfxp = mpc.SecFxp(2*f)
c = mpc.run(mpc.output(secfxp(1) + secfxp(1)))
Expand Down

0 comments on commit cd1a0a8

Please sign in to comment.