This folder contains a set of benchmarking procedures comparing Catalyst with PennyLane in various configurations.
-
Git-clone the Catalyst repository locally and follow the regular installation procedure.
-
Install the additional dependencies:
-
Python dependencies:
$ pip install --user -r benchmark/requirements.txt
-
LaTeX dependencies:
texlivepackage needs to be installed using the system package manager.
-
-
Add the
benchmarkfolder to thePYTHONPATH:# From the Catalyst folder $ export PYTHONPATH=$(pwd)/benchmark:$PYTHONPATH
-
Optionally, run the self-check:
$ python3 -m catalyst_benchmark.main selfcheck
-
Run the
./batchrun.py.$ python3 batchrun.py --tag=today --timeout-1run=4000
- The data is collected incrementally.
- Data collection and post-processing operations could be separated using the
-a|--actionargument. Thecollectandplotoperations are supported. - If the script is not running on the same machine that was used to collect the data, call the
plotaction with the-H|--force-sysinfo-hasharguemnt specifying the measurement system's sysinfo hash.
-
Render the report by copying the
./tex/report_template.tex, adjusting the measurement tag and/or the system information hash, adding comments and finally running thesh/mkpdflatex.shrendering script.$ cp ./tex/report_template.tex ./tex/report.tex $ $EDITOR ./tex/report.tex # ... edit `\SYSHASH`, `\TAG`, etc. $ ./sh/mkpdflatex.sh ./tex/report.tex
Grab the
./tex/report.pdf.
-
./benchmark.pymeasures a specific time value in a fixed configuration as specified by its command line arguemnts. The full command has the following structure:$ python3 benchmark.py run \ -p PROBLEM -m MEASURE -i IMPLEMENTATION \ <problem-specific-options>
Passing ? to -p,-m or -i prints the list of supported parameters.
The IMPLEMENTATION field has the following format:
(pennylane[+jax]|catalyst)/(device_name)
Examples:
$ python3 benchmark.py run -p grover -m compile -i pennylane+jax/default.qubit.jax
$ python3 benchmark.py run -p chemvqe -m runtime -i catalyst/lightning.qubit-
In order to add a new problem, one typically needs to provide its
CatalystandPennylaneimplementations as separate files in thetest_casessubfolder. Each implementation should export the following global entities:-
A subclass of the
Problemclass with thetrial_paramsmethod:from .types import Problem class MyProblem(Problem): def __init__(self, dev, params, **qnode_kwargs): super().__init__(dev, **qnode_kwargs) # Access `self.nqubits` to scale the problem # Access `params` to scale the problem # Initialize the problem-specific state def trial_params(self, i:int)->Any: """ Return problem-specific parameters for the trial `i`. The result type is typically a `pnp.array` or `jnp.array`. """ # Initialize the problem parameters return pnp.array(....) # or `jnp.array(...)`
-
The
qcompilefunction matching the following signature:def qcompile(p:Problem, params:NumpyArray) -> NoneThe function is expected to compile the quantum parts of the problem.
-
The
workflowfunction matching the following signature:def workflow(p:Problem, params:NumpyArray) -> NumpyArray -
Optionally, the
depthfunction, calculating the depth of the problem circuits in quantum gates.
Here,
NumpyArrayis typically anp.array,pnp.arrayorjnp.array, depending on the implementation. -
-
Modify each of the
measurements.measure_{compile,runtime}_{catalyst,pennylane,pennylanejax}functions defined inmain.py(currently there are six functions). Themain.pymodule generally uses the following pattern for performing the measurements:import framework from .test_cases.my_problem import Problem, qcompile, workflow p = Problem(qp.device(...), ...) def _main(params): qcompile(p, params) return algorithm(p, params) compiled_main = framework.compile(_main) for i in range(ntrials): params = p.trial_params(i) b = time() compiled_main(params) e = time()
-
Modify the
measurements.selfcheckfunction, compare the numeric results across the the implementations.