Skip to content

Commit

Permalink
Merge pull request #287 from april-tools/sos-notebook
Browse files Browse the repository at this point in the history
SOS circuits notebook
  • Loading branch information
loreloc authored Oct 12, 2024
2 parents 8635ebc + 59fe8c3 commit b7addab
Show file tree
Hide file tree
Showing 7 changed files with 1,051 additions and 239 deletions.
14 changes: 9 additions & 5 deletions cirkit/templates/circuit_templates/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ def image_data(
*,
input_layer: str,
num_input_units: int,
input_params: dict[str, Parameterization],
sum_product_layer: str,
num_sum_units: int,
sum_weight_param: Parameterization,
sum_weight_param: Parameterization | None = {},
input_params: dict[str, Parameterization] | None = {},
) -> Circuit:
"""Constructs a symbolic circuit whose structure is tailored for image data sets.
Expand All @@ -36,8 +36,6 @@ def image_data(
'binomial' (encoding a Binomial distribution over pixel channel values),
'embedding' (encoding an Embedding vector over pixel channel values).
num_input_units: The number of input units per input layer.
input_params: A dictionary mapping each name of a parameter of the input layer to
its parameterization.
sum_product_layer: The name of the sum-product inner layer. It can be one of the following:
'cp' (the canonical decomposition layer, consisting of dense layers followed by a
hadamard product layer), 'cpt' (the transposed canonical decomposition layer, consisting
Expand All @@ -46,7 +44,11 @@ def image_data(
layer).
num_sum_units: The number of sum units in each sum layer, i.e., either dense or mixing
layer.
sum_weight_param: The parameterization to use for sum layers parameters.
input_params: A dictionary mapping each name of a parameter of the input layer to
its parameterization. If it is None, then the default parameterization of the chosen
input layer will be chosen.
sum_weight_param: The parameterization to use for sum layers parameters. If it None,
then a softmax parameterization of the sum weights will be used.
Returns:
Circuit: A symbolic circuit.
Expand Down Expand Up @@ -86,6 +88,8 @@ def image_data(
input_factory = name_to_input_layer_factory(input_layer, **input_kwargs)

# Get the sum weight factory
if sum_weight_param is None:
sum_weight_param = Parameterization(activation="softmax", initialization="normal")
sum_weight_factory = parameterization_to_factory(sum_weight_param)

# Build and return the symbolic circuit
Expand Down
4 changes: 4 additions & 0 deletions notebooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ graph TD;
A[<a href='https://github.com/april-tools/cirkit/blob/main/notebooks/learning-a-circuit.ipynb'>Learning a circuit</a>]-->B[<a href='https://github.com/april-tools/cirkit/blob/main/notebooks/compilation-options.ipynb'>Compilation Options</a>];
A-->C[<a href='https://github.com/april-tools/cirkit/blob/main/notebooks/region-graphs-and-parametrisation.ipynb'>Region Graphs and Parametrisation</a>];
A-->D[<a href='https://github.com/april-tools/cirkit/blob/main/notebooks/learning-a-circuit-with-pic.ipynb'>Probabilistic Integral Circuits</a>];
B-->E[<a href='https://github.com/april-tools/cirkit/blob/main/notebooks/sum-of-squares-circuits.ipynb'>Sum of Squares Circuits</a>];
C-->E;
```

48 changes: 28 additions & 20 deletions notebooks/compilation-options.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
" num_input_units=64, # Each input layer consists of 64 Categorical input units\n",
" sum_product_layer='tucker', # Use Tucker sum-product layers, i.e., alternate dense sum layers and kronecker product layers\n",
" num_sum_units=64, # Each dense sum layer consists of 64 sum units\n",
" sum_weight_param='softmax' # Parameterize the weights of dense sum layers with 'softmax'\n",
" sum_weight_param=circuit_templates.Parameterization(\n",
" activation='softmax', # Parameterize the sum weights by using a softmax activation\n",
" initialization='normal' # Initialize the sum weights by sampling from a standard normal distribution\n",
" )\n",
")"
]
},
Expand Down Expand Up @@ -175,9 +178,10 @@
"ctx = PipelineContext(\n",
" backend='torch', # Use the PyTorch backend\n",
" # Specify the backend compilation flags next\n",
" semiring='lse-sum', # Specify how to evaluate sum and product layers\n",
" # In this case we use the numerically-stable 'lse-sum' semiring (R, +, *), i.e.,\n",
" # ---- Specify how to evaluate sum and product layers ---- #\n",
" semiring='lse-sum', # In this case we use the numerically-stable 'lse-sum' semiring (R, +, *), i.e.,\n",
" # where: + is the log-sum-exp operation, and * is the sum operation.\n",
" # -------------------------------------------------------- #\n",
")"
]
},
Expand All @@ -199,8 +203,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 3.26 s, sys: 505 ms, total: 3.77 s\n",
"Wall time: 3.67 s\n"
"CPU times: user 4.57 s, sys: 950 ms, total: 5.52 s\n",
"Wall time: 5.45 s\n"
]
}
],
Expand Down Expand Up @@ -269,7 +273,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"892 ms ± 6.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
"1.2 s ± 14.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
Expand Down Expand Up @@ -310,7 +314,9 @@
" backend='torch', # Use the PyTorch backend\n",
" # Specify the backend compilation flags next\n",
" semiring='lse-sum', # Use the 'lse-sum' semiring\n",
" fold=True, # <---- Enable folding\n",
" # --------- Enable circuit folding ---------- #\n",
" fold=True,\n",
" # ------------------------------------------- #\n",
")"
]
},
Expand All @@ -332,8 +338,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 3.49 s, sys: 400 ms, total: 3.89 s\n",
"Wall time: 3.79 s\n"
"CPU times: user 4.48 s, sys: 991 ms, total: 5.47 s\n",
"Wall time: 5.39 s\n"
]
}
],
Expand All @@ -357,7 +363,7 @@
"id": "d16615fd-38e8-4b7f-b03b-8e30502ce965",
"metadata": {},
"source": [
"Note that the compilation procedure took just a little more time, when compared to the compilation with the default compilation options shown above. In addition, we compare the number of layers of an \"unfolded\" circuits with the number of layers of a \"folded\" circuit."
"Note that the compilation procedure took a similar amount of time, when compared to the compilation with the default compilation options shown above. In addition, we compare the number of layers of an \"unfolded\" circuits with the number of layers of a \"folded\" circuit."
]
},
{
Expand Down Expand Up @@ -414,7 +420,7 @@
"id": "f074e168-dee4-4234-8eae-afd28fae317f",
"metadata": {},
"source": [
"As we see in the next code snippet, enabling folding provided an (approximately) **13.6x speed-up** for feed-forward circuit evaluations."
"As we see in the next code snippet, enabling folding provided an (approximately) **20x speed-up** for feed-forward circuit evaluations."
]
},
{
Expand All @@ -427,7 +433,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"65.5 ms ± 24.8 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
"60 ms ± 15.5 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
]
}
],
Expand Down Expand Up @@ -496,8 +502,10 @@
" backend='torch', # Use the PyTorch backend\n",
" # Specify the backend compilation flags next\n",
" semiring='lse-sum', # Use the 'lse-sum' semiring\n",
" fold=True, # Enable folding\n",
" optimize=True, # <---- Enable layer optimizations\n",
" fold=True, # Enable circuit folding\n",
" # -------- Enable layer optimizations -------- #\n",
" optimize=True,\n",
" # -------------------------------------------- #\n",
")"
]
},
Expand All @@ -519,8 +527,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 3.57 s, sys: 374 ms, total: 3.94 s\n",
"Wall time: 3.84 s\n"
"CPU times: user 4.81 s, sys: 876 ms, total: 5.68 s\n",
"Wall time: 5.61 s\n"
]
}
],
Expand Down Expand Up @@ -583,7 +591,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"33.9 ms ± 99.9 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
"26.7 ms ± 15.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
]
}
],
Expand All @@ -600,13 +608,13 @@
"id": "11d95c02-2c66-4414-b676-0dec303f2aa9",
"metadata": {},
"source": [
"Note that, we achieved an (approximately) **1.9x speed-up**, when compared to the folded circuit compiled above, and an (approximately) **26.3x speed-up**, when compared to the circuit compiled with no folding and no optimizations."
"Note that, we achieved an (approximately) **2.2x speed-up**, when compared to the folded circuit compiled above, and an (approximately) **44.9x speed-up**, when compared to the circuit compiled with no folding and no optimizations."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f3ed0fc0-31b9-428a-ab51-81e7ad7f2e96",
"id": "ae5edd97-7c99-4f7f-a581-402ddf80763c",
"metadata": {},
"outputs": [],
"source": []
Expand All @@ -628,7 +636,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
97 changes: 77 additions & 20 deletions notebooks/learning-a-circuit-with-pic.ipynb

Large diffs are not rendered by default.

Loading

0 comments on commit b7addab

Please sign in to comment.