ladnir / aby3

A Three Party MPC framework for Machine learning and Databases
MIT License
190 stars 55 forks source link

Using SIMD and Multithreading #52

Open chart21 opened 2 months ago

chart21 commented 2 months ago

Does ABY have SIMD or Multithreading support? If so, how can I evaluate multiple inependent multiplications like in this example more efficiently? Also, what's the API for AND gates instead of Multiplication gates?

si64 prod = sharedVec[0]; task = runtime.noDependencies(); for (u64 i = 1; i < sharedVec.size(); ++i) task = eval.asyncMul(task, prod, sharedVec[i], prod);

task.get();
ladnir commented 2 months ago

No multithreading unless you manually do it. Just make everything independent and it should be fine.

You can concurrently execute multiple asyncMul. Do

for(....)
    task &=eval.asyncMul(runtime,...) 
task.get()

For simd, the library internally does simd operations of the matrices. So matrix matrix multiplication will be simd.

The multiplication protocol is also super simple so if you want something more custom that's also possible with a bit of code.

ladnir commented 2 months ago

For binary stuff you need to make a betacircuit of the computation you want to do and then evaluate that using the binaryEvaluator. See the unit tests.

chart21 commented 2 months ago

thanks for the swift reply. I assume by concurrently with task &= ... you mean there is still only one main computation thread but the communication of the different subtasks is handled concurrently.

I just want to evaluate multiple AND gates in parallel, similiar to the multiplication example. Is there a simple few-liner with a similiar API to mult? Also there seems to be a circuit to evaluate AES. Is there a benchmark to evaluate multiple AES circuits in parallel?

ladnir commented 2 months ago

so here is an exmaple https://github.com/ladnir/aby3/blob/master/aby3_tests/Sh3BinaryEvaluatorTests.cpp#L243

you define a binary circuit (BetaCircuit cir) that implements your function of interest, e.g. maybe just and AND gate of two inputs. You can the SIMD evaluate the same circuit on n inputs. You do this by setting the input as matricies with n rows. Each row will be evaluated independently.

task = eval.asyncEvaluate(task, cir, gen, { &A, &B }, { &C });

so this means that cir has two inputs, a and b and one output c. The call above will evaluate n copies of cir where each row of A,B,C are treated as an independent instance. The bit size of each row of A should be the bit size of a. Same for B,C.

Here are more examples of how to build circuits https://github.com/ladnir/cryptoTools/blob/master/tests_cryptoTools/Circuit_Tests.cpp.

BetaLibrary is a collection of useful circuits. The general ideal is that you declare BetaBundles which can be thought of as values within the circuit. You can use these values as input, intermidate (temporary), or output values.

chart21 commented 2 months ago

Thanks, integrating multithreading was straightforward and evaluating arithmetic functions with it. It seems there is only int64 and not int32 for secret values?

Unfortunately I didn't manage to get custom boolean circuits to run and the examples are a little bit too complex for me. How would I define for instance 1000 64-bit vectors A,B,C to perform C[i] = A[i] & B[i] with SIMD using the code snippet you mentioned?