Skip to content

Commit d755078

Browse files
committed
feat: Added examples for dot product and matrix multiplication
1 parent d3b5c7a commit d755078

File tree

11 files changed

+248
-1
lines changed

11 files changed

+248
-1
lines changed

examples/dot_product/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Dot Product Tutorial
2+
3+
This tutorial shows how to efficiently program a dot product in Nada using Nada Algebra.
4+
5+
```python
6+
from nada_dsl import *
7+
# Step 0: Nada Algebra is imported with this line
8+
import nada_algebra as na
9+
10+
11+
def nada_main():
12+
# Step 1: We use Nada Algebra wrapper to create "Party0", "Party1" and "Party2"
13+
parties = na.parties(3)
14+
15+
# Step 2: Party0 creates an array of dimension (3, ) with name "A"
16+
a = na.array([3], parties[0], "A")
17+
18+
# Step 3: Party1 creates an array of dimension (3, ) with name "B"
19+
b = na.array([3], parties[1], "B")
20+
21+
# Step 4: The result is of computing the dot product between the two
22+
result = a.dot(b)
23+
24+
# Step 5: We can use result.output() to produce the output for Party2 and variable name "my_output"
25+
return result.output(parties[1], "my_output")
26+
27+
```
28+
29+
0. We import Nada algebra using `import nada_algebra as na`.
30+
1. We create an array of parties, with our wrapper using `parties = na.parties(3)` which creates an array of parties named: `Party0`, `Party1` and `Party2`.
31+
2. We create our input array `a` with `na.array([3], parties[0], "A")`, meaning our array will have dimension 3, `Party0` will be in charge of giving its inputs and the name of the variable is `"A"`.
32+
3. We create our input array `b` with `na.array([3], parties[1], "B")`, meaning our array will have dimension 3, `Party1` will be in charge of giving its inputs and the name of the variable is `"B"`.
33+
4. Then, we use the `dot` function to compute the dot product like `a.dot(b)`, which will encompass all the functionality.
34+
5. Finally, we use Nada Algebra to produce the outputs of the array like: `result.output(parties[2], "my_output")` establishing that the output party will be `Party2`and the name of the output variable will be `my_output`.
35+
# How to run the tutorial.
36+
37+
1. First, we need to compile the nada program running: `nada build`.
38+
2. Then, we can test our program is running with: `nada test`.
39+
40+
Inspecting `tests/dot-product.yml`, we see how the inputs for the file are two vectors of 3s:
41+
42+
$$ A = (3, 3, 3), B = (3, 3, 3)$$
43+
And we obtain:
44+
$$A \times B = 3 \cdot 3 + 3 \cdot 3 + 3 \cdot 3 = 27$$
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name = "dot_product"
2+
version = "0.1.0"
3+
authors = [""]
4+
5+
[[programs]]
6+
path = "src/main.py"
7+
prime_size = 128

