data61 / MP-SPDZ

Versatile framework for multi-party computation
Other
895 stars 278 forks source link

Shamir-party.x Matrices #616

Closed RHG101997 closed 2 years ago

RHG101997 commented 2 years ago

Hello, I was benchmarking several of the function for matrix multiplication in Shamir.

M = input0 * input1

M = input0.dot(input1, n_threads=4) 

input0.plain_mul(input1)

M = input0.direct_mul_to_matrix(input1)
  1. Those are the ones I found. Am I missing any other methods of multiplying Matrices?
  2. Do you know which function should be the fastest one? In my experiments is .dot() just want to compare.
mkskeller commented 2 years ago

All but plain_mul() use the same method, which is the fastest one by design as it is implemented directly in the virtual machine. You should find that dot() behaves the same when run with one thread. I can't think of any other methods.

RHG101997 commented 2 years ago

Thanks for answers

I am assuming by the same methods you mean using the instructions: MATMULS or MATMULSM. If so could you point out where (file) these methods are defined? I found them in the Processor/Instructions but they are defined as an enum, I don't see where they call the dot_product.

Thank you for your time

mkskeller commented 2 years ago

They are defined starting at this line: https://github.com/data61/MP-SPDZ/blob/0d642822378bbd6f65bbf63478d3b076cd065d05/Processor/Processor.hpp#L501

RHG101997 commented 2 years ago

They are defined starting at this line:

https://github.com/data61/MP-SPDZ/blob/0d642822378bbd6f65bbf63478d3b076cd065d05/Processor/Processor.hpp#L501

Thank you,

One last thing. I have been using the high-level interface to do the timers. Is there a way I can add the same timers to check the matrix multiplication without accounting for the time used for communication (protocol.exchange()). In other words, just measure the computation when matmuls is running. I notice there are many debugging flags maybe one of the can help?

Thanks you for your time.

mkskeller commented 2 years ago

Not directly but you can run with -v and then subtract the communication times listed from the total time.

RHG101997 commented 2 years ago

Not directly but you can run with -v and then subtract the communication times listed from the total time.

Oka Thanks.

When I am multiplying a matrix 1024 x 1024. I get 1024 virtual machine rounds when I compile. Is it correct to assume that each round here is a dot product?

mkskeller commented 2 years ago

Yes if using the less efficient method. The efficient method should actually generate no rounds in this figure because it is not considered for the round optimization in the compiler.

RHG101997 commented 2 years ago

Thanks, ok so VM runs the matrix multiplication it will just do everything locally, and then execute .exchange() and this is the only communication round required.

I want to input a matrix using the Client input mentioned in the Documentation.

  1. Is there any function that helps get several inputs at once or should I just use for_range() and loop over all the inputs and save it to Matrix.
  2. Will the NumPy array will not work in the .mpc scripts because the compilation and execution are at different times? correct?
mkskeller commented 2 years ago
  1. You can use sfix.input_tensor_from_client(): https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.types.sfix.input_tensor_from_client
  2. Yes, correct.
RHG101997 commented 2 years ago
  1. You can use sfix.input_tensor_from_client()

I see, I tried using this I am getting the following error with this code:

image

The code:

myclient.py

import sys

sys.path.append('.')

from client import *
from domains import *

client_id = int(sys.argv[1])
n_parties = int(sys.argv[2])

client = Client(['localhost'] * n_parties, 14000, client_id)

# received from server
type = client.specification.get_int(4)

if type == ord('R'):
    domain = Z2(client.specification.get_int(4))
elif type == ord('p'):
    domain = Fp(client.specification.get_bigint())
else:
    raise Exception('invalid type')
# 6x6 matrix values
x = [1, 2, 3, 4, 5, 6,7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18,19, 20, 21, 22, 23, 24,25, 26, 27, 28, 29, 30,31, 32, 33, 34, 35, 36]
d_x = [domain(i) for i in x]
client.send_private_inputs(d_x)

in_tensor.mpc

# Input matrix to MP-SPDZ
PORTNUM = 14000
listen_for_clients(PORTNUM)
client_id = accept_client_connection(PORTNUM)
print_ln("Now getting input")
matrix = sfix.input_tensor_from_client(client_id, [6,6])
print_ln("Finishing")
closeclientconnection(client_id)
mkskeller commented 2 years ago

Thank you for raising this. You should find that 1bbbcd2770 fixes it.

RHG101997 commented 2 years ago

Thanks, it works now.

RHG101997 commented 2 years ago

Hello again, I am trying to multiply two 128x128 matrices using CCD/Shamir. I am compiling using ./compile.py -B 64 mult

image

matrix1.dot(matrix2, n_threads= 1)

Is this problem related to Memory?

Note: When I run a 32x32 multiplication it works flawlessly.

mkskeller commented 2 years ago

Thank you for raising this. I've found a number of bugs including correctness, which should all be fixed in 81419ba32180c62c07e3033f7eab7c4f810b7184. Did you see correct results for smaller matrices?

RHG101997 commented 2 years ago

Thank you for the fixes, I did not check the correctness of small matrices.

I tried running the small matrices again before applying your fix, but I seem to be having trouble printing the matrix using print_reveal_nested(). When compiling without -B 32 it compiles fine.

image

RHG101997 commented 2 years ago
  1. You can use sfix.input_tensor_from_client(): https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.types.sfix.input_tensor_from_client
  2. Yes, correct.

To Convert a Tensor to Matrix, I am using Tensor as you suggested is there any function already built in that allows me to do this.

mkskeller commented 2 years ago

Most matrix functionality is available for tensors. If you need to convert, use Matrix(x.sizes[0], x.sizes[1], x.value_type, address=x.address) for a tensor x.

RHG101997 commented 2 years ago

Thank you

mkskeller commented 2 years ago

I tried running the small matrices again before applying your fix, but I seem to be having trouble printing the matrix using print_reveal_nested(). When compiling without -B 32 it compiles fine.

image

This should be fixed in 91960440f578909bc5f06f05ca42f7edc6d1c7ad.

RHG101997 commented 2 years ago

Thanks