documentation
parent
5caf810448
commit
ddcae6a6c0
|
@ -0,0 +1,4 @@
|
|||
_build/
|
||||
xml/
|
||||
html/
|
||||
latex/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,24 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = python -msphinx
|
||||
SPHINXPROJ = percy
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
doxygen: ../include/percy/*.hpp
|
||||
doxygen Doxyfile
|
||||
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
html: doxygen Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
clean:
|
||||
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
@ -0,0 +1,8 @@
|
|||
Acknowledgments
|
||||
===============
|
||||
|
||||
The implementation of `percy` was inspired by Mathias Soeken's exact synthesis
|
||||
implementation in ABC_. A special thanks also goes out to Alan Mishchenko for
|
||||
inspiring discussions and ideas.
|
||||
|
||||
.. _ABC: https://github.com/berkeley-abc/abc
|
|
@ -0,0 +1,231 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# percy documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu May 10 16:18:11 2018.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['sphinx.ext.mathjax', 'breathe']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'percy'
|
||||
copyright = '2018, Winston Haaswijk'
|
||||
author = 'Winston Haaswijk'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1.2'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1.2'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# This is required for the alabaster theme
|
||||
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'relations.html', # needs 'show_related': True theme option to display
|
||||
'searchbox.html',
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'percydoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'percy.tex', 'percy Documentation',
|
||||
'Winston Haaswijk', 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'percy', 'percy Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'percy', 'percy Documentation',
|
||||
author, 'percy', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for breathe --------------------------------------------------
|
||||
|
||||
import subprocess, os
|
||||
|
||||
read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if read_the_docs_build:
|
||||
subprocess.call('doxygen Doxyfile', shell = True)
|
||||
|
||||
breathe_projects = {"percy": "xml"}
|
||||
breathe_default_project = "percy"
|
||||
|
||||
# -- Custom directives --------------------------------------------------
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import Directive
|
||||
from sphinx import addnodes
|
||||
|
||||
def extract_brief(tree, name):
|
||||
node = tree.findtext("./compounddef/sectiondef/memberdef/[name='%s']/briefdescription/para" % name)
|
||||
return node.strip() if node else "no brief description"
|
||||
|
||||
class DocBriefDirective(Directive):
|
||||
has_content = True
|
||||
def run(self):
|
||||
tree = self.state.document.settings.env.app.doxyxml
|
||||
return [nodes.line(text = extract_brief(tree, self.content[0].strip()))]
|
||||
|
||||
class DocBriefTableDirective(Directive):
|
||||
has_content = True
|
||||
def run(self):
|
||||
tree = self.state.document.settings.env.app.doxyxml
|
||||
table = nodes.table()
|
||||
tgroup = nodes.tgroup(cols = 2)
|
||||
tgroup += nodes.colspec(colwidth = 50)
|
||||
tgroup += nodes.colspec(colwidth = 50)
|
||||
# header
|
||||
tgroup += nodes.thead('', nodes.row('', *[nodes.entry('', nodes.line(text = c)) for c in ["Function", "Description"]]))
|
||||
# rows
|
||||
tbody = nodes.tbody()
|
||||
for c in self.content:
|
||||
name = c.strip()
|
||||
query = name.replace("&", " &")
|
||||
for elem in tree.findall("./compounddef/sectiondef/memberdef/[name='%s']" % query):
|
||||
args = ', '.join(e.text for e in elem.findall("./param/declname"))
|
||||
ref = addnodes.pending_xref('', refdomain = 'cpp', refexplicit = False, reftype = 'func', reftarget = 'percy::' + name)
|
||||
ref += nodes.literal(text = '%s(%s)' % (name, args))
|
||||
reft = nodes.paragraph()
|
||||
reft.extend([ref])
|
||||
func = nodes.entry('', reft)
|
||||
desc = nodes.entry('', nodes.line(text = elem.findtext("./briefdescription/para")))
|
||||
tbody += nodes.row('', func, desc)
|
||||
|
||||
tgroup += tbody
|
||||
table += tgroup
|
||||
|
||||
return [table]
|
||||
|
||||
def setup(app):
|
||||
import xml.etree.ElementTree as ET
|
||||
app.doxyxml = ET.parse("xml/namespacepercy.xml")
|
||||
app.add_directive('doc_brief', DocBriefDirective)
|
||||
app.add_directive('doc_brief_table', DocBriefTableDirective)
|
|
@ -0,0 +1,94 @@
|
|||
Examples
|
||||
============
|
||||
|
||||
Synthesis of an optimum full adder
|
||||
----------------------------------
|
||||
|
||||
In the following example, we show how `percy` can be used to synthesize an
|
||||
optimum full adder. While simple, the example shows some common interactions
|
||||
between the library's components.
|
||||
|
||||
.. code-black:: c++
|
||||
|
||||
spec spec;
|
||||
spec.verbosity = 0;
|
||||
|
||||
chain c;
|
||||
|
||||
dynamic_truth_table x( 3 ), y( 3 ), z( 3 );
|
||||
|
||||
create_nth_var( x, 0 );
|
||||
create_nth_var( y, 1 );
|
||||
create_nth_var( z, 2 );
|
||||
|
||||
// The sum and carry functions represent the outputs of the
|
||||
// chain that we want to synthesize.
|
||||
auto const sum = x ^ y ^ z;
|
||||
auto const carry = ternary_majority( x, y, z );
|
||||
spec[0] = sum;
|
||||
spec[1] = carry;
|
||||
|
||||
// Call the synthesizer with the specification we've constructed.
|
||||
auto const result = synthesize( spec, c );
|
||||
|
||||
// Ensure that synthesis was successful.
|
||||
assert( result == success );
|
||||
|
||||
// Simulate the synthesized circuit and ensure that it
|
||||
// computes the correct functions.
|
||||
auto sim_fs = c.simulate();
|
||||
assert( sim_fs[0] == sum );
|
||||
assert( sim_fs[1] == carry );
|
||||
|
||||
In this example, we synthesize a Boolean chain for a full adder
|
||||
specified by the two Boolean functions `sum` and `carry`. We see how
|
||||
synthesis is invoked using the `synthesize` function that takes two
|
||||
parameters. The first parameter is the specification `spec`, the
|
||||
second parameter `c` references a chain. If synthesis is successful,
|
||||
the `synthesize` function returns `success` and stores the synthesized
|
||||
chain in `c`. Last but not least, we simulate the chain to ensure
|
||||
that it's output functions are equivalent to the specified functions
|
||||
of the full adder.
|
||||
|
||||
Percy offers several different encodings and synthesis methods, and
|
||||
allows its users to select from various SAT solver backends. By
|
||||
default all engines use ABC's `bsat` solver backend [1]_
|
||||
(`SLV_BSAT2`), the SSV encoding (`ENC_SSV`), and the standard
|
||||
synthesis method (`SYNTH_STD`). Suppose that this particular
|
||||
combination is not suitable for our workflow. We can then easily
|
||||
customize the synthesis process by cherry-picking a solver, encoder,
|
||||
and synthesis method from the available options.
|
||||
|
||||
The next example demonstrates fence-based synthesis using the
|
||||
corresponding encoder and synthesis method together with ABC's `bsat`
|
||||
as solver backend:
|
||||
|
||||
.. code-black:: c++
|
||||
|
||||
percy::SolverType solver_type = percy::SLV_BSAT2;
|
||||
percy::EncoderType encoder_type = percy::ENC_FENCE;
|
||||
percy::SynthMethod synth_method = percy::SYNTH_FENCE;
|
||||
|
||||
auto solver = get_solver( solver_type );
|
||||
auto encoder = get_encoder( *solver, encoder_type );
|
||||
auto const result = synthesize( spec, c, *solver, *encoder, synth_method );
|
||||
|
||||
Enumerate (and count) partial DAGs
|
||||
----------------------------------
|
||||
|
||||
In the following code snippet, we use `percy` to enumerate partial
|
||||
DAGs for a given number of nodes (up to 7 nodes), count them, and
|
||||
print the numbers.
|
||||
|
||||
.. code-black:: c++
|
||||
|
||||
#include <percy/partial_dag.hpp>
|
||||
|
||||
for ( auto i = 1u; i < 8; ++i )
|
||||
{
|
||||
const auto dags = percy::pd_generate( i );
|
||||
std::cout << i << ' ' << dags.size() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
.. [1] https://github.com/berkeley-abc/abc
|
|
@ -0,0 +1,17 @@
|
|||
.. percy documentation master file, created by
|
||||
sphinx-quickstart on Thu May 10 16:18:11 2018.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to percy's documentation!
|
||||
=================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
introduction
|
||||
installation
|
||||
examples
|
||||
acknowledgments
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Installation
|
||||
============
|
||||
|
||||
Percy is a header-only library. As such, no build steps are required to start
|
||||
using it. Simply add ${PERCY_ROOT}/include to your compiler's include path and
|
||||
you're good to go. However, if you want to run the tests, you'll need to build
|
||||
some binaries.
|
||||
|
||||
The build instructions depend on your operating system. On Unix-like operating
|
||||
systems you will need either g++ (at least version 4.9.0) or clang++ (at least
|
||||
version 3.5.0). On Windows you can build using Visual Studio. (NOTE: This has
|
||||
been tested only with Visual Studio 2017.) Once those requirements are met, run
|
||||
the following commands to build and run the tests:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone --recurse-submodules https://github.com/whaaswijk/percy.git
|
||||
cd percy
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DPERCY_TEST=ON # Only on Unix
|
||||
cmake -DPERCY_TEST=ON -G "Visual Studio 15 2017" .. # On Windows
|
||||
make # Only on Unix
|
||||
make test # Only on Unix
|
||||
|
||||
On Unix systems this will build and run the test suite. On Windows it will
|
||||
generate a solution file which allows you to build and run the tests using
|
||||
Visual Studio.
|
|
@ -0,0 +1,53 @@
|
|||
Introduction
|
||||
============
|
||||
|
||||
The `percy` library provides a collection of SAT based exact synthesis engines.
|
||||
That includes engines based on conventional methods, as well as
|
||||
state-of-the-art engines which can take advantage of DAG topology information
|
||||
The aim of `percy` is to provide a flexible common interface that makes it easy
|
||||
to construct a parameterizable synthesis engine suitable for different domains.
|
||||
It is a header-only library, meaning that it can be used simply by including
|
||||
the percy/include folder in your project. Internally, `percy` uses the `kitty`
|
||||
library [#]_ to represent the truth tables of the functions to be synthesized.
|
||||
|
||||
Synthesis using `percy` concerns five main components:
|
||||
|
||||
1. *Specifications* -- Specification objects contain the information essential
|
||||
to the synthesis process such as which functions to synthesize, I/O
|
||||
information, and possibly optional parameters such as conflict limits for
|
||||
time-bound synthesis, or topology information.
|
||||
2. *Encoders* -- Encoders are objects which convert specifications to CNF
|
||||
formulae. There are various ways to create such encodings, and by
|
||||
separating their implementations it becomes simple to experiment with
|
||||
different encodings in various settings.
|
||||
3. *Solvers* -- Once an encoding has been created, we use a SAT solver to find
|
||||
a solution. Currently supported are ABC's `bsat` solver [#]_, the
|
||||
Glucose and Glucose-Syrup solvers, [#]_ and the CryptoMinisat solver. [#]_
|
||||
Adding a new solver to `percy` is as simple as declaring a handful of
|
||||
interface functions. [#]_
|
||||
4. *Synthesizers* -- Synthesizers perform the task of composing encoders and
|
||||
solvers. Different synthesizers correspond to different synthesis flows. For
|
||||
example, some synthesizers may support synthesis flows that use topological
|
||||
constraints, or allow for parallel synthesis flows. To perform synthesis
|
||||
using `percy`, one creates a synthesizer object. Synthesizers are
|
||||
parameterizable: we can change their encoder and solver backends. This
|
||||
happens at compile time, so there is no runtime overhead.
|
||||
5. *Chains* -- Boolean chains are the result of exact synthesis. A Boolean
|
||||
chain is a compact multi-level logic representation that can be used to
|
||||
represent multi-output Boolean functions.
|
||||
|
||||
A typical workflow will have some source for generating specifications, which
|
||||
are then given to a synthesizer that converts the specifications into optimum
|
||||
Boolean chains. Internally, the synthesizer will compose its underlying encoder
|
||||
and SAT solver in its specific synthesis flow. For example, a resynthesis
|
||||
algorithm might generate cuts in a logic network which serve as specifications.
|
||||
They are then fed to a synthesizer, and if the resulting optimum Boolean chains
|
||||
leads to an improvement, are replaced in the logic network. In optimizing this
|
||||
workflow, `percy` makes it easy to swap out one synthesis flow for another, to
|
||||
change CNF encodings, or to switch to a different SAT solver.
|
||||
|
||||
.. [#] https://github.com/msoeken/kitty
|
||||
.. [#] https://github.com/berkeley-abc/abc
|
||||
.. [#] http://www.labri.fr/perso/lsimon/glucose/
|
||||
.. [#] https://github.com/msoos/cryptominisat
|
||||
.. [#] Unfortunately some solvers may not compile on your favorite OS...
|
|
@ -0,0 +1 @@
|
|||
breathe
|
Loading…
Reference in New Issue