examples/dot_product/src/main.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from nada_dsl import *
2+
3+
# Step 0: Nada Algebra is imported with this line
4+
import nada_algebra as na
5+
6+
7+
def nada_main():
8+
# Step 1: We use Nada Algebra wrapper to create "Party0", "Party1" and "Party2"
9+
parties = na.parties(3)
10+
11+
# Step 2: Party0 creates an array of dimension (3, ) with name "A"
12+
a = na.array([3], parties[0], "A")
13+
14+
# Step 3: Party1 creates an array of dimension (3, ) with name "B"
15+
b = na.array([3], parties[1], "B")
16+
17+
# Step 4: The result is of computing the dot product between the two
18+
result = a.dot(b)
19+
20+
# Step 5: We can use result.output() to produce the output for Party2 and variable name "my_output"
21+
return result.output(parties[1], "my_output")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# This directory is kept purposely, so that no compilation errors arise.
2+
# Ignore everything in this directory
3+
*
4+
# Except this file
5+
!.gitignore
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
program: main
3+
inputs:
4+
secrets:
5+
A_0:
6+
SecretInteger: "3"
7+
A_1:
8+
SecretInteger: "3"
9+
A_2:
10+
SecretInteger: "3"
11+
B_0:
12+
SecretInteger: "3"
13+
B_1:
14+
SecretInteger: "3"
15+
B_2:
16+
SecretInteger: "3"
17+
public_variables: {}
18+
expected_outputs:
19+
my_output_0:
20+
SecretInteger: "27"
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Matrix Multiplication Tutorial
2+
3+
This tutorial shows how to efficiently program a matrix multiplication in Nada using Nada Algebra.
4+
5+
```python
6+
from nada_dsl import *
7+
# Step 0: Nada Algebra is imported with this line
8+
import nada_algebra as na
9+
10+
11+
def nada_main():
12+
# Step 1: We use Nada Algebra wrapper to create "Party0", "Party1" and "Party2"
13+
parties = na.parties(3)
14+
15+
# Step 2: Party0 creates an array of dimension (3 x 3) with name "A"
16+
a = na.array([3, 3], parties[0], "A")
17+
18+
# Step 3: Party1 creates an array of dimension (3 x 3) with name "B"
19+
b = na.array([3, 3], parties[1], "B")
20+
21+
# Step 4: The result is of computing the dot product between the two which is another (3 x 3) matrix
22+
result = a @ b
23+
24+
# Step 5: We can use result.output() to produce the output for Party2 and variable name "my_output"
25+
return result.output(parties[1], "my_output")
26+
27+
```
28+
29+
0. We import Nada algebra using `import nada_algebra as na`.
30+
1. We create an array of parties, with our wrapper using `parties = na.parties(3)` which creates an array of parties named: `Party0`, `Party1` and `Party2`.
31+
2. We create our input array `a` with `na.array([3], parties[0], "A")`, meaning our array will have dimension 3, `Party0` will be in charge of giving its inputs and the name of the variable is `"A"`.
32+
3. We create our input array `b` with `na.array([3], parties[1], "B")`, meaning our array will have dimension 3, `Party1` will be in charge of giving its inputs and the name of the variable is `"B"`.
33+
4. Then, we use the `dot` function to compute the dot product like `a.dot(b)`, which will encompass all the functionality.
34+
5. Finally, we use Nada Algebra to produce the outputs of the array like: `result.output(parties[2], "my_output")` establishing that the output party will be `Party2`and the name of the output variable will be `my_output`.
35+
36+
# How to Run the Tutorial
37+
38+
1. Start by compiling the Nada program using the command:
39+
```
40+
nada build
41+
```
42+
43+
2. Next, ensure that the program functions correctly by testing it with:
44+
```
45+
nada test
46+
```
47+
48+
Upon inspecting the `tests/matrix-multiplication.yml` file, you'll observe that the inputs consist of two matrices with dimensions (3 x 3):
49+
50+
$$
51+
A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}, \quad B = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}
52+
$$
53+
And we obtain an output matrix:
54+
55+
$$
56+
C = A \times B = \begin{pmatrix} 1 \cdot 1 + 2 \cdot 4 + 3 \cdot 7 & 1 \cdot 2 + 2 \cdot 5 + 3 \cdot 8 & 1 \cdot 3 + 2 \cdot 6 + 3 \cdot 9 \\ 4 \cdot 1 + 5 \cdot 4 + 6 \cdot 7 & 4 \cdot 2 + 5 \cdot 5 + 6 \cdot 8 & 4 \cdot 3 + 4 \cdot 6 + 6 \cdot 9 \\ 7 \cdot 1 + 8 \cdot 4 + 9 \cdot 7 & 7 \cdot 2 + 8 \cdot 5 + 9 \cdot 8 & 7 \cdot 3 + 8 \cdot 6 + 9 \cdot 9 \end{pmatrix} = \begin{pmatrix} 30 & 36 & 42 \\ 66 & 81 & 96 \\ 102 & 126 & 150 \end{pmatrix} $$
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name = "matrix_multiplication"
2+
version = "0.1.0"
3+
authors = [""]
4+
5+
[[programs]]
6+
path = "src/main.py"
7+
prime_size = 128
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from nada_dsl import *
2+
3+
# Step 0: Nada Algebra is imported with this line
4+
import nada_algebra as na
5+
6+
7+
def nada_main():
8+
# Step 1: We use Nada Algebra wrapper to create "Party0", "Party1" and "Party2"
9+
parties = na.parties(3)
10+
11+
# Step 2: Party0 creates an array of dimension (3 x 3) with name "A"
12+
a = na.array([3, 3], parties[0], "A")
13+
14+
# Step 3: Party1 creates an array of dimension (3 x 3) with name "B"
15+
b = na.array([3, 3], parties[1], "B")
16+
17+
# Step 4: The result is of computing the dot product between the two which is another (3 x 3) matrix
18+
result = a @ b
19+
20+
# Step 5: We can use result.output() to produce the output for Party2 and variable name "my_output"
21+
return result.output(parties[1], "my_output")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# This directory is kept purposely, so that no compilation errors arise.
2+
# Ignore everything in this directory
3+
*
4+
# Except this file
5+
!.gitignore
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
program: main
3+
inputs:
4+
secrets:
5+
A_0_0:
6+
SecretInteger: "1"
7+
A_0_1:
8+
SecretInteger: "2"
9+
A_0_2:
10+
SecretInteger: "3"
11+
A_1_0:
12+
SecretInteger: "4"
13+
A_1_1:
14+
SecretInteger: "5"
15+
A_1_2:
16+
SecretInteger: "6"
17+
A_2_0:
18+
SecretInteger: "7"
19+
A_2_1:
20+
SecretInteger: "8"
21+
A_2_2:
22+
SecretInteger: "9"
23+
B_0_0:
24+
SecretInteger: "1"
25+
B_0_1:
26+
SecretInteger: "2"
27+
B_0_2:
28+
SecretInteger: "3"
29+
B_1_0:
30+
SecretInteger: "4"
31+
B_1_1:
32+
SecretInteger: "5"
33+
B_1_2:
34+
SecretInteger: "6"
35+
B_2_0:
36+
SecretInteger: "7"
37+
B_2_1:
38+
SecretInteger: "8"
39+
B_2_2:
40+
SecretInteger: "9"
41+
public_variables: {}
42+
expected_outputs:
43+
my_output_0_0:
44+
SecretInteger: "30"
45+
my_output_0_1:
46+
SecretInteger: "36"
47+
my_output_0_2:
48+
SecretInteger: "42"
49+
my_output_1_0:
50+
SecretInteger: "66"
51+
my_output_1_1:
52+
SecretInteger: "81"
53+
my_output_1_2:
54+
SecretInteger: "96"
55+
my_output_2_0:
56+
SecretInteger: "102"
57+
my_output_2_1:
58+
SecretInteger: "126"
59+
my_output_2_2:
60+
SecretInteger: "150"

0 commit comments

Comments
 (0)