├── LICENSE ├── Makefile ├── Makefile.in ├── README.md ├── compile.py ├── config ├── Aspen1_M.rlb ├── Aspen1_S.rlb ├── Aspen1_T.rlb ├── Aspen3_M.rlb ├── Aspen3_S.rlb ├── Aspen3_T.rlb ├── RM4x8_M.rlb ├── RM4x8_S.rlb ├── RM4x8_T.rlb ├── RM8x16_M.rlb ├── RM8x16_S.rlb ├── RM8x16_T.rlb ├── RM8x8_M.rlb ├── RM8x8_S.rlb ├── RM8x8_T.rlb ├── RM8x9_M.rlb ├── RM8x9_S.rlb ├── RM8x9_T.rlb ├── agave_M.rlb ├── agave_S.rlb ├── agave_T.rlb ├── cmd_notes.txt ├── dummy_M.rlb ├── dummy_S.rlb ├── dummy_T.rlb ├── ibmq_16_melbourne_M.rlb ├── ibmq_16_melbourne_S.rlb ├── ibmq_16_melbourne_T.rlb ├── ibmqx4_M.rlb ├── ibmqx4_S.rlb ├── ibmqx4_T.rlb ├── ibmqx5_M.rlb ├── ibmqx5_S.rlb ├── ibmqx5_T.rlb ├── patterns.txt ├── tion_M.rlb ├── tion_S.rlb └── tion_T.rlb ├── configure.ac ├── ir2dag.py └── src ├── backtrack.cpp ├── backtrack.hpp ├── circuit.cpp ├── circuit.hpp ├── expt.cpp ├── gate.cpp ├── gate.hpp ├── headers.hpp ├── machine.cpp ├── machine.hpp ├── mapper.cpp ├── mapper.hpp ├── optimize_1q.cpp ├── optimize_1q.hpp ├── pattern.cpp ├── pattern.hpp ├── quaternion.cpp ├── quaternion.hpp ├── qubit.hpp ├── targetter.cpp └── targetter.hpp /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2019, prakashmurali 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=g++ 2 | Z3INCLUDE= 3 | CXXFLAGS=-I$(Z3INCLUDE) -std=c++11 4 | 5 | src = $(wildcard src/*.cpp) 6 | obj = $(src:.cpp=.o) 7 | 8 | LDFLAGS = -lz3 -lboost_system 9 | 10 | %.o: %.c 11 | $(CC) $(CXXFLAGS) -o $@ -c $< 12 | 13 | triq: $(obj) 14 | $(CC) -o $@ $^ $(LDFLAGS) 15 | 16 | .PHONY: clean 17 | clean: 18 | rm -f $(obj) triq 19 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in generated by automake 1.13.4 from Makefile.am. 2 | # @configure_input@ 3 | 4 | # Copyright (C) 1994-2013 Free Software Foundation, Inc. 5 | 6 | # This Makefile.in is free software; the Free Software Foundation 7 | # gives unlimited permission to copy and/or distribute it, 8 | # with or without modifications, as long as this notice is preserved. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 12 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. 14 | 15 | @SET_MAKE@ 16 | 17 | VPATH = @srcdir@ 18 | am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' 19 | am__make_running_with_option = \ 20 | case $${target_option-} in \ 21 | ?) ;; \ 22 | *) echo "am__make_running_with_option: internal error: invalid" \ 23 | "target option '$${target_option-}' specified" >&2; \ 24 | exit 1;; \ 25 | esac; \ 26 | has_opt=no; \ 27 | sane_makeflags=$$MAKEFLAGS; \ 28 | if $(am__is_gnu_make); then \ 29 | sane_makeflags=$$MFLAGS; \ 30 | else \ 31 | case $$MAKEFLAGS in \ 32 | *\\[\ \ ]*) \ 33 | bs=\\; \ 34 | sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ 35 | | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ 36 | esac; \ 37 | fi; \ 38 | skip_next=no; \ 39 | strip_trailopt () \ 40 | { \ 41 | flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ 42 | }; \ 43 | for flg in $$sane_makeflags; do \ 44 | test $$skip_next = yes && { skip_next=no; continue; }; \ 45 | case $$flg in \ 46 | *=*|--*) continue;; \ 47 | -*I) strip_trailopt 'I'; skip_next=yes;; \ 48 | -*I?*) strip_trailopt 'I';; \ 49 | -*O) strip_trailopt 'O'; skip_next=yes;; \ 50 | -*O?*) strip_trailopt 'O';; \ 51 | -*l) strip_trailopt 'l'; skip_next=yes;; \ 52 | -*l?*) strip_trailopt 'l';; \ 53 | -[dEDm]) skip_next=yes;; \ 54 | -[JT]) skip_next=yes;; \ 55 | esac; \ 56 | case $$flg in \ 57 | *$$target_option*) has_opt=yes; break;; \ 58 | esac; \ 59 | done; \ 60 | test $$has_opt = yes 61 | am__make_dryrun = (target_option=n; $(am__make_running_with_option)) 62 | am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 63 | pkgdatadir = $(datadir)/@PACKAGE@ 64 | pkgincludedir = $(includedir)/@PACKAGE@ 65 | pkglibdir = $(libdir)/@PACKAGE@ 66 | pkglibexecdir = $(libexecdir)/@PACKAGE@ 67 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 68 | install_sh_DATA = $(install_sh) -c -m 644 69 | install_sh_PROGRAM = $(install_sh) -c 70 | install_sh_SCRIPT = $(install_sh) -c 71 | INSTALL_HEADER = $(INSTALL_DATA) 72 | transform = $(program_transform_name) 73 | NORMAL_INSTALL = : 74 | PRE_INSTALL = : 75 | POST_INSTALL = : 76 | NORMAL_UNINSTALL = : 77 | PRE_UNINSTALL = : 78 | POST_UNINSTALL = : 79 | bin_PROGRAMS = triq$(EXEEXT) 80 | subdir = . 81 | DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ 82 | $(top_srcdir)/configure $(am__configure_deps) depcomp \ 83 | install-sh missing 84 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 85 | am__aclocal_m4_deps = $(top_srcdir)/configure.ac 86 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 87 | $(ACLOCAL_M4) 88 | am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ 89 | configure.lineno config.status.lineno 90 | mkinstalldirs = $(install_sh) -d 91 | CONFIG_CLEAN_FILES = 92 | CONFIG_CLEAN_VPATH_FILES = 93 | am__installdirs = "$(DESTDIR)$(bindir)" 94 | PROGRAMS = $(bin_PROGRAMS) 95 | am_triq_OBJECTS = triq-backtrack.$(OBJEXT) triq-circuit.$(OBJEXT) \ 96 | triq-expt.$(OBJEXT) triq-gate.$(OBJEXT) triq-machine.$(OBJEXT) \ 97 | triq-mapper.$(OBJEXT) triq-optimize_1q.$(OBJEXT) \ 98 | triq-pattern.$(OBJEXT) triq-quaternion.$(OBJEXT) \ 99 | triq-targetter.$(OBJEXT) 100 | triq_OBJECTS = $(am_triq_OBJECTS) 101 | triq_LDADD = $(LDADD) 102 | triq_LINK = $(CXXLD) $(triq_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ 103 | $(LDFLAGS) -o $@ 104 | AM_V_P = $(am__v_P_@AM_V@) 105 | am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) 106 | am__v_P_0 = false 107 | am__v_P_1 = : 108 | AM_V_GEN = $(am__v_GEN_@AM_V@) 109 | am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) 110 | am__v_GEN_0 = @echo " GEN " $@; 111 | am__v_GEN_1 = 112 | AM_V_at = $(am__v_at_@AM_V@) 113 | am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) 114 | am__v_at_0 = @ 115 | am__v_at_1 = 116 | DEFAULT_INCLUDES = -I.@am__isrc@ 117 | depcomp = $(SHELL) $(top_srcdir)/depcomp 118 | am__depfiles_maybe = depfiles 119 | am__mv = mv -f 120 | AM_V_lt = $(am__v_lt_@AM_V@) 121 | am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 122 | am__v_lt_0 = --silent 123 | am__v_lt_1 = 124 | CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ 125 | $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 126 | AM_V_CXX = $(am__v_CXX_@AM_V@) 127 | am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) 128 | am__v_CXX_0 = @echo " CXX " $@; 129 | am__v_CXX_1 = 130 | CXXLD = $(CXX) 131 | CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ 132 | -o $@ 133 | AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) 134 | am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) 135 | am__v_CXXLD_0 = @echo " CXXLD " $@; 136 | am__v_CXXLD_1 = 137 | SOURCES = $(triq_SOURCES) 138 | DIST_SOURCES = $(triq_SOURCES) 139 | am__can_run_installinfo = \ 140 | case $$AM_UPDATE_INFO_DIR in \ 141 | n|no|NO) false;; \ 142 | *) (install-info --version) >/dev/null 2>&1;; \ 143 | esac 144 | am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 145 | # Read a list of newline-separated strings from the standard input, 146 | # and print each of them once, without duplicates. Input order is 147 | # *not* preserved. 148 | am__uniquify_input = $(AWK) '\ 149 | BEGIN { nonempty = 0; } \ 150 | { items[$$0] = 1; nonempty = 1; } \ 151 | END { if (nonempty) { for (i in items) print i; }; } \ 152 | ' 153 | # Make sure the list of sources is unique. This is necessary because, 154 | # e.g., the same source file might be shared among _SOURCES variables 155 | # for different programs/libraries. 156 | am__define_uniq_tagged_files = \ 157 | list='$(am__tagged_files)'; \ 158 | unique=`for i in $$list; do \ 159 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 160 | done | $(am__uniquify_input)` 161 | ETAGS = etags 162 | CTAGS = ctags 163 | CSCOPE = cscope 164 | AM_RECURSIVE_TARGETS = cscope 165 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 166 | distdir = $(PACKAGE)-$(VERSION) 167 | top_distdir = $(distdir) 168 | am__remove_distdir = \ 169 | if test -d "$(distdir)"; then \ 170 | find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ 171 | && rm -rf "$(distdir)" \ 172 | || { sleep 5 && rm -rf "$(distdir)"; }; \ 173 | else :; fi 174 | am__post_remove_distdir = $(am__remove_distdir) 175 | DIST_ARCHIVES = $(distdir).tar.gz 176 | GZIP_ENV = --best 177 | DIST_TARGETS = dist-gzip 178 | distuninstallcheck_listfiles = find . -type f -print 179 | am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ 180 | | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' 181 | distcleancheck_listfiles = find . -type f -print 182 | ACLOCAL = @ACLOCAL@ 183 | AMTAR = @AMTAR@ 184 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 185 | AUTOCONF = @AUTOCONF@ 186 | AUTOHEADER = @AUTOHEADER@ 187 | AUTOMAKE = @AUTOMAKE@ 188 | AWK = @AWK@ 189 | CPPFLAGS = @CPPFLAGS@ 190 | CXX = @CXX@ 191 | CXXDEPMODE = @CXXDEPMODE@ 192 | CXXFLAGS = @CXXFLAGS@ 193 | CYGPATH_W = @CYGPATH_W@ 194 | DEFS = @DEFS@ 195 | DEPDIR = @DEPDIR@ 196 | ECHO_C = @ECHO_C@ 197 | ECHO_N = @ECHO_N@ 198 | ECHO_T = @ECHO_T@ 199 | EXEEXT = @EXEEXT@ 200 | INSTALL = @INSTALL@ 201 | INSTALL_DATA = @INSTALL_DATA@ 202 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ 203 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 204 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 205 | LDFLAGS = @LDFLAGS@ 206 | LIBOBJS = @LIBOBJS@ 207 | LIBS = @LIBS@ 208 | LTLIBOBJS = @LTLIBOBJS@ 209 | MAKEINFO = @MAKEINFO@ 210 | MKDIR_P = @MKDIR_P@ 211 | OBJEXT = @OBJEXT@ 212 | PACKAGE = @PACKAGE@ 213 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ 214 | PACKAGE_NAME = @PACKAGE_NAME@ 215 | PACKAGE_STRING = @PACKAGE_STRING@ 216 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ 217 | PACKAGE_URL = @PACKAGE_URL@ 218 | PACKAGE_VERSION = @PACKAGE_VERSION@ 219 | PATH_SEPARATOR = @PATH_SEPARATOR@ 220 | SET_MAKE = @SET_MAKE@ 221 | SHELL = @SHELL@ 222 | STRIP = @STRIP@ 223 | VERSION = @VERSION@ 224 | abs_builddir = @abs_builddir@ 225 | abs_srcdir = @abs_srcdir@ 226 | abs_top_builddir = @abs_top_builddir@ 227 | abs_top_srcdir = @abs_top_srcdir@ 228 | ac_ct_CXX = @ac_ct_CXX@ 229 | am__include = @am__include@ 230 | am__leading_dot = @am__leading_dot@ 231 | am__quote = @am__quote@ 232 | am__tar = @am__tar@ 233 | am__untar = @am__untar@ 234 | bindir = @bindir@ 235 | build_alias = @build_alias@ 236 | builddir = @builddir@ 237 | datadir = @datadir@ 238 | datarootdir = @datarootdir@ 239 | docdir = @docdir@ 240 | dvidir = @dvidir@ 241 | exec_prefix = @exec_prefix@ 242 | host_alias = @host_alias@ 243 | htmldir = @htmldir@ 244 | includedir = @includedir@ 245 | infodir = @infodir@ 246 | install_sh = @install_sh@ 247 | libdir = @libdir@ 248 | libexecdir = @libexecdir@ 249 | localedir = @localedir@ 250 | localstatedir = @localstatedir@ 251 | mandir = @mandir@ 252 | mkdir_p = @mkdir_p@ 253 | oldincludedir = @oldincludedir@ 254 | pdfdir = @pdfdir@ 255 | prefix = @prefix@ 256 | program_transform_name = @program_transform_name@ 257 | psdir = @psdir@ 258 | sbindir = @sbindir@ 259 | sharedstatedir = @sharedstatedir@ 260 | srcdir = @srcdir@ 261 | sysconfdir = @sysconfdir@ 262 | target_alias = @target_alias@ 263 | top_build_prefix = @top_build_prefix@ 264 | top_builddir = @top_builddir@ 265 | top_srcdir = @top_srcdir@ 266 | AUTOMAKE_OPTIONS = foreign 267 | triq_SOURCES = src/backtrack.cpp src/circuit.cpp src/expt.cpp src/gate.cpp src/machine.cpp src/mapper.cpp src/optimize_1q.cpp src/pattern.cpp src/quaternion.cpp src/targetter.cpp 268 | AM_LDFLAGS = -lz3 -lboost_system$(BOOST_LIB_SUFFIX) 269 | triq_CXXFLAGS = -std=c++11 270 | all: all-am 271 | 272 | .SUFFIXES: 273 | .SUFFIXES: .cpp .o .obj 274 | am--refresh: Makefile 275 | @: 276 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 277 | @for dep in $?; do \ 278 | case '$(am__configure_deps)' in \ 279 | *$$dep*) \ 280 | echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ 281 | $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ 282 | && exit 0; \ 283 | exit 1;; \ 284 | esac; \ 285 | done; \ 286 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ 287 | $(am__cd) $(top_srcdir) && \ 288 | $(AUTOMAKE) --foreign Makefile 289 | .PRECIOUS: Makefile 290 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 291 | @case '$?' in \ 292 | *config.status*) \ 293 | echo ' $(SHELL) ./config.status'; \ 294 | $(SHELL) ./config.status;; \ 295 | *) \ 296 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ 297 | cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ 298 | esac; 299 | 300 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 301 | $(SHELL) ./config.status --recheck 302 | 303 | $(top_srcdir)/configure: $(am__configure_deps) 304 | $(am__cd) $(srcdir) && $(AUTOCONF) 305 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) 306 | $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) 307 | $(am__aclocal_m4_deps): 308 | install-binPROGRAMS: $(bin_PROGRAMS) 309 | @$(NORMAL_INSTALL) 310 | @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ 311 | if test -n "$$list"; then \ 312 | echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ 313 | $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ 314 | fi; \ 315 | for p in $$list; do echo "$$p $$p"; done | \ 316 | sed 's/$(EXEEXT)$$//' | \ 317 | while read p p1; do if test -f $$p \ 318 | ; then echo "$$p"; echo "$$p"; else :; fi; \ 319 | done | \ 320 | sed -e 'p;s,.*/,,;n;h' \ 321 | -e 's|.*|.|' \ 322 | -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ 323 | sed 'N;N;N;s,\n, ,g' | \ 324 | $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ 325 | { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ 326 | if ($$2 == $$4) files[d] = files[d] " " $$1; \ 327 | else { print "f", $$3 "/" $$4, $$1; } } \ 328 | END { for (d in files) print "f", d, files[d] }' | \ 329 | while read type dir files; do \ 330 | if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ 331 | test -z "$$files" || { \ 332 | echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ 333 | $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ 334 | } \ 335 | ; done 336 | 337 | uninstall-binPROGRAMS: 338 | @$(NORMAL_UNINSTALL) 339 | @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ 340 | files=`for p in $$list; do echo "$$p"; done | \ 341 | sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ 342 | -e 's/$$/$(EXEEXT)/' \ 343 | `; \ 344 | test -n "$$list" || exit 0; \ 345 | echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ 346 | cd "$(DESTDIR)$(bindir)" && rm -f $$files 347 | 348 | clean-binPROGRAMS: 349 | -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) 350 | 351 | triq$(EXEEXT): $(triq_OBJECTS) $(triq_DEPENDENCIES) $(EXTRA_triq_DEPENDENCIES) 352 | @rm -f triq$(EXEEXT) 353 | $(AM_V_CXXLD)$(triq_LINK) $(triq_OBJECTS) $(triq_LDADD) $(LIBS) 354 | 355 | mostlyclean-compile: 356 | -rm -f *.$(OBJEXT) 357 | 358 | distclean-compile: 359 | -rm -f *.tab.c 360 | 361 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-backtrack.Po@am__quote@ 362 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-circuit.Po@am__quote@ 363 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-expt.Po@am__quote@ 364 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-gate.Po@am__quote@ 365 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-machine.Po@am__quote@ 366 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-mapper.Po@am__quote@ 367 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-optimize_1q.Po@am__quote@ 368 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-pattern.Po@am__quote@ 369 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-quaternion.Po@am__quote@ 370 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triq-targetter.Po@am__quote@ 371 | 372 | .cpp.o: 373 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< 374 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 375 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 376 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 377 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< 378 | 379 | .cpp.obj: 380 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` 381 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 382 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 383 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 384 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 385 | 386 | triq-backtrack.o: src/backtrack.cpp 387 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-backtrack.o -MD -MP -MF $(DEPDIR)/triq-backtrack.Tpo -c -o triq-backtrack.o `test -f 'src/backtrack.cpp' || echo '$(srcdir)/'`src/backtrack.cpp 388 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-backtrack.Tpo $(DEPDIR)/triq-backtrack.Po 389 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/backtrack.cpp' object='triq-backtrack.o' libtool=no @AMDEPBACKSLASH@ 390 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 391 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-backtrack.o `test -f 'src/backtrack.cpp' || echo '$(srcdir)/'`src/backtrack.cpp 392 | 393 | triq-backtrack.obj: src/backtrack.cpp 394 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-backtrack.obj -MD -MP -MF $(DEPDIR)/triq-backtrack.Tpo -c -o triq-backtrack.obj `if test -f 'src/backtrack.cpp'; then $(CYGPATH_W) 'src/backtrack.cpp'; else $(CYGPATH_W) '$(srcdir)/src/backtrack.cpp'; fi` 395 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-backtrack.Tpo $(DEPDIR)/triq-backtrack.Po 396 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/backtrack.cpp' object='triq-backtrack.obj' libtool=no @AMDEPBACKSLASH@ 397 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 398 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-backtrack.obj `if test -f 'src/backtrack.cpp'; then $(CYGPATH_W) 'src/backtrack.cpp'; else $(CYGPATH_W) '$(srcdir)/src/backtrack.cpp'; fi` 399 | 400 | triq-circuit.o: src/circuit.cpp 401 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-circuit.o -MD -MP -MF $(DEPDIR)/triq-circuit.Tpo -c -o triq-circuit.o `test -f 'src/circuit.cpp' || echo '$(srcdir)/'`src/circuit.cpp 402 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-circuit.Tpo $(DEPDIR)/triq-circuit.Po 403 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/circuit.cpp' object='triq-circuit.o' libtool=no @AMDEPBACKSLASH@ 404 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 405 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-circuit.o `test -f 'src/circuit.cpp' || echo '$(srcdir)/'`src/circuit.cpp 406 | 407 | triq-circuit.obj: src/circuit.cpp 408 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-circuit.obj -MD -MP -MF $(DEPDIR)/triq-circuit.Tpo -c -o triq-circuit.obj `if test -f 'src/circuit.cpp'; then $(CYGPATH_W) 'src/circuit.cpp'; else $(CYGPATH_W) '$(srcdir)/src/circuit.cpp'; fi` 409 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-circuit.Tpo $(DEPDIR)/triq-circuit.Po 410 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/circuit.cpp' object='triq-circuit.obj' libtool=no @AMDEPBACKSLASH@ 411 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 412 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-circuit.obj `if test -f 'src/circuit.cpp'; then $(CYGPATH_W) 'src/circuit.cpp'; else $(CYGPATH_W) '$(srcdir)/src/circuit.cpp'; fi` 413 | 414 | triq-expt.o: src/expt.cpp 415 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-expt.o -MD -MP -MF $(DEPDIR)/triq-expt.Tpo -c -o triq-expt.o `test -f 'src/expt.cpp' || echo '$(srcdir)/'`src/expt.cpp 416 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-expt.Tpo $(DEPDIR)/triq-expt.Po 417 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/expt.cpp' object='triq-expt.o' libtool=no @AMDEPBACKSLASH@ 418 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 419 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-expt.o `test -f 'src/expt.cpp' || echo '$(srcdir)/'`src/expt.cpp 420 | 421 | triq-expt.obj: src/expt.cpp 422 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-expt.obj -MD -MP -MF $(DEPDIR)/triq-expt.Tpo -c -o triq-expt.obj `if test -f 'src/expt.cpp'; then $(CYGPATH_W) 'src/expt.cpp'; else $(CYGPATH_W) '$(srcdir)/src/expt.cpp'; fi` 423 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-expt.Tpo $(DEPDIR)/triq-expt.Po 424 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/expt.cpp' object='triq-expt.obj' libtool=no @AMDEPBACKSLASH@ 425 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 426 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-expt.obj `if test -f 'src/expt.cpp'; then $(CYGPATH_W) 'src/expt.cpp'; else $(CYGPATH_W) '$(srcdir)/src/expt.cpp'; fi` 427 | 428 | triq-gate.o: src/gate.cpp 429 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-gate.o -MD -MP -MF $(DEPDIR)/triq-gate.Tpo -c -o triq-gate.o `test -f 'src/gate.cpp' || echo '$(srcdir)/'`src/gate.cpp 430 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-gate.Tpo $(DEPDIR)/triq-gate.Po 431 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/gate.cpp' object='triq-gate.o' libtool=no @AMDEPBACKSLASH@ 432 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 433 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-gate.o `test -f 'src/gate.cpp' || echo '$(srcdir)/'`src/gate.cpp 434 | 435 | triq-gate.obj: src/gate.cpp 436 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-gate.obj -MD -MP -MF $(DEPDIR)/triq-gate.Tpo -c -o triq-gate.obj `if test -f 'src/gate.cpp'; then $(CYGPATH_W) 'src/gate.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gate.cpp'; fi` 437 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-gate.Tpo $(DEPDIR)/triq-gate.Po 438 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/gate.cpp' object='triq-gate.obj' libtool=no @AMDEPBACKSLASH@ 439 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 440 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-gate.obj `if test -f 'src/gate.cpp'; then $(CYGPATH_W) 'src/gate.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gate.cpp'; fi` 441 | 442 | triq-machine.o: src/machine.cpp 443 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-machine.o -MD -MP -MF $(DEPDIR)/triq-machine.Tpo -c -o triq-machine.o `test -f 'src/machine.cpp' || echo '$(srcdir)/'`src/machine.cpp 444 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-machine.Tpo $(DEPDIR)/triq-machine.Po 445 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/machine.cpp' object='triq-machine.o' libtool=no @AMDEPBACKSLASH@ 446 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 447 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-machine.o `test -f 'src/machine.cpp' || echo '$(srcdir)/'`src/machine.cpp 448 | 449 | triq-machine.obj: src/machine.cpp 450 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-machine.obj -MD -MP -MF $(DEPDIR)/triq-machine.Tpo -c -o triq-machine.obj `if test -f 'src/machine.cpp'; then $(CYGPATH_W) 'src/machine.cpp'; else $(CYGPATH_W) '$(srcdir)/src/machine.cpp'; fi` 451 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-machine.Tpo $(DEPDIR)/triq-machine.Po 452 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/machine.cpp' object='triq-machine.obj' libtool=no @AMDEPBACKSLASH@ 453 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 454 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-machine.obj `if test -f 'src/machine.cpp'; then $(CYGPATH_W) 'src/machine.cpp'; else $(CYGPATH_W) '$(srcdir)/src/machine.cpp'; fi` 455 | 456 | triq-mapper.o: src/mapper.cpp 457 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-mapper.o -MD -MP -MF $(DEPDIR)/triq-mapper.Tpo -c -o triq-mapper.o `test -f 'src/mapper.cpp' || echo '$(srcdir)/'`src/mapper.cpp 458 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-mapper.Tpo $(DEPDIR)/triq-mapper.Po 459 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/mapper.cpp' object='triq-mapper.o' libtool=no @AMDEPBACKSLASH@ 460 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 461 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-mapper.o `test -f 'src/mapper.cpp' || echo '$(srcdir)/'`src/mapper.cpp 462 | 463 | triq-mapper.obj: src/mapper.cpp 464 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-mapper.obj -MD -MP -MF $(DEPDIR)/triq-mapper.Tpo -c -o triq-mapper.obj `if test -f 'src/mapper.cpp'; then $(CYGPATH_W) 'src/mapper.cpp'; else $(CYGPATH_W) '$(srcdir)/src/mapper.cpp'; fi` 465 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-mapper.Tpo $(DEPDIR)/triq-mapper.Po 466 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/mapper.cpp' object='triq-mapper.obj' libtool=no @AMDEPBACKSLASH@ 467 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 468 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-mapper.obj `if test -f 'src/mapper.cpp'; then $(CYGPATH_W) 'src/mapper.cpp'; else $(CYGPATH_W) '$(srcdir)/src/mapper.cpp'; fi` 469 | 470 | triq-optimize_1q.o: src/optimize_1q.cpp 471 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-optimize_1q.o -MD -MP -MF $(DEPDIR)/triq-optimize_1q.Tpo -c -o triq-optimize_1q.o `test -f 'src/optimize_1q.cpp' || echo '$(srcdir)/'`src/optimize_1q.cpp 472 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-optimize_1q.Tpo $(DEPDIR)/triq-optimize_1q.Po 473 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/optimize_1q.cpp' object='triq-optimize_1q.o' libtool=no @AMDEPBACKSLASH@ 474 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 475 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-optimize_1q.o `test -f 'src/optimize_1q.cpp' || echo '$(srcdir)/'`src/optimize_1q.cpp 476 | 477 | triq-optimize_1q.obj: src/optimize_1q.cpp 478 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-optimize_1q.obj -MD -MP -MF $(DEPDIR)/triq-optimize_1q.Tpo -c -o triq-optimize_1q.obj `if test -f 'src/optimize_1q.cpp'; then $(CYGPATH_W) 'src/optimize_1q.cpp'; else $(CYGPATH_W) '$(srcdir)/src/optimize_1q.cpp'; fi` 479 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-optimize_1q.Tpo $(DEPDIR)/triq-optimize_1q.Po 480 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/optimize_1q.cpp' object='triq-optimize_1q.obj' libtool=no @AMDEPBACKSLASH@ 481 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 482 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-optimize_1q.obj `if test -f 'src/optimize_1q.cpp'; then $(CYGPATH_W) 'src/optimize_1q.cpp'; else $(CYGPATH_W) '$(srcdir)/src/optimize_1q.cpp'; fi` 483 | 484 | triq-pattern.o: src/pattern.cpp 485 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-pattern.o -MD -MP -MF $(DEPDIR)/triq-pattern.Tpo -c -o triq-pattern.o `test -f 'src/pattern.cpp' || echo '$(srcdir)/'`src/pattern.cpp 486 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-pattern.Tpo $(DEPDIR)/triq-pattern.Po 487 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/pattern.cpp' object='triq-pattern.o' libtool=no @AMDEPBACKSLASH@ 488 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 489 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-pattern.o `test -f 'src/pattern.cpp' || echo '$(srcdir)/'`src/pattern.cpp 490 | 491 | triq-pattern.obj: src/pattern.cpp 492 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-pattern.obj -MD -MP -MF $(DEPDIR)/triq-pattern.Tpo -c -o triq-pattern.obj `if test -f 'src/pattern.cpp'; then $(CYGPATH_W) 'src/pattern.cpp'; else $(CYGPATH_W) '$(srcdir)/src/pattern.cpp'; fi` 493 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-pattern.Tpo $(DEPDIR)/triq-pattern.Po 494 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/pattern.cpp' object='triq-pattern.obj' libtool=no @AMDEPBACKSLASH@ 495 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 496 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-pattern.obj `if test -f 'src/pattern.cpp'; then $(CYGPATH_W) 'src/pattern.cpp'; else $(CYGPATH_W) '$(srcdir)/src/pattern.cpp'; fi` 497 | 498 | triq-quaternion.o: src/quaternion.cpp 499 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-quaternion.o -MD -MP -MF $(DEPDIR)/triq-quaternion.Tpo -c -o triq-quaternion.o `test -f 'src/quaternion.cpp' || echo '$(srcdir)/'`src/quaternion.cpp 500 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-quaternion.Tpo $(DEPDIR)/triq-quaternion.Po 501 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/quaternion.cpp' object='triq-quaternion.o' libtool=no @AMDEPBACKSLASH@ 502 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 503 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-quaternion.o `test -f 'src/quaternion.cpp' || echo '$(srcdir)/'`src/quaternion.cpp 504 | 505 | triq-quaternion.obj: src/quaternion.cpp 506 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-quaternion.obj -MD -MP -MF $(DEPDIR)/triq-quaternion.Tpo -c -o triq-quaternion.obj `if test -f 'src/quaternion.cpp'; then $(CYGPATH_W) 'src/quaternion.cpp'; else $(CYGPATH_W) '$(srcdir)/src/quaternion.cpp'; fi` 507 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-quaternion.Tpo $(DEPDIR)/triq-quaternion.Po 508 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/quaternion.cpp' object='triq-quaternion.obj' libtool=no @AMDEPBACKSLASH@ 509 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 510 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-quaternion.obj `if test -f 'src/quaternion.cpp'; then $(CYGPATH_W) 'src/quaternion.cpp'; else $(CYGPATH_W) '$(srcdir)/src/quaternion.cpp'; fi` 511 | 512 | triq-targetter.o: src/targetter.cpp 513 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-targetter.o -MD -MP -MF $(DEPDIR)/triq-targetter.Tpo -c -o triq-targetter.o `test -f 'src/targetter.cpp' || echo '$(srcdir)/'`src/targetter.cpp 514 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-targetter.Tpo $(DEPDIR)/triq-targetter.Po 515 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/targetter.cpp' object='triq-targetter.o' libtool=no @AMDEPBACKSLASH@ 516 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 517 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-targetter.o `test -f 'src/targetter.cpp' || echo '$(srcdir)/'`src/targetter.cpp 518 | 519 | triq-targetter.obj: src/targetter.cpp 520 | @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -MT triq-targetter.obj -MD -MP -MF $(DEPDIR)/triq-targetter.Tpo -c -o triq-targetter.obj `if test -f 'src/targetter.cpp'; then $(CYGPATH_W) 'src/targetter.cpp'; else $(CYGPATH_W) '$(srcdir)/src/targetter.cpp'; fi` 521 | @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/triq-targetter.Tpo $(DEPDIR)/triq-targetter.Po 522 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/targetter.cpp' object='triq-targetter.obj' libtool=no @AMDEPBACKSLASH@ 523 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 524 | @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(triq_CXXFLAGS) $(CXXFLAGS) -c -o triq-targetter.obj `if test -f 'src/targetter.cpp'; then $(CYGPATH_W) 'src/targetter.cpp'; else $(CYGPATH_W) '$(srcdir)/src/targetter.cpp'; fi` 525 | 526 | ID: $(am__tagged_files) 527 | $(am__define_uniq_tagged_files); mkid -fID $$unique 528 | tags: tags-am 529 | TAGS: tags 530 | 531 | tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 532 | set x; \ 533 | here=`pwd`; \ 534 | $(am__define_uniq_tagged_files); \ 535 | shift; \ 536 | if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ 537 | test -n "$$unique" || unique=$$empty_fix; \ 538 | if test $$# -gt 0; then \ 539 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ 540 | "$$@" $$unique; \ 541 | else \ 542 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ 543 | $$unique; \ 544 | fi; \ 545 | fi 546 | ctags: ctags-am 547 | 548 | CTAGS: ctags 549 | ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 550 | $(am__define_uniq_tagged_files); \ 551 | test -z "$(CTAGS_ARGS)$$unique" \ 552 | || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ 553 | $$unique 554 | 555 | GTAGS: 556 | here=`$(am__cd) $(top_builddir) && pwd` \ 557 | && $(am__cd) $(top_srcdir) \ 558 | && gtags -i $(GTAGS_ARGS) "$$here" 559 | cscope: cscope.files 560 | test ! -s cscope.files \ 561 | || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) 562 | clean-cscope: 563 | -rm -f cscope.files 564 | cscope.files: clean-cscope cscopelist 565 | cscopelist: cscopelist-am 566 | 567 | cscopelist-am: $(am__tagged_files) 568 | list='$(am__tagged_files)'; \ 569 | case "$(srcdir)" in \ 570 | [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ 571 | *) sdir=$(subdir)/$(srcdir) ;; \ 572 | esac; \ 573 | for i in $$list; do \ 574 | if test -f "$$i"; then \ 575 | echo "$(subdir)/$$i"; \ 576 | else \ 577 | echo "$$sdir/$$i"; \ 578 | fi; \ 579 | done >> $(top_builddir)/cscope.files 580 | 581 | distclean-tags: 582 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags 583 | -rm -f cscope.out cscope.in.out cscope.po.out cscope.files 584 | 585 | distdir: $(DISTFILES) 586 | $(am__remove_distdir) 587 | test -d "$(distdir)" || mkdir "$(distdir)" 588 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 589 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 590 | list='$(DISTFILES)'; \ 591 | dist_files=`for file in $$list; do echo $$file; done | \ 592 | sed -e "s|^$$srcdirstrip/||;t" \ 593 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ 594 | case $$dist_files in \ 595 | */*) $(MKDIR_P) `echo "$$dist_files" | \ 596 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ 597 | sort -u` ;; \ 598 | esac; \ 599 | for file in $$dist_files; do \ 600 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ 601 | if test -d $$d/$$file; then \ 602 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ 603 | if test -d "$(distdir)/$$file"; then \ 604 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 605 | fi; \ 606 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ 607 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ 608 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 609 | fi; \ 610 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ 611 | else \ 612 | test -f "$(distdir)/$$file" \ 613 | || cp -p $$d/$$file "$(distdir)/$$file" \ 614 | || exit 1; \ 615 | fi; \ 616 | done 617 | -test -n "$(am__skip_mode_fix)" \ 618 | || find "$(distdir)" -type d ! -perm -755 \ 619 | -exec chmod u+rwx,go+rx {} \; -o \ 620 | ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ 621 | ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ 622 | ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ 623 | || chmod -R a+r "$(distdir)" 624 | dist-gzip: distdir 625 | tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz 626 | $(am__post_remove_distdir) 627 | 628 | dist-bzip2: distdir 629 | tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 630 | $(am__post_remove_distdir) 631 | 632 | dist-lzip: distdir 633 | tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz 634 | $(am__post_remove_distdir) 635 | 636 | dist-xz: distdir 637 | tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz 638 | $(am__post_remove_distdir) 639 | 640 | dist-tarZ: distdir 641 | tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z 642 | $(am__post_remove_distdir) 643 | 644 | dist-shar: distdir 645 | shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz 646 | $(am__post_remove_distdir) 647 | 648 | dist-zip: distdir 649 | -rm -f $(distdir).zip 650 | zip -rq $(distdir).zip $(distdir) 651 | $(am__post_remove_distdir) 652 | 653 | dist dist-all: 654 | $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' 655 | $(am__post_remove_distdir) 656 | 657 | # This target untars the dist file and tries a VPATH configuration. Then 658 | # it guarantees that the distribution is self-contained by making another 659 | # tarfile. 660 | distcheck: dist 661 | case '$(DIST_ARCHIVES)' in \ 662 | *.tar.gz*) \ 663 | GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ 664 | *.tar.bz2*) \ 665 | bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ 666 | *.tar.lz*) \ 667 | lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ 668 | *.tar.xz*) \ 669 | xz -dc $(distdir).tar.xz | $(am__untar) ;;\ 670 | *.tar.Z*) \ 671 | uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ 672 | *.shar.gz*) \ 673 | GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ 674 | *.zip*) \ 675 | unzip $(distdir).zip ;;\ 676 | esac 677 | chmod -R a-w $(distdir) 678 | chmod u+w $(distdir) 679 | mkdir $(distdir)/_build $(distdir)/_inst 680 | chmod a-w $(distdir) 681 | test -d $(distdir)/_build || exit 0; \ 682 | dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ 683 | && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ 684 | && am__cwd=`pwd` \ 685 | && $(am__cd) $(distdir)/_build \ 686 | && ../configure --srcdir=.. --prefix="$$dc_install_base" \ 687 | $(AM_DISTCHECK_CONFIGURE_FLAGS) \ 688 | $(DISTCHECK_CONFIGURE_FLAGS) \ 689 | && $(MAKE) $(AM_MAKEFLAGS) \ 690 | && $(MAKE) $(AM_MAKEFLAGS) dvi \ 691 | && $(MAKE) $(AM_MAKEFLAGS) check \ 692 | && $(MAKE) $(AM_MAKEFLAGS) install \ 693 | && $(MAKE) $(AM_MAKEFLAGS) installcheck \ 694 | && $(MAKE) $(AM_MAKEFLAGS) uninstall \ 695 | && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ 696 | distuninstallcheck \ 697 | && chmod -R a-w "$$dc_install_base" \ 698 | && ({ \ 699 | (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ 700 | && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ 701 | && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ 702 | && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ 703 | distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ 704 | } || { rm -rf "$$dc_destdir"; exit 1; }) \ 705 | && rm -rf "$$dc_destdir" \ 706 | && $(MAKE) $(AM_MAKEFLAGS) dist \ 707 | && rm -rf $(DIST_ARCHIVES) \ 708 | && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ 709 | && cd "$$am__cwd" \ 710 | || exit 1 711 | $(am__post_remove_distdir) 712 | @(echo "$(distdir) archives ready for distribution: "; \ 713 | list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ 714 | sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' 715 | distuninstallcheck: 716 | @test -n '$(distuninstallcheck_dir)' || { \ 717 | echo 'ERROR: trying to run $@ with an empty' \ 718 | '$$(distuninstallcheck_dir)' >&2; \ 719 | exit 1; \ 720 | }; \ 721 | $(am__cd) '$(distuninstallcheck_dir)' || { \ 722 | echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ 723 | exit 1; \ 724 | }; \ 725 | test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ 726 | || { echo "ERROR: files left after uninstall:" ; \ 727 | if test -n "$(DESTDIR)"; then \ 728 | echo " (check DESTDIR support)"; \ 729 | fi ; \ 730 | $(distuninstallcheck_listfiles) ; \ 731 | exit 1; } >&2 732 | distcleancheck: distclean 733 | @if test '$(srcdir)' = . ; then \ 734 | echo "ERROR: distcleancheck can only run from a VPATH build" ; \ 735 | exit 1 ; \ 736 | fi 737 | @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ 738 | || { echo "ERROR: files left in build directory after distclean:" ; \ 739 | $(distcleancheck_listfiles) ; \ 740 | exit 1; } >&2 741 | check-am: all-am 742 | check: check-am 743 | all-am: Makefile $(PROGRAMS) 744 | installdirs: 745 | for dir in "$(DESTDIR)$(bindir)"; do \ 746 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ 747 | done 748 | install: install-am 749 | install-exec: install-exec-am 750 | install-data: install-data-am 751 | uninstall: uninstall-am 752 | 753 | install-am: all-am 754 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 755 | 756 | installcheck: installcheck-am 757 | install-strip: 758 | if test -z '$(STRIP)'; then \ 759 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 760 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 761 | install; \ 762 | else \ 763 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 764 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 765 | "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ 766 | fi 767 | mostlyclean-generic: 768 | 769 | clean-generic: 770 | 771 | distclean-generic: 772 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 773 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) 774 | 775 | maintainer-clean-generic: 776 | @echo "This command is intended for maintainers to use" 777 | @echo "it deletes files that may require special tools to rebuild." 778 | clean: clean-am 779 | 780 | clean-am: clean-binPROGRAMS clean-generic mostlyclean-am 781 | 782 | distclean: distclean-am 783 | -rm -f $(am__CONFIG_DISTCLEAN_FILES) 784 | -rm -rf ./$(DEPDIR) 785 | -rm -f Makefile 786 | distclean-am: clean-am distclean-compile distclean-generic \ 787 | distclean-tags 788 | 789 | dvi: dvi-am 790 | 791 | dvi-am: 792 | 793 | html: html-am 794 | 795 | html-am: 796 | 797 | info: info-am 798 | 799 | info-am: 800 | 801 | install-data-am: 802 | 803 | install-dvi: install-dvi-am 804 | 805 | install-dvi-am: 806 | 807 | install-exec-am: install-binPROGRAMS 808 | 809 | install-html: install-html-am 810 | 811 | install-html-am: 812 | 813 | install-info: install-info-am 814 | 815 | install-info-am: 816 | 817 | install-man: 818 | 819 | install-pdf: install-pdf-am 820 | 821 | install-pdf-am: 822 | 823 | install-ps: install-ps-am 824 | 825 | install-ps-am: 826 | 827 | installcheck-am: 828 | 829 | maintainer-clean: maintainer-clean-am 830 | -rm -f $(am__CONFIG_DISTCLEAN_FILES) 831 | -rm -rf $(top_srcdir)/autom4te.cache 832 | -rm -rf ./$(DEPDIR) 833 | -rm -f Makefile 834 | maintainer-clean-am: distclean-am maintainer-clean-generic 835 | 836 | mostlyclean: mostlyclean-am 837 | 838 | mostlyclean-am: mostlyclean-compile mostlyclean-generic 839 | 840 | pdf: pdf-am 841 | 842 | pdf-am: 843 | 844 | ps: ps-am 845 | 846 | ps-am: 847 | 848 | uninstall-am: uninstall-binPROGRAMS 849 | 850 | .MAKE: install-am install-strip 851 | 852 | .PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ 853 | clean-binPROGRAMS clean-cscope clean-generic cscope \ 854 | cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ 855 | dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ 856 | distcheck distclean distclean-compile distclean-generic \ 857 | distclean-tags distcleancheck distdir distuninstallcheck dvi \ 858 | dvi-am html html-am info info-am install install-am \ 859 | install-binPROGRAMS install-data install-data-am install-dvi \ 860 | install-dvi-am install-exec install-exec-am install-html \ 861 | install-html-am install-info install-info-am install-man \ 862 | install-pdf install-pdf-am install-ps install-ps-am \ 863 | install-strip installcheck installcheck-am installdirs \ 864 | maintainer-clean maintainer-clean-generic mostlyclean \ 865 | mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ 866 | tags tags-am uninstall uninstall-am uninstall-binPROGRAMS 867 | 868 | 869 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 870 | # Otherwise a system limit (for SysV at least) may be exceeded. 871 | .NOEXPORT: 872 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TriQ 2 | TriQ is the backend compiler for the [Scaffold](https://github.com/epiqc/ScaffCC) quantum programming language. TriQ takes two inputs: 1) a gate sequence produced by [ScaffCC](https://github.com/epiqc/ScaffCC) and 2) qubit connectivity and calibration data for the target machine. It compiles the program gate sequence by choosing a good initial placement of the program qubits on the hardware qubits, reducing communication, and by applying gate optimization techniques. 3 | 4 | # Supported Backends 5 | TriQ generates optimized quantum assembly code for both superconducting and ion trap quantum computers. We support the 14 and 5-qubit superconducting devices from IBM (IBMQ14, IBMQ5), the 16-qubit superconducting systems from Rigetti (Aspen1, Aspen3) and 5-qubit trapped ion system from University of Maryland. 6 | 7 | # Install 8 | Dependencies: 9 | 1. [ScaffCC](https://github.com/epiqc/ScaffCC) 10 | 2. [Z3 SMT Solver](https://github.com/Z3Prover/z3) 11 | 12 | To install TriQ, 13 | ``` 14 | make 15 | ``` 16 | 17 | # Compiling a program 18 | To run a program prog_name.scaffold with TriQ, first exract an intermediate representation using ScaffCC. 19 | ``` 20 | ./scaffold.sh -b prog_name.scaffold 21 | ``` 22 | Run TriQ on the intermediate representation 23 | ``` 24 | python ir2dag.py prog_name.qasm prog_name.in 25 | ./triq prog_name.in 26 | ``` 27 | For example, to compile programs for IBMQ5 28 | ``` 29 | ./triq prog_name.in prog_name.out ibmqx5 0 30 | ``` 31 | For each backend, TriQ assumes that the error data for single qubit, two-qubit and readout operations are specified in the config directory. For example, for IBMQ5, the Single qubit fidelity data should be specified in ibmqx5_S.rlb. Each line in this file specifies a qubit number and the corresponding fidelity. Two-qubit gate fidelity is specified in ibmqx5_T.rlb and readout fidelity is specified in ibmqx5_M.rlb. 32 | 33 | # Citing TriQ 34 | If you use TriQ in your work, we would appreciate it if you cite our paper: 35 | 36 | Prakash Murali, Jonathan M. Baker, Ali Javadi Abhari, Frederic T. Chong, Margaret Martonosi. "Noise-Adaptive Compiler Mappings for Noisy Intermediate-Scale Quantum Computers", International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS), 2019. 37 | 38 | # Questions 39 | Please reach out to Prakash Murali (pmurali@princeton.edu) for any questions or clarifications. 40 | 41 | # Coming Soon 42 | More compiler options and helper methods to extract reliablity data automatically from vendor APIs 43 | -------------------------------------------------------------------------------- /compile.py: -------------------------------------------------------------------------------- 1 | import subprocess as sp 2 | import sys 3 | import os 4 | scaffcc_path="" 5 | triq_path="" 6 | out_path="" 7 | 8 | out_file=open("compile.log",'w') 9 | sp.call([os.path.join(scaffcc_path, "scaffold.sh"), "-b", sys.argv[1]], stdout=out_file) 10 | base_name = ''.join(sys.argv[1].split('.')[:-1]) 11 | ir_name = base_name + ".qasm" 12 | dag_name = base_name + ".in" 13 | out_name = base_name + ".qasm" 14 | sp.call(["python3.6", "./ir2dag.py", ir_name, dag_name]) 15 | 16 | sp.call([os.path.join(triq_path, "triq"), os.path.join(triq_path, dag_name), os.path.join(triq_path, out_name), sys.argv[2], " 0 "]) 17 | 18 | -------------------------------------------------------------------------------- /config/Aspen1_M.rlb: -------------------------------------------------------------------------------- 1 | 16 2 | 0 0.751875 3 | 1 0.96375 4 | 2 0.88375 5 | 3 0.93375 6 | 4 0.93 7 | 5 0.935 8 | 6 0.8775 9 | 7 0.936875 10 | 8 0.943125 11 | 9 0.946875 12 | 10 0.961875 13 | 11 0.89375 14 | 12 0.789375 15 | 13 0.94875 16 | 14 0.956875 17 | 15 0.960625 18 | -------------------------------------------------------------------------------- /config/Aspen1_S.rlb: -------------------------------------------------------------------------------- 1 | 16 2 | 0 0.990036016774214 3 | 1 0.993943963963789 4 | 2 0.971805986990463 5 | 3 0.99218699312246 6 | 4 0.993345085664941 7 | 5 0.96246871992215 8 | 6 0.89024242564483 9 | 7 0.984462471230659 10 | 8 0.916224493149245 11 | 9 0.994354111796187 12 | 10 0.896491092641233 13 | 11 0.904262001604027 14 | 12 0.936786699141349 15 | 13 0.994849026358807 16 | 14 0.988947861468655 17 | 15 0.993350466846982 18 | -------------------------------------------------------------------------------- /config/Aspen1_T.rlb: -------------------------------------------------------------------------------- 1 | 18 2 | 0 1 0.926042142654435 3 | 0 7 0.875755822177262 4 | 1 2 0.914677142895931 5 | 1 14 0.939864086561327 6 | 2 3 0.908619720984457 7 | 2 13 0.860933502812637 8 | 3 4 0.914103985163264 9 | 4 5 0.887449413361492 10 | 5 6 0.869546236992959 11 | 6 7 0.634144797485517 12 | 8 9 0.929793777111282 13 | 8 15 0.949612320078891 14 | 9 10 0.945156534867354 15 | 10 11 0.923719742262139 16 | 11 12 0.96756836403617 17 | 12 13 0.949331866224858 18 | 13 14 0.959917114779525 19 | 14 15 0.963368592252726 20 | -------------------------------------------------------------------------------- /config/Aspen3_M.rlb: -------------------------------------------------------------------------------- 1 | 14 2 | 0 0.920625 3 | 1 0.951875 4 | 2 0.959375 5 | 3 0.96875 6 | 4 0.7275 7 | 5 0.9275 8 | 6 0.928125 9 | 7 0.9525 10 | 8 0.919375 11 | 9 0.875 12 | 10 0.96625 13 | 11 0.9675 14 | 12 0.886875 15 | 13 0.960625 16 | -------------------------------------------------------------------------------- /config/Aspen3_S.rlb: -------------------------------------------------------------------------------- 1 | 14 2 | 0 0.997639038569014 3 | 1 0.994505047711586 4 | 2 0.994390789411993 5 | 3 0.995869918305858 6 | 4 0.507337576681507 7 | 5 0.990176917209726 8 | 6 0.974709137480389 9 | 7 0.918701714079577 10 | 8 0.995615924987736 11 | 9 0.976735183050306 12 | 10 0.961869018380326 13 | 11 0.995277009986475 14 | 12 0.998116175741805 15 | 13 0.994404626419523 16 | -------------------------------------------------------------------------------- /config/Aspen3_T.rlb: -------------------------------------------------------------------------------- 1 | 14 2 | 0 1 0.91714235262854 3 | 1 2 0.986744255873061 4 | 1 13 0.959116095779811 5 | 2 3 0.912089307649727 6 | 2 12 0.971304264767521 7 | 3 4 0.871673913775573 8 | 4 5 0.806781873960501 9 | 5 6 0.923711451873435 10 | 7 8 0.933869547209638 11 | 8 9 0.95070221648953 12 | 9 10 0.93434200300695 13 | 10 11 0.988296244759261 14 | 11 12 0.929629052090299 15 | 12 13 0.959424144669611 16 | -------------------------------------------------------------------------------- /config/RM4x8_M.rlb: -------------------------------------------------------------------------------- 1 | 32 2 | 0 0.929 3 | 1 0.9612 4 | 2 0.9447 5 | 3 0.9513 6 | 4 0.8292 7 | 5 0.9246 8 | 6 0.878 9 | 7 0.915 10 | 8 0.8943 11 | 9 0.947 12 | 10 0.951 13 | 11 0.9572 14 | 12 0.9282 15 | 13 0.8049999999999999 16 | 14 0.9354 17 | 15 0.771 18 | 16 0.9532 19 | 17 0.8969 20 | 18 0.9625 21 | 19 0.9636 22 | 20 0.9390000000000001 23 | 21 0.938 24 | 22 0.95 25 | 23 0.956 26 | 24 0.9165 27 | 25 0.985 28 | 26 0.8376 29 | 27 0.9440999999999999 30 | 28 0.9574 31 | 29 0.9473 32 | 30 0.9546 33 | 31 0.9667 34 | -------------------------------------------------------------------------------- /config/RM4x8_S.rlb: -------------------------------------------------------------------------------- 1 | 32 2 | 0 1.0 3 | 1 1.0 4 | 2 1.0 5 | 3 1.0 6 | 4 1.0 7 | 5 1.0 8 | 6 1.0 9 | 7 1.0 10 | 8 1.0 11 | 9 1.0 12 | 10 1.0 13 | 11 1.0 14 | 12 1.0 15 | 13 1.0 16 | 14 1.0 17 | 15 1.0 18 | 16 1.0 19 | 17 1.0 20 | 18 1.0 21 | 19 1.0 22 | 20 1.0 23 | 21 1.0 24 | 22 1.0 25 | 23 1.0 26 | 24 1.0 27 | 25 1.0 28 | 26 1.0 29 | 27 1.0 30 | 28 1.0 31 | 29 1.0 32 | 30 1.0 33 | 31 1.0 34 | -------------------------------------------------------------------------------- /config/RM4x8_T.rlb: -------------------------------------------------------------------------------- 1 | 52 2 | 0 1 0.9203645666832193 3 | 0 8 0.9642249058248827 4 | 1 2 0.9616298545873704 5 | 1 9 0.9732941694954924 6 | 2 3 0.9581724240412404 7 | 2 10 0.9422136093225943 8 | 3 4 0.9732123926157534 9 | 3 11 0.954911920891093 10 | 4 5 0.7531680321103176 11 | 4 12 0.9562722413480252 12 | 5 6 0.9561574906632945 13 | 5 13 0.8805057729878931 14 | 6 7 0.9712347092792688 15 | 6 14 0.9525614255214003 16 | 7 15 0.9704914696574325 17 | 8 9 0.9629360860703255 18 | 8 16 0.9626158483783194 19 | 9 10 0.9576323073833486 20 | 9 17 0.9424287848751477 21 | 10 11 0.958180280233029 22 | 10 18 0.9713177727372168 23 | 11 12 0.9582124111304935 24 | 11 19 0.9741085754236691 25 | 12 13 0.9678530226667379 26 | 12 20 0.9557558547286774 27 | 13 14 0.955987678562134 28 | 13 21 0.9165001928335009 29 | 14 15 0.9596714380847826 30 | 14 22 0.9667101452374838 31 | 15 23 0.9636219123954424 32 | 16 17 0.9741764219089786 33 | 16 24 0.9557065982029833 34 | 17 18 0.9746084876657415 35 | 17 25 0.9720949275676245 36 | 18 19 0.9600749476302965 37 | 18 26 0.9722755168385802 38 | 19 20 0.9691200238956023 39 | 19 27 0.9460041407472426 40 | 20 21 0.9678042324318004 41 | 20 28 0.956852304633492 42 | 21 22 0.959269517774486 43 | 21 29 0.957665224679786 44 | 22 23 0.9729546983547157 45 | 22 30 0.9513289077894327 46 | 23 31 0.9569083100892734 47 | 24 25 0.9500634874519329 48 | 25 26 0.9371226655508308 49 | 26 27 0.9565318644085112 50 | 27 28 0.9552286375178111 51 | 28 29 0.9579252134393572 52 | 29 30 0.916361879302775 53 | 30 31 0.9582124111304935 54 | -------------------------------------------------------------------------------- /config/RM8x16_M.rlb: -------------------------------------------------------------------------------- 1 | 128 2 | 0 0.9144 3 | 1 0.9434 4 | 2 0.876 5 | 3 0.898 6 | 4 0.9442 7 | 5 0.766 8 | 6 0.9346000000000001 9 | 7 0.9582 10 | 8 0.9013 11 | 9 0.954 12 | 10 0.9373 13 | 11 0.8849 14 | 12 0.9189 15 | 13 0.9442999999999999 16 | 14 0.8817 17 | 15 0.9427000000000001 18 | 16 0.9062 19 | 17 0.6768000000000001 20 | 18 0.8829 21 | 19 0.9456 22 | 20 0.928 23 | 21 0.9246 24 | 22 0.872 25 | 23 0.9368000000000001 26 | 24 0.9440999999999999 27 | 25 0.9501999999999999 28 | 26 0.9118999999999999 29 | 27 0.9390000000000001 30 | 28 0.9293 31 | 29 0.9464 32 | 30 0.9459 33 | 31 0.9465 34 | 32 0.942 35 | 33 0.9612 36 | 34 0.9319999999999999 37 | 35 0.9651 38 | 36 0.9468000000000001 39 | 37 0.9025 40 | 38 0.9177 41 | 39 0.8932 42 | 40 0.888 43 | 41 0.946 44 | 42 0.8992 45 | 43 0.967 46 | 44 0.8682000000000001 47 | 45 0.942 48 | 46 0.942 49 | 47 0.8942 50 | 48 0.9199999999999999 51 | 49 0.9393 52 | 50 0.9069 53 | 51 0.876 54 | 52 0.9331 55 | 53 0.9570000000000001 56 | 54 0.9553 57 | 55 0.8817 58 | 56 0.9606 59 | 57 0.95 60 | 58 0.9534 61 | 59 0.9519 62 | 60 0.933 63 | 61 0.95 64 | 62 0.9422999999999999 65 | 63 0.9012 66 | 64 0.931 67 | 65 0.8785 68 | 66 0.9189 69 | 67 0.9410000000000001 70 | 68 0.8956 71 | 69 0.8815 72 | 70 0.8974 73 | 71 0.9387 74 | 72 0.943 75 | 73 0.9528 76 | 74 0.8997999999999999 77 | 75 0.933 78 | 76 0.8806 79 | 77 0.8822 80 | 78 0.9484 81 | 79 0.9609 82 | 80 0.9553 83 | 81 0.9308000000000001 84 | 82 0.9299999999999999 85 | 83 0.9547 86 | 84 0.9255 87 | 85 0.942 88 | 86 0.9280999999999999 89 | 87 0.9674 90 | 88 0.945 91 | 89 0.9530000000000001 92 | 90 0.957 93 | 91 0.9244 94 | 92 0.967 95 | 93 0.8554999999999999 96 | 94 0.9247000000000001 97 | 95 0.977 98 | 96 0.952 99 | 97 0.983 100 | 98 0.9438 101 | 99 0.9262999999999999 102 | 100 0.9473 103 | 101 0.9289000000000001 104 | 102 0.9593 105 | 103 0.9055 106 | 104 0.9605 107 | 105 0.962 108 | 106 0.958 109 | 107 0.9477 110 | 108 0.9476 111 | 109 0.9404 112 | 110 0.9390000000000001 113 | 111 0.9379 114 | 112 0.946 115 | 113 0.9538 116 | 114 0.9417 117 | 115 0.9435 118 | 116 0.6395 119 | 117 0.9149 120 | 118 0.9340999999999999 121 | 119 0.8875 122 | 120 0.9262 123 | 121 0.9208000000000001 124 | 122 0.931 125 | 123 0.927 126 | 124 0.9494 127 | 125 0.95 128 | 126 0.9456 129 | 127 0.9586 130 | -------------------------------------------------------------------------------- /config/RM8x16_S.rlb: -------------------------------------------------------------------------------- 1 | 128 2 | 0 1.0 3 | 1 1.0 4 | 2 1.0 5 | 3 1.0 6 | 4 1.0 7 | 5 1.0 8 | 6 1.0 9 | 7 1.0 10 | 8 1.0 11 | 9 1.0 12 | 10 1.0 13 | 11 1.0 14 | 12 1.0 15 | 13 1.0 16 | 14 1.0 17 | 15 1.0 18 | 16 1.0 19 | 17 1.0 20 | 18 1.0 21 | 19 1.0 22 | 20 1.0 23 | 21 1.0 24 | 22 1.0 25 | 23 1.0 26 | 24 1.0 27 | 25 1.0 28 | 26 1.0 29 | 27 1.0 30 | 28 1.0 31 | 29 1.0 32 | 30 1.0 33 | 31 1.0 34 | 32 1.0 35 | 33 1.0 36 | 34 1.0 37 | 35 1.0 38 | 36 1.0 39 | 37 1.0 40 | 38 1.0 41 | 39 1.0 42 | 40 1.0 43 | 41 1.0 44 | 42 1.0 45 | 43 1.0 46 | 44 1.0 47 | 45 1.0 48 | 46 1.0 49 | 47 1.0 50 | 48 1.0 51 | 49 1.0 52 | 50 1.0 53 | 51 1.0 54 | 52 1.0 55 | 53 1.0 56 | 54 1.0 57 | 55 1.0 58 | 56 1.0 59 | 57 1.0 60 | 58 1.0 61 | 59 1.0 62 | 60 1.0 63 | 61 1.0 64 | 62 1.0 65 | 63 1.0 66 | 64 1.0 67 | 65 1.0 68 | 66 1.0 69 | 67 1.0 70 | 68 1.0 71 | 69 1.0 72 | 70 1.0 73 | 71 1.0 74 | 72 1.0 75 | 73 1.0 76 | 74 1.0 77 | 75 1.0 78 | 76 1.0 79 | 77 1.0 80 | 78 1.0 81 | 79 1.0 82 | 80 1.0 83 | 81 1.0 84 | 82 1.0 85 | 83 1.0 86 | 84 1.0 87 | 85 1.0 88 | 86 1.0 89 | 87 1.0 90 | 88 1.0 91 | 89 1.0 92 | 90 1.0 93 | 91 1.0 94 | 92 1.0 95 | 93 1.0 96 | 94 1.0 97 | 95 1.0 98 | 96 1.0 99 | 97 1.0 100 | 98 1.0 101 | 99 1.0 102 | 100 1.0 103 | 101 1.0 104 | 102 1.0 105 | 103 1.0 106 | 104 1.0 107 | 105 1.0 108 | 106 1.0 109 | 107 1.0 110 | 108 1.0 111 | 109 1.0 112 | 110 1.0 113 | 111 1.0 114 | 112 1.0 115 | 113 1.0 116 | 114 1.0 117 | 115 1.0 118 | 116 1.0 119 | 117 1.0 120 | 118 1.0 121 | 119 1.0 122 | 120 1.0 123 | 121 1.0 124 | 122 1.0 125 | 123 1.0 126 | 124 1.0 127 | 125 1.0 128 | 126 1.0 129 | 127 1.0 130 | -------------------------------------------------------------------------------- /config/RM8x16_T.rlb: -------------------------------------------------------------------------------- 1 | 232 2 | 0 1 0.9524860195086018 3 | 0 16 0.9529282880369916 4 | 1 2 0.9540257271061188 5 | 1 17 0.9505029338224967 6 | 2 3 0.9546048104377549 7 | 2 18 0.9786914082038652 8 | 3 4 0.9696917082913719 9 | 3 19 0.9593096708776873 10 | 4 5 0.9640765744383628 11 | 4 20 0.9711692776496903 12 | 5 6 0.9013476968779408 13 | 5 21 0.9524790470179532 14 | 6 7 0.9649881540737134 15 | 6 22 0.9703982074689408 16 | 7 8 0.9657303252813656 17 | 7 23 0.9661484339535166 18 | 8 9 0.9510021095709416 19 | 8 24 0.957182957584277 20 | 9 10 0.8842810533465922 21 | 9 25 0.9621231087383495 22 | 10 11 0.951473034123643 23 | 10 26 0.9575497404297234 24 | 11 12 0.9604979140030367 25 | 11 27 0.9743121053460589 26 | 12 13 0.9524790470179532 27 | 12 28 0.9504506647323048 28 | 13 14 0.9560412770116393 29 | 13 29 0.9484579716600627 30 | 14 15 0.9513289077894327 31 | 14 30 0.9304335237497624 32 | 15 31 0.9687140146851144 33 | 16 17 0.9610909104142962 34 | 16 32 0.9745372755783388 35 | 17 18 0.955716704057388 36 | 17 33 0.9546076629079223 37 | 18 19 0.9609601554891113 38 | 18 34 0.9742261827074248 39 | 19 20 0.9593749807743908 40 | 19 35 0.9531264777055364 41 | 20 21 0.9625585023640528 42 | 20 36 0.9350254895734444 43 | 21 22 0.9766238908049172 44 | 21 37 0.966015013317955 45 | 22 23 0.8439542122870992 46 | 22 38 0.9279754300578409 47 | 23 24 0.9739918290818343 48 | 23 39 0.8813053308359989 49 | 24 25 0.9642715778794133 50 | 24 40 0.9690790743159409 51 | 25 26 0.9580065803036788 52 | 25 41 0.9609530905384231 53 | 26 27 0.9537352826638275 54 | 26 42 0.9534099945188771 55 | 27 28 0.956410827941085 56 | 27 43 0.9511688975673402 57 | 28 29 0.9349692706480592 58 | 28 44 0.9680404688430339 59 | 29 30 0.9600523466659158 60 | 29 45 0.8868157918758284 61 | 30 31 0.9600749476302965 62 | 30 46 0.9690951780838621 63 | 31 47 0.9666014804151035 64 | 32 33 0.9664201979993355 65 | 32 48 0.9413722114961054 66 | 33 34 0.9402493305397487 67 | 33 49 0.9513351592207986 68 | 34 35 0.9658239253229696 69 | 34 50 0.9429476008944138 70 | 35 36 0.9662615761617595 71 | 35 51 0.9667271324185478 72 | 36 37 0.9747134989621051 73 | 36 52 0.9532445908329791 74 | 37 38 0.9534223370377776 75 | 37 53 0.9529711765002458 76 | 38 39 0.9682618228073473 77 | 38 54 0.9131585548693508 78 | 39 40 0.9617811325976215 79 | 39 55 0.9546814937384691 80 | 40 41 0.9640479604758843 81 | 40 56 0.971935806313224 82 | 41 42 0.9530497712761012 83 | 41 57 0.9728571721638657 84 | 42 43 0.9139857029161499 85 | 42 58 0.9210862900910106 86 | 43 44 0.9600035971346821 87 | 43 59 0.9606115655787432 88 | 44 45 0.9740240191920158 89 | 44 60 0.9612155698820558 90 | 45 46 0.9538876717064406 91 | 45 61 0.9441389323451284 92 | 46 47 0.9705116393526925 93 | 46 62 0.967848016460263 94 | 47 63 0.9556895472102523 95 | 48 49 0.9561745609453003 96 | 48 64 0.9618021578926984 97 | 49 50 0.9534255673487513 98 | 49 65 0.9414629413144705 99 | 50 51 0.965329538315741 100 | 50 66 0.9657894771652482 101 | 51 52 0.9205223519906105 102 | 51 67 0.9749225236273233 103 | 52 53 0.9658838879497348 104 | 52 68 0.9580375615395206 105 | 53 54 0.9537743818058229 106 | 53 69 0.9451774386060221 107 | 54 55 0.9693342194625203 108 | 54 70 0.9677200578229868 109 | 55 56 0.9562658035759466 110 | 55 71 0.9600983249798706 111 | 56 57 0.9454899482324612 112 | 56 72 0.8780311994283708 113 | 57 58 0.9665403305584406 114 | 57 73 0.9745372755783388 115 | 58 59 0.9558680971003685 116 | 58 74 0.9753358769610737 117 | 59 60 0.9588676694571948 118 | 59 75 0.9544059964697149 119 | 60 61 0.9495385595311752 120 | 60 76 0.9562032045384778 121 | 61 62 0.9566853390018609 122 | 61 77 0.962809884842314 123 | 62 63 0.9608244660627785 124 | 62 78 0.9648445923491442 125 | 63 79 0.9548710991854346 126 | 64 65 0.9692722530351439 127 | 64 80 0.971935806313224 128 | 65 66 0.961279757693243 129 | 65 81 0.9594933333128853 130 | 66 67 0.9566466136746337 131 | 66 82 0.9410249889213794 132 | 67 68 0.9576323073833486 133 | 67 83 0.9729667009010617 134 | 68 69 0.9563066669133867 135 | 68 84 0.9568497181966855 136 | 69 70 0.9692152377465415 137 | 69 85 0.946846815955478 138 | 70 71 0.9666494410680535 139 | 70 86 0.9558446937163696 140 | 71 72 0.9701680211651587 141 | 71 87 0.9571557472044221 142 | 72 73 0.9609838346876787 143 | 72 88 0.9572422923573821 144 | 73 74 0.9558546537895933 145 | 73 89 0.9650564318835115 146 | 74 75 0.9583347371763707 147 | 74 90 0.9680404688430339 148 | 75 76 0.9540524905854422 149 | 75 91 0.963211784845468 150 | 76 77 0.9755326850164808 151 | 76 92 0.9554827805179414 152 | 77 78 0.9072718480527173 153 | 77 93 0.9496300749094235 154 | 78 79 0.9646115028646781 155 | 78 94 0.970678283399345 156 | 79 95 0.9632855367284152 157 | 80 81 0.9542379718073347 158 | 80 96 0.966762319364256 159 | 81 82 0.9509214531688011 160 | 81 97 0.9626732450877278 161 | 82 83 0.9609937564397011 162 | 82 98 0.9401912985654675 163 | 83 84 0.9681936975306555 164 | 83 99 0.9345482968427631 165 | 84 85 0.9528043739783774 166 | 84 100 0.9551561939799921 167 | 85 86 0.951139026606384 168 | 85 101 0.9582124111304935 169 | 86 87 0.9591039993511659 170 | 86 102 0.9744026680533306 171 | 87 88 0.954808224503619 172 | 87 103 0.9507145543540917 173 | 88 89 0.9605276794331971 174 | 88 104 0.9723525666766663 175 | 89 90 0.9525066644082667 176 | 89 105 0.9580588015932311 177 | 90 91 0.9478147549754935 178 | 90 106 0.9563968012993472 179 | 91 92 0.9604239735240532 180 | 91 107 0.975871552722279 181 | 92 93 0.9571844612011616 182 | 92 108 0.8696982294013715 183 | 93 94 0.9698471163566943 184 | 93 109 0.9744026680533306 185 | 94 95 0.9479987254965161 186 | 94 110 0.9658696231309467 187 | 95 111 0.9666902054167377 188 | 96 97 0.9191114679052699 189 | 96 112 0.9621035439038136 190 | 97 98 0.9666264591033547 191 | 97 113 0.9547908421027715 192 | 98 99 0.9740352932389206 193 | 98 114 0.7757201993935489 194 | 99 100 0.9427654595792038 195 | 99 115 0.9714384589145205 196 | 100 101 0.9575344466967495 197 | 100 116 0.970999831673923 198 | 101 102 0.970198895771795 199 | 101 117 0.97194930100354 200 | 102 103 0.9606800533089087 201 | 102 118 0.8876113823069963 202 | 103 104 0.9753834402701325 203 | 103 119 0.9725582217950214 204 | 104 105 0.9689858855524669 205 | 104 120 0.9585636299687894 206 | 105 106 0.9560186419477076 207 | 105 121 0.9714162250143461 208 | 106 107 0.9223301973540043 209 | 106 122 0.9638952652987893 210 | 107 108 0.9181935951335924 211 | 107 123 0.9743121053460589 212 | 108 109 0.9702865275560505 213 | 108 124 0.9714162250143461 214 | 109 110 0.9712347092792688 215 | 109 125 0.967848016460263 216 | 110 111 0.9631161623805703 217 | 110 126 0.9438696461121314 218 | 111 127 0.9638269319798796 219 | 112 113 0.9695217298036867 220 | 113 114 0.9732678583743171 221 | 114 115 0.9296572306509414 222 | 115 116 0.9658407995038569 223 | 116 117 0.6687474818732732 224 | 117 118 0.9627604134464226 225 | 118 119 0.9304973509707904 226 | 119 120 0.9513295856186228 227 | 120 121 0.39309031147589857 228 | 121 122 0.9352796214493465 229 | 122 123 0.9374656394388243 230 | 123 124 0.954090089140359 231 | 124 125 0.9613181737136305 232 | 125 126 0.963211784845468 233 | 126 127 0.967182286028095 234 | -------------------------------------------------------------------------------- /config/RM8x8_M.rlb: -------------------------------------------------------------------------------- 1 | 64 2 | 0 0.9023 3 | 1 0.9057 4 | 2 0.8292 5 | 3 0.962 6 | 4 0.868 7 | 5 0.9359999999999999 8 | 6 0.873 9 | 7 0.9440999999999999 10 | 8 0.951 11 | 9 0.952 12 | 10 0.95 13 | 11 0.9651 14 | 12 0.83 15 | 13 0.9375 16 | 14 0.893 17 | 15 0.975 18 | 16 0.9066000000000001 19 | 17 0.9490000000000001 20 | 18 0.9522 21 | 19 0.8292 22 | 20 0.9284 23 | 21 0.9533 24 | 22 0.9410000000000001 25 | 23 0.9308000000000001 26 | 24 0.9460999999999999 27 | 25 0.9579 28 | 26 0.845 29 | 27 0.9438 30 | 28 0.8976 31 | 29 0.8571 32 | 30 0.931 33 | 31 0.8696 34 | 32 0.9639 35 | 33 0.977 36 | 34 0.7030000000000001 37 | 35 0.8974 38 | 36 0.9553 39 | 37 0.8986 40 | 38 0.9567 41 | 39 0.927 42 | 40 0.9438 43 | 41 0.772 44 | 42 0.9343 45 | 43 0.8927 46 | 44 0.8958 47 | 45 0.9494 48 | 46 0.957 49 | 47 0.961 50 | 48 0.9426 51 | 49 0.9491 52 | 50 0.9504999999999999 53 | 51 0.9359999999999999 54 | 52 0.9158 55 | 53 0.9497 56 | 54 0.928 57 | 55 0.9081 58 | 56 0.9554 59 | 57 0.962 60 | 58 0.944 61 | 59 0.9319999999999999 62 | 60 0.9529000000000001 63 | 61 0.8963 64 | 62 0.952 65 | 63 0.8916999999999999 66 | -------------------------------------------------------------------------------- /config/RM8x8_S.rlb: -------------------------------------------------------------------------------- 1 | 64 2 | 0 1.0 3 | 1 1.0 4 | 2 1.0 5 | 3 1.0 6 | 4 1.0 7 | 5 1.0 8 | 6 1.0 9 | 7 1.0 10 | 8 1.0 11 | 9 1.0 12 | 10 1.0 13 | 11 1.0 14 | 12 1.0 15 | 13 1.0 16 | 14 1.0 17 | 15 1.0 18 | 16 1.0 19 | 17 1.0 20 | 18 1.0 21 | 19 1.0 22 | 20 1.0 23 | 21 1.0 24 | 22 1.0 25 | 23 1.0 26 | 24 1.0 27 | 25 1.0 28 | 26 1.0 29 | 27 1.0 30 | 28 1.0 31 | 29 1.0 32 | 30 1.0 33 | 31 1.0 34 | 32 1.0 35 | 33 1.0 36 | 34 1.0 37 | 35 1.0 38 | 36 1.0 39 | 37 1.0 40 | 38 1.0 41 | 39 1.0 42 | 40 1.0 43 | 41 1.0 44 | 42 1.0 45 | 43 1.0 46 | 44 1.0 47 | 45 1.0 48 | 46 1.0 49 | 47 1.0 50 | 48 1.0 51 | 49 1.0 52 | 50 1.0 53 | 51 1.0 54 | 52 1.0 55 | 53 1.0 56 | 54 1.0 57 | 55 1.0 58 | 56 1.0 59 | 57 1.0 60 | 58 1.0 61 | 59 1.0 62 | 60 1.0 63 | 61 1.0 64 | 62 1.0 65 | 63 1.0 66 | -------------------------------------------------------------------------------- /config/RM8x8_T.rlb: -------------------------------------------------------------------------------- 1 | 112 2 | 0 1 0.962161669690003 3 | 0 8 0.5864662297218872 4 | 1 2 0.9655276497768241 5 | 1 9 0.9070581879616035 6 | 2 3 0.9407798707355021 7 | 2 10 0.9728202740018634 8 | 3 4 0.9726725091415267 9 | 3 11 0.9705926583024146 10 | 4 5 0.9540574383986982 11 | 4 12 0.9647079407067528 12 | 5 6 0.9750369464085652 13 | 5 13 0.9072718480527173 14 | 6 7 0.9647617949348809 15 | 6 14 0.9748361910944403 16 | 7 15 0.9668728271635214 17 | 8 9 0.9577101841146405 18 | 8 16 0.9621768371708712 19 | 9 10 0.9662783622337259 20 | 9 17 0.9542283409324164 21 | 10 11 0.9644418141739459 22 | 10 18 0.9573601535376632 23 | 11 12 0.9723525666766663 24 | 11 19 0.967480085542936 25 | 12 13 0.9617331898272513 26 | 12 20 0.9484579716600627 27 | 13 14 0.9465009605152019 28 | 13 21 0.9549805312424313 29 | 14 15 0.9732262816413346 30 | 14 22 0.9541979015518556 31 | 15 23 0.9569683518325203 32 | 16 17 0.9710591857747348 33 | 16 24 0.9661138192166978 34 | 17 18 0.9748787120263293 35 | 17 25 0.9658407995038569 36 | 18 19 0.9688748049940571 37 | 18 26 0.958143804178681 38 | 19 20 0.9590023304534516 39 | 19 27 0.9630577518378567 40 | 20 21 0.9748873045979067 41 | 20 28 0.953249077390171 42 | 21 22 0.9606348109582851 43 | 21 29 0.9287465139604373 44 | 22 23 0.9669668894178972 45 | 22 30 0.9407798707355021 46 | 23 31 0.9531386274472397 47 | 24 25 0.9570047952320966 48 | 24 32 0.97434406562978 49 | 25 26 0.9513968153812121 50 | 25 33 0.9712063242137301 51 | 26 27 0.9590354355473474 52 | 26 34 0.9529714738401557 53 | 27 28 0.951559148738778 54 | 27 35 0.933846416806474 55 | 28 29 0.9705116393526925 56 | 28 36 0.965268183518885 57 | 29 30 0.974139137469909 58 | 29 37 0.9247200496775982 59 | 30 31 0.9663069000283783 60 | 30 38 0.9753293264036422 61 | 31 39 0.9671174035180675 62 | 32 33 0.9500197942143213 63 | 32 40 0.9675117737454879 64 | 33 34 0.9644418141739459 65 | 33 41 0.9584292741012932 66 | 34 35 0.9230582108589594 67 | 34 42 0.9758964130086817 68 | 35 36 0.9595668776484547 69 | 35 43 0.9374163236984386 70 | 36 37 0.9697020152605715 71 | 36 44 0.9518009759398177 72 | 37 38 0.9402493305397487 73 | 37 45 0.9635527532624979 74 | 38 39 0.9693351963077634 75 | 38 46 0.959137621006491 76 | 39 47 0.9691703761113919 77 | 40 41 0.9552681874119154 78 | 40 48 0.952885256197268 79 | 41 42 0.9654173199793629 80 | 41 49 0.9626634480833965 81 | 42 43 0.9714408195647868 82 | 42 50 0.9694891845018869 83 | 43 44 0.954563541002736 84 | 43 51 0.9531386274472397 85 | 44 45 0.9654660303118756 86 | 44 52 0.9625963723134905 87 | 45 46 0.9571613297243251 88 | 45 53 0.9640479604758843 89 | 46 47 0.9713921031555999 90 | 46 54 0.975109879498341 91 | 47 55 0.9569951524591701 92 | 48 49 0.9753414651368963 93 | 48 56 0.9696944741507209 94 | 49 50 0.9546212108931109 95 | 49 57 0.956852304633492 96 | 50 51 0.9523704966777835 97 | 50 58 0.9717789873193451 98 | 51 52 0.9238585977241549 99 | 51 59 0.9606856746352483 100 | 52 53 0.9582124111304935 101 | 52 60 0.9504826188170804 102 | 53 54 0.9600035971346821 103 | 53 61 0.9713840049159757 104 | 54 55 0.9581849111876016 105 | 54 62 0.9574147684105421 106 | 55 63 0.9571269383573764 107 | 56 57 0.9742442652162434 108 | 57 58 0.9524860195086018 109 | 58 59 0.9546476248081491 110 | 59 60 0.9622654422706586 111 | 60 61 0.9719137101315846 112 | 61 62 0.9707267490431879 113 | 62 63 0.9530576230549224 114 | -------------------------------------------------------------------------------- /config/RM8x9_M.rlb: -------------------------------------------------------------------------------- 1 | 72 2 | 0 0.9347 3 | 1 0.944 4 | 2 0.9329000000000001 5 | 3 0.8972 6 | 4 0.9051 7 | 5 0.9612 8 | 6 0.9672000000000001 9 | 7 0.9433 10 | 8 0.9618 11 | 9 0.9517 12 | 10 0.9379 13 | 11 0.9359999999999999 14 | 12 0.8853 15 | 13 0.9378 16 | 14 0.9325 17 | 15 0.9669 18 | 16 0.9335 19 | 17 0.956 20 | 18 0.9177 21 | 19 0.8974 22 | 20 0.8871 23 | 21 0.9118999999999999 24 | 22 0.9423999999999999 25 | 23 0.8735999999999999 26 | 24 0.953 27 | 25 0.9103 28 | 26 0.9553 29 | 27 0.8902 30 | 28 0.8873 31 | 29 0.96 32 | 30 0.9541 33 | 31 0.8949 34 | 32 0.9472 35 | 33 0.9447 36 | 34 0.954 37 | 35 0.8948 38 | 36 0.9507 39 | 37 0.9480999999999999 40 | 38 0.9487000000000001 41 | 39 0.8872 42 | 40 0.9477 43 | 41 0.9563999999999999 44 | 42 0.9400999999999999 45 | 43 0.915 46 | 44 0.9212 47 | 45 0.956 48 | 46 0.9567 49 | 47 0.945 50 | 48 0.9304 51 | 49 0.8962 52 | 50 0.962 53 | 51 0.8885 54 | 52 0.962 55 | 53 0.8898 56 | 54 0.9582999999999999 57 | 55 0.9278 58 | 56 0.9393 59 | 57 0.9513 60 | 58 0.9373 61 | 59 0.8752 62 | 60 0.977 63 | 61 0.951 64 | 62 0.9354 65 | 63 0.952 66 | 64 0.9268 67 | 65 0.8332999999999999 68 | 66 0.9333 69 | 67 0.9491 70 | 68 0.9289000000000001 71 | 69 0.925 72 | 70 0.978 73 | 71 0.9514 74 | -------------------------------------------------------------------------------- /config/RM8x9_S.rlb: -------------------------------------------------------------------------------- 1 | 72 2 | 0 1.0 3 | 1 1.0 4 | 2 1.0 5 | 3 1.0 6 | 4 1.0 7 | 5 1.0 8 | 6 1.0 9 | 7 1.0 10 | 8 1.0 11 | 9 1.0 12 | 10 1.0 13 | 11 1.0 14 | 12 1.0 15 | 13 1.0 16 | 14 1.0 17 | 15 1.0 18 | 16 1.0 19 | 17 1.0 20 | 18 1.0 21 | 19 1.0 22 | 20 1.0 23 | 21 1.0 24 | 22 1.0 25 | 23 1.0 26 | 24 1.0 27 | 25 1.0 28 | 26 1.0 29 | 27 1.0 30 | 28 1.0 31 | 29 1.0 32 | 30 1.0 33 | 31 1.0 34 | 32 1.0 35 | 33 1.0 36 | 34 1.0 37 | 35 1.0 38 | 36 1.0 39 | 37 1.0 40 | 38 1.0 41 | 39 1.0 42 | 40 1.0 43 | 41 1.0 44 | 42 1.0 45 | 43 1.0 46 | 44 1.0 47 | 45 1.0 48 | 46 1.0 49 | 47 1.0 50 | 48 1.0 51 | 49 1.0 52 | 50 1.0 53 | 51 1.0 54 | 52 1.0 55 | 53 1.0 56 | 54 1.0 57 | 55 1.0 58 | 56 1.0 59 | 57 1.0 60 | 58 1.0 61 | 59 1.0 62 | 60 1.0 63 | 61 1.0 64 | 62 1.0 65 | 63 1.0 66 | 64 1.0 67 | 65 1.0 68 | 66 1.0 69 | 67 1.0 70 | 68 1.0 71 | 69 1.0 72 | 70 1.0 73 | 71 1.0 74 | -------------------------------------------------------------------------------- /config/RM8x9_T.rlb: -------------------------------------------------------------------------------- 1 | 127 2 | 0 1 0.9585011434974181 3 | 0 9 0.9763550217455248 4 | 1 2 0.974998234469802 5 | 1 10 0.9549811813904507 6 | 2 3 0.9633508907649277 7 | 2 11 0.9595838532054475 8 | 3 4 0.9562032045384778 9 | 3 12 0.9610909104142962 10 | 4 5 0.9613628418422179 11 | 4 13 0.9516202015276122 12 | 5 6 0.9580588015932311 13 | 5 14 0.9595668776484547 14 | 6 7 0.954808224503619 15 | 6 15 0.9698499773214271 16 | 7 8 0.9689163697521821 17 | 7 16 0.9535338990072174 18 | 8 17 0.9452752026787181 19 | 9 10 0.9435724301413704 20 | 9 18 0.9519422250052848 21 | 10 11 0.9554119430434469 22 | 10 19 0.9594479222174513 23 | 11 12 0.9615016488605753 24 | 11 20 0.9617331898272513 25 | 12 13 0.9755368299820437 26 | 12 21 0.9744477760757227 27 | 13 14 0.8635284608001483 28 | 13 22 0.9573235909898532 29 | 14 15 0.9565135129532746 30 | 14 23 0.9542283409324164 31 | 15 16 0.9680404688430339 32 | 15 24 0.9530683496606653 33 | 16 17 0.962474200400144 34 | 16 25 0.9680404688430339 35 | 17 26 0.9155069588559226 36 | 18 19 0.9574575517574317 37 | 18 27 0.9680574372830202 38 | 19 20 0.9540492775388086 39 | 19 28 0.954558909236142 40 | 20 21 0.9591723821358974 41 | 20 29 0.5864662297218872 42 | 21 22 0.9640853521415415 43 | 21 30 0.9138781998853496 44 | 22 23 0.9633906100987433 45 | 22 31 0.9567200784569565 46 | 23 24 0.9648317774805959 47 | 23 32 0.9677612536609408 48 | 24 25 0.9565251720284086 49 | 24 33 0.9474000062202715 50 | 25 26 0.9557195551042844 51 | 25 34 0.975871552722279 52 | 26 35 0.9528043739783774 53 | 27 28 0.9530579167960228 54 | 27 36 0.9551249776214519 55 | 28 29 0.9559299409618518 56 | 28 37 0.9579297638460083 57 | 29 30 0.971076774971903 58 | 29 38 0.9246055528080346 59 | 30 31 0.967480085542936 60 | 30 39 0.9548100104106303 61 | 31 32 0.9609084220699894 62 | 31 40 0.9532626955977539 63 | 32 33 0.9582511343084109 64 | 32 41 0.947211607692792 65 | 33 34 0.9640479604758843 66 | 33 42 0.9564592448300984 67 | 34 35 0.975668241593183 68 | 34 43 0.9374163236984386 69 | 35 44 0.9682526277867365 70 | 36 37 0.9772262334778103 71 | 36 45 0.9608244660627785 72 | 37 38 0.9643457784777626 73 | 37 46 0.9683976835073927 74 | 38 39 0.9578007195530676 75 | 38 47 0.9401912985654675 76 | 39 40 0.965329538315741 77 | 39 48 0.9616706977716547 78 | 40 41 0.9688821687944934 79 | 40 49 0.9758964130086817 80 | 41 42 0.8635284608001483 81 | 41 50 0.9624476212914403 82 | 42 43 0.9698620281109194 83 | 42 51 0.9696157251484678 84 | 43 44 0.9328500328030667 85 | 43 52 0.8842810533465922 86 | 44 53 0.9573561423047849 87 | 45 46 0.9662166564341311 88 | 45 54 0.971811671098555 89 | 46 47 0.9658239253229696 90 | 46 55 0.9714408195647868 91 | 47 48 0.9436616983627931 92 | 47 56 0.9639703400292513 93 | 48 49 0.9582810147593722 94 | 48 57 0.9510935271693832 95 | 49 50 0.9523793543205621 96 | 49 58 0.6808087615577503 97 | 50 51 0.9596676492742198 98 | 50 59 0.9651604583988767 99 | 51 52 0.9690237691508831 100 | 51 60 0.9699509246427013 101 | 52 53 0.9571049132037484 102 | 52 61 0.9600035971346821 103 | 53 62 0.9658337233313081 104 | 54 55 0.9505485176204505 105 | 54 63 0.9640479604758843 106 | 55 56 0.8996968783014393 107 | 55 64 0.9472167464957911 108 | 56 57 0.9569683518325203 109 | 56 65 0.9647571537170363 110 | 57 58 0.9688041094739714 111 | 57 66 0.9576323073833486 112 | 58 59 0.921660784757752 113 | 58 67 0.965808612486776 114 | 59 60 0.967123045372624 115 | 59 68 0.9704914696574325 116 | 60 61 0.9442854481628039 117 | 60 69 0.9576323073833486 118 | 61 62 0.9620928415730048 119 | 61 70 0.9675439697732243 120 | 62 71 0.9569002261306725 121 | 63 64 0.9503532143213637 122 | 64 65 0.9546300079519447 123 | 65 66 0.9469764035891716 124 | 66 67 0.9265021416302381 125 | 67 68 0.9657064308680592 126 | 68 69 0.9474000062202715 127 | 69 70 0.95348780683246 128 | 70 71 0.9660920046843665 129 | -------------------------------------------------------------------------------- /config/agave_M.rlb: -------------------------------------------------------------------------------- 1 | 4 2 | 0 0.8959 3 | 1 0.9391 4 | 2 0.9324 5 | 3 0.9227 -------------------------------------------------------------------------------- /config/agave_S.rlb: -------------------------------------------------------------------------------- 1 | 4 2 | 0 0.974 3 | 1 0.9764 4 | 2 0.982 5 | 3 0.9676 -------------------------------------------------------------------------------- /config/agave_T.rlb: -------------------------------------------------------------------------------- 1 | 3 2 | 0 1 0.8657 3 | 1 2 0.9623 4 | 2 3 0.9192 -------------------------------------------------------------------------------- /config/cmd_notes.txt: -------------------------------------------------------------------------------- 1 | To generate graph for metis: 2 | python ~/code/IBM_Data/metis_graph.py RM8x8_T.rlb . RM8x8.metis_graph 3 | 4 | To use metis: 5 | gpmetis RM8x8.metis_graph 6 | 7 | Alwin Zulehner code: 8 | /home/prakash/code/Zulh/ibm_qx_mapping 9 | 10 | Trapped ion sim: 11 | In ~/isca/trapped_ion folder 12 | 13 | -------------------------------------------------------------------------------- /config/dummy_M.rlb: -------------------------------------------------------------------------------- 1 | 6 2 | 0 1 3 | 1 1 4 | 2 1 5 | 3 1 6 | 4 1 7 | 5 1 -------------------------------------------------------------------------------- /config/dummy_S.rlb: -------------------------------------------------------------------------------- 1 | 6 2 | 0 1 3 | 1 1 4 | 2 1 5 | 3 1 6 | 4 1 7 | 5 1 -------------------------------------------------------------------------------- /config/dummy_T.rlb: -------------------------------------------------------------------------------- 1 | 7 2 | 0 1 0.9 3 | 1 2 0.9 4 | 0 5 0.8 5 | 1 4 0.9 6 | 2 3 0.7 7 | 5 4 0.9 8 | 4 3 0.8 -------------------------------------------------------------------------------- /config/ibmq_16_melbourne_M.rlb: -------------------------------------------------------------------------------- 1 | 14 2 | 0 0.9691000000000001 3 | 1 0.9681 4 | 2 0.9647 5 | 3 0.7399 6 | 4 0.9715 7 | 5 0.9373 8 | 6 0.9671000000000001 9 | 7 0.5325 10 | 8 0.9648 11 | 9 0.8425 12 | 10 0.7686 13 | 11 0.9556 14 | 12 0.9376 15 | 13 0.8989 16 | -------------------------------------------------------------------------------- /config/ibmq_16_melbourne_S.rlb: -------------------------------------------------------------------------------- 1 | 14 2 | 0 0.996757189527604 3 | 1 0.9793793725978255 4 | 2 0.9897185653226979 5 | 3 0.9987609056484434 6 | 4 0.9964841388928687 7 | 5 0.9916932994004406 8 | 6 0.9848184244233908 9 | 7 0.9833042956834309 10 | 8 0.9978444026534106 11 | 9 0.9925626580199498 12 | 10 0.9914763338475653 13 | 11 0.99580965731764 14 | 12 0.9969675362043758 15 | 13 0.8793886441600057 16 | -------------------------------------------------------------------------------- /config/ibmq_16_melbourne_T.rlb: -------------------------------------------------------------------------------- 1 | 18 2 | 5 4 0.9500415764843599 3 | 2 3 0.9574552240406733 4 | 11 3 0.9571530007346793 5 | 4 3 0.9439360238197881 6 | 5 9 0.861262453129556 7 | 11 12 0.9551420419704448 8 | 13 1 0.6611596066648988 9 | 11 10 0.39959221674416556 10 | 13 12 0.7455161999254012 11 | 6 8 0.9611064583395956 12 | 1 0 0.9555453046248608 13 | 9 10 0.9152715894185248 14 | 1 2 0.9306612972854601 15 | 7 8 0.6615054815895598 16 | 12 2 0.9019897225982896 17 | 4 10 0.9515933858380659 18 | 5 6 0.9379522648979998 19 | 9 8 0.9457406533540407 20 | -------------------------------------------------------------------------------- /config/ibmqx4_M.rlb: -------------------------------------------------------------------------------- 1 | 5 2 | 0 0.846 3 | 1 0.937 4 | 2 0.962 5 | 3 0.97 6 | 4 0.926 7 | -------------------------------------------------------------------------------- /config/ibmqx4_S.rlb: -------------------------------------------------------------------------------- 1 | 5 2 | 0 0.9992273692706546 3 | 1 0.9988839145121239 4 | 2 0.9989697818583652 5 | 3 0.9984545411897114 6 | 4 0.9987121725030761 7 | -------------------------------------------------------------------------------- /config/ibmqx4_T.rlb: -------------------------------------------------------------------------------- 1 | 6 2 | 3 2 0.9347599759334276 3 | 1 0 0.971324125855421 4 | 2 1 0.9632801476247475 5 | 4 2 0.9356666889085882 6 | 3 4 0.9502316716169495 7 | 2 0 0.9728188875810317 8 | -------------------------------------------------------------------------------- /config/ibmqx5_M.rlb: -------------------------------------------------------------------------------- 1 | 16 2 | 0 0.9424 3 | 1 0.9375 4 | 2 0.8292 5 | 3 0.9308000000000001 6 | 4 0.931 7 | 5 0.9442 8 | 6 0.9563999999999999 9 | 7 0.9649 10 | 8 0.9612 11 | 9 0.893 12 | 10 0.9212 13 | 11 0.9508000000000001 14 | 12 0.8841 15 | 13 0.9651 16 | 14 0.9422999999999999 17 | 15 0.8835 18 | -------------------------------------------------------------------------------- /config/ibmqx5_S.rlb: -------------------------------------------------------------------------------- 1 | 16 2 | 0 0.9977855387232824 3 | 1 0.996310776521717 4 | 2 0.9960756352453278 5 | 3 0.9965832000446118 6 | 4 0.9984050358370564 7 | 5 0.9981542019473859 8 | 6 0.9982286187410632 9 | 7 0.9975733418677558 10 | 8 0.9982650759390777 11 | 9 0.9990304857954931 12 | 10 0.997298062030519 13 | 11 0.9980397373216277 14 | 12 0.9973599177009459 15 | 13 0.9980582395570781 16 | 14 0.9977276431994632 17 | 15 0.9935281128052034 18 | -------------------------------------------------------------------------------- /config/ibmqx5_T.rlb: -------------------------------------------------------------------------------- 1 | 22 2 | 12 5 0.9549507000934807 3 | 9 10 0.9680404688430339 4 | 15 2 0.9479987254965161 5 | 13 4 0.9651604583988767 6 | 1 2 0.9605276794331971 7 | 5 4 0.9640479604758843 8 | 9 8 0.9705116393526925 9 | 3 14 0.9436461661876892 10 | 6 5 0.956852304633492 11 | 2 3 0.9459716027603042 12 | 1 0 0.9617811325976215 13 | 13 14 0.9524790470179532 14 | 12 13 0.9632855367284152 15 | 8 7 0.9576323073833486 16 | 6 11 0.9750369464085652 17 | 12 11 0.9574147684105421 18 | 15 14 0.9407798707355021 19 | 6 7 0.9714384589145205 20 | 11 10 0.9606992107225086 21 | 3 4 0.9510063371934758 22 | 7 10 0.9569002261306725 23 | 15 0 0.9165001928335009 24 | -------------------------------------------------------------------------------- /config/patterns.txt: -------------------------------------------------------------------------------- 1 | Pattern: CNOT Implementation 2 | Search: 3 | CNOT 4 | Action: 5 | Replace 6 | RY,0,params:pi/2; 7 | XX,0,1,params:pi/4; 8 | RY,0,params:-pi/2; 9 | RX,1,params:-pi/2; 10 | RZ,0,params:-pi/2; 11 | End 12 | Pattern: H Implementation 13 | Search: 14 | H 15 | Action: 16 | Replace 17 | RY,0,params:pi/2; 18 | RX,0,params:pi; 19 | End 20 | Pattern: X Implementation 21 | Search: 22 | X 23 | Action 24 | Replace 25 | RX,0,params:pi; 26 | End -------------------------------------------------------------------------------- /config/tion_M.rlb: -------------------------------------------------------------------------------- 1 | 5 2 | 0 1.0 3 | 1 1.0 4 | 2 1.0 5 | 3 1.0 6 | 4 1.0 7 | -------------------------------------------------------------------------------- /config/tion_S.rlb: -------------------------------------------------------------------------------- 1 | 5 2 | 0 1.0 3 | 1 1.0 4 | 2 1.0 5 | 3 1.0 6 | 4 1.0 7 | -------------------------------------------------------------------------------- /config/tion_T.rlb: -------------------------------------------------------------------------------- 1 | 25 2 | 0 0 0 3 | 0 1 0.970 4 | 0 2 0.980 5 | 0 3 0.970 6 | 0 4 0.970 7 | 1 0 0.970 8 | 1 1 0 9 | 1 2 0.980 10 | 1 3 0.990 11 | 1 4 0.980 12 | 2 0 0.980 13 | 2 1 0.980 14 | 2 2 0 15 | 2 3 0.990 16 | 2 4 0.990 17 | 3 0 0.970 18 | 3 1 0.990 19 | 3 2 0.990 20 | 3 3 0 21 | 3 4 0.970 22 | 4 0 0.970 23 | 4 1 0.980 24 | 4 2 0.990 25 | 4 3 0.970 26 | 4 4 0 27 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([triq], [0.1], [pmurali@princeton.edu]) 2 | AM_INIT_AUTOMAKE 3 | AC_PROG_CXX 4 | AC_CONFIG_FILES([Makefile]) 5 | AC_OUTPUT 6 | -------------------------------------------------------------------------------- /ir2dag.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | global_gate_id = 0 4 | prev_gate = {} 5 | gate_names = {"cx":"CNOT", "cz":"CZ", "h":"H", "x":"X", "y":"Y", "z":"Z", "rx":"RX", "ry":"RY", "rz":"RZ", "s":"S", "sdg":"Sdag", "t":"T", "tdg":"Tdag", "measure":"MeasZ"} 6 | gset1 = ['x', 'y', 'z', 'h', 's', 'sdg', 't', 'tdg', 'measure'] 7 | gset2 = ['rx', 'ry', 'rz'] 8 | gset3 = ['cx'] 9 | 10 | def find_dep_gate(qbit): 11 | if qbit in prev_gate.keys(): 12 | return [prev_gate[qbit]] 13 | else: 14 | return [] 15 | 16 | def update_dep_gate(qbit, gate_id): 17 | prev_gate[qbit] = gate_id 18 | 19 | def check_valid_gate(line): 20 | flag = 0 21 | gset = [] 22 | gset.extend(gset1) 23 | gset.extend(gset2) 24 | gset.extend(gset3) 25 | for g in gset: 26 | if line.startswith(g): 27 | flag = 1 28 | break 29 | return flag 30 | 31 | def process_gate(line, f_out): 32 | global gset1 33 | global gset2 34 | global gset3 35 | gflag = 0 36 | dep_gates = [] 37 | for g in gset1: 38 | if line.startswith(g): 39 | qbit = line.split()[1].split('[')[1].split(']')[0] 40 | gflag = 1 41 | #print(global_gate_id, g, qbit) 42 | f_out.write(str(global_gate_id) + ' ' + gate_names[g] + ' 1 ' + qbit) 43 | dep_gates = find_dep_gate(qbit) 44 | if len(dep_gates) == 1: 45 | f_out.write(' 1 ' + str(dep_gates[0]) + '\n') 46 | elif len(dep_gates) == 0: 47 | f_out.write(' 0\n') 48 | else: 49 | assert(0) 50 | update_dep_gate(qbit, global_gate_id) 51 | 52 | break 53 | for g in gset2: 54 | if line.startswith(g): 55 | qbit = line.split()[1].split('[')[1].split(']')[0] 56 | angle = line.split()[0].split('(')[1].split(')')[0] 57 | 58 | print(global_gate_id, g, qbit, angle) 59 | f_out.write(str(global_gate_id) + ' ' + gate_names[g] + ' 1 ' + qbit) 60 | dep_gates = find_dep_gate(qbit) 61 | if len(dep_gates) == 1: 62 | f_out.write(' 1 ' + str(dep_gates[0]) + ' ' + str(angle) + '\n') 63 | elif len(dep_gates) == 0: 64 | f_out.write(' 0 ' + str(angle) + '\n') 65 | else: 66 | assert(0) 67 | update_dep_gate(qbit, global_gate_id) 68 | gflag = 1 69 | break 70 | for g in gset3: 71 | if line.startswith(g): 72 | base = ''.join(line.split()).split(',') 73 | qbit1 = base[0].split('[')[1].split(']')[0] 74 | qbit2 = base[1].split('[')[1].split(']')[0] 75 | #print(global_gate_id, g, qbit1, qbit2) 76 | f_out.write(str(global_gate_id) + ' ' + gate_names[g] + ' 2 ' + qbit1 + ' ' + qbit2) 77 | dep_gates1 = find_dep_gate(qbit1) 78 | dep_gates2 = find_dep_gate(qbit2) 79 | dep_gates1.extend(dep_gates2) 80 | update_dep_gate(qbit1, global_gate_id) 81 | update_dep_gate(qbit2, global_gate_id) 82 | f_out.write(' ' + str(len(dep_gates1)) + ' ') 83 | for item in dep_gates1: 84 | f_out.write(str(item) + ' ') 85 | f_out.write('\n') 86 | gflag = 1 87 | break 88 | 89 | def parse_ir(fname, outfname): 90 | global global_gate_id 91 | f = open(fname, 'r') 92 | l = f.readlines() 93 | f_out = open(outfname, 'w') 94 | 95 | qcnt = 0 96 | gcnt = 0 97 | for line in l: 98 | line = ' '.join(line.split()) 99 | if line.startswith("OPENQASM"): 100 | continue 101 | elif line.startswith("include"): 102 | continue 103 | elif line.startswith("qreg"): 104 | sline = line.split() 105 | qcnt = int(sline[1].split('[')[1].split(']')[0]) 106 | elif line.startswith("creg"): 107 | continue 108 | else: 109 | if check_valid_gate(line): 110 | gcnt += 1 111 | 112 | f_out.write(str(qcnt) + ' ' + str(gcnt) + '\n') 113 | 114 | for line in l: 115 | line = ' '.join(line.split()) 116 | if line.startswith("OPENQASM"): 117 | continue 118 | elif line.startswith("include"): 119 | continue 120 | elif line.startswith("qreg"): 121 | continue 122 | elif line.startswith("creg"): 123 | continue 124 | else: 125 | if check_valid_gate(line): 126 | process_gate(line, f_out) 127 | global_gate_id += 1 128 | 129 | parse_ir(sys.argv[1], sys.argv[2]) 130 | -------------------------------------------------------------------------------- /src/backtrack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * backtrack.cpp 3 | * 4 | * Created on: Sep 10, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "backtrack.hpp" 9 | #include "headers.hpp" 10 | #include "machine.hpp" 11 | 12 | 13 | //vector Backtrack::all_nodes; 14 | int Backtrack::is_leaf(BacktrackNode *n){ 15 | if(n->gate_idx == (gate_order.size()-1)) return 1; 16 | else return 0; 17 | } 18 | 19 | void Backtrack::print_perm(map *qmap){ 20 | for(int i=0; iqubits.size(); i++){ 21 | cout << "Q" << C->qubits[i]->id << " : " << (*qmap)[C->qubits[i]] << endl; 22 | } 23 | } 24 | 25 | void change_perm(map *qmap, map *hw_map, vector *spath){ 26 | int i; 27 | int s1, s2; 28 | for(i=0; isize()-1; i++){ 29 | s1 = spath->at(i); 30 | s2 = spath->at(i+1); 31 | //swap hw qubits 32 | Qubit *tmp = hw_map->at(s1); 33 | (*hw_map)[s1] = hw_map->at(s2); 34 | (*hw_map)[s2] = tmp; 35 | //adjust entries in qmap 36 | Qubit *p1 = hw_map->at(s1); 37 | Qubit *p2 = hw_map->at(s2); 38 | if(p1 != 0){ 39 | (*qmap)[p1] = s1; 40 | } 41 | if(p2 != 0){ 42 | (*qmap)[p2] = s2; 43 | } 44 | } 45 | } 46 | 47 | BacktrackNode* Backtrack::create_child(BacktrackNode *parent, swap_decision option){ 48 | BacktrackNode *c = new BacktrackNode; 49 | c->parent = parent; 50 | c->reliab = parent->reliab; 51 | c->gate_idx = parent->gate_idx + 1; 52 | c->decision = option; 53 | c->qubit_map = parent->qubit_map; 54 | c->hw_map = parent->hw_map; 55 | all_nodes.push_back(c); 56 | Gate *g = gate_order[c->gate_idx]; 57 | float gate_reliab; 58 | 59 | int hwq1 = parent->qubit_map[g->vars[0]]; 60 | int hwq2 = parent->qubit_map[g->vars[1]]; 61 | 62 | SwapInfo *s = (*(M->swap_info[hwq1]))[hwq2]; 63 | c->s = s; 64 | 65 | assert(s->c == hwq1); 66 | assert(s->t == hwq2); 67 | 68 | float c2te_swap_reliab = s->c2te_swap_reliab; 69 | float te2t_cx_reliab = s->te2t_cx_reliab; 70 | float t2ce_swap_reliab = s->t2ce_swap_reliab; 71 | float c2ce_cx_reliab = s->c2ce_cx_reliab; 72 | if(option == CtrlRestore){ 73 | gate_reliab = c2te_swap_reliab + te2t_cx_reliab + c2te_swap_reliab; 74 | }else if(option == TargRestore){ 75 | gate_reliab = t2ce_swap_reliab + c2ce_cx_reliab + t2ce_swap_reliab; 76 | }else if(option == CtrlNotRestore){ 77 | gate_reliab = c2te_swap_reliab + te2t_cx_reliab; 78 | change_perm(&(c->qubit_map), &(c->hw_map), s->c2te_path); 79 | }else if(option == TargNotRestore){ 80 | gate_reliab = t2ce_swap_reliab + c2ce_cx_reliab; 81 | change_perm(&(c->qubit_map), &(c->hw_map), s->t2ce_path); 82 | } 83 | 84 | c->reliab = c->reliab + gate_reliab; 85 | return c; 86 | } 87 | 88 | void print_int_vector(vector *v, string name){ 89 | cout << name << endl; 90 | for(int i=0; isize(); i++){ 91 | cout << v->at(i) << " "; 92 | } 93 | cout << endl; 94 | } 95 | void Backtrack::print_trace(BacktrackNode *n, BacktrackNode *root){ 96 | BacktrackNode *parent = n; 97 | 98 | while (n != root) { 99 | Gate *g = gate_order[n->gate_idx]; 100 | cout << "N:" << n->gate_idx << "D:" << n->decision << "\t"; 101 | g->print(); 102 | print_perm(&(n->qubit_map)); 103 | if(n->decision == 2){ 104 | print_int_vector(n->s->c2te_path, "C2TE"); 105 | } 106 | if(n->decision == 3){ 107 | print_int_vector(n->s->t2ce_path, "T2CE"); 108 | } 109 | n = n->parent; 110 | cout << "----\n"; 111 | } 112 | print_perm(&(root->qubit_map)); 113 | } 114 | 115 | map Backtrack::get_solution(int apply_first_gate_check){ 116 | BacktrackNode *n = best_leaf; 117 | map sol; 118 | while (n != root){ 119 | Gate *g = gate_order[n->gate_idx]; 120 | sol[g] = new BacktrackSolution; 121 | BacktrackSolution *s = sol[g]; 122 | s->decision = n->decision; 123 | s->post_perm = n->qubit_map; 124 | s->pre_perm = n->parent->qubit_map; 125 | s->sinfo = n->s; 126 | //s->bnode = n; 127 | n = n->parent; 128 | } 129 | if (apply_first_gate_check) { 130 | if (sol[gate_order[0]]->decision == CtrlNotRestore 131 | || sol[gate_order[0]]->decision == TargNotRestore) { 132 | BacktrackSolution *s = sol[gate_order[0]]; 133 | s->decision = CtrlRestore; 134 | s->pre_perm = s->post_perm; 135 | root->qubit_map = s->post_perm; 136 | for (int i = 0; i < C->qubits.size(); i++) { 137 | Qubit *qi = C->qubits[i]; 138 | int hw_qubit = root->qubit_map[qi]; 139 | root->hw_map[hw_qubit] = qi; 140 | } 141 | 142 | int hwq1 = root->qubit_map[gate_order[0]->vars[0]]; 143 | int hwq2 = root->qubit_map[gate_order[0]->vars[1]]; 144 | s->sinfo = (*(M->swap_info[hwq1]))[hwq2]; 145 | *orig_mapping = root->qubit_map; 146 | } 147 | } 148 | return sol; 149 | } 150 | 151 | int Backtrack::check_if_backtracking_required(BacktrackNode *n){ 152 | if(M->machine_name == "tion") return 0; 153 | int gidx = n->gate_idx; 154 | assert(!is_leaf(n)); 155 | Gate *g = gate_order[gidx+1]; //g is the next gate 156 | Qubit *q1 = g->vars[0]; 157 | Qubit *q2 = g->vars[1]; 158 | auto qmap = n->qubit_map; 159 | if(n != root){ 160 | qmap = n->parent->qubit_map; 161 | } 162 | int hw1 = qmap[q1]; 163 | int hw2 = qmap[q2]; 164 | if(M->is_edge(hw1, hw2)){ 165 | return 0; 166 | }else{ 167 | return 1; 168 | } 169 | } 170 | 171 | #if 0 172 | void Backtrack::solve(BacktrackNode *n){ 173 | if(is_leaf(n)) cout << "Saw a leaf" << n->gate_idx << "\n"; 174 | if(n == root || !is_leaf(n)){ 175 | int i; 176 | if (check_if_backtracking_required(n)) { 177 | n->child.push_back(create_child(n, CtrlRestore)); 178 | n->child.push_back(create_child(n, TargRestore)); 179 | n->child.push_back(create_child(n, CtrlNotRestore)); 180 | n->child.push_back(create_child(n, TargNotRestore)); 181 | for (i = 0; i < 4; i++) { 182 | if (n->child[i]->reliab < best_reliab) 183 | solve(n->child[i]); 184 | } 185 | } else { 186 | n->child.push_back(create_child(n, CtrlRestore)); 187 | if (n->child[0]->reliab < best_reliab){ 188 | cout << "Issuing solve for a child\n"; 189 | solve(n->child[0]); 190 | cout << "Returned from only child\n"; 191 | } 192 | } 193 | 194 | if(n == root){ 195 | cout << "Best reliab:" << exp(-best_reliab) << endl; 196 | print_trace(best_leaf, root); 197 | } 198 | }else{ 199 | if(n->reliab < best_reliab){ 200 | cout << "Updated best leaf" << n->gate_idx << " " << n->decision << "\n"; 201 | cout << exp(-n->reliab) << " " << exp(-best_reliab); 202 | best_reliab = n->reliab; 203 | best_leaf = n; 204 | } 205 | return; 206 | } 207 | } 208 | #endif 209 | 210 | void Backtrack::solve(BacktrackNode *n, int consider_measurements){ 211 | if(!is_leaf(n)){ 212 | if(CompilerAlgorithm == CompileOpt && check_if_backtracking_required(n)){ 213 | n->child.push_back(create_child(n, CtrlRestore)); 214 | n->child.push_back(create_child(n, TargRestore)); 215 | n->child.push_back(create_child(n, CtrlNotRestore)); 216 | n->child.push_back(create_child(n, TargNotRestore)); 217 | for (int i = 0; i < 4; i++) { 218 | if (n->child[i]->reliab < best_reliab) 219 | solve(n->child[i], consider_measurements); 220 | } 221 | }else{ 222 | if(CompilerAlgorithm == CompileOpt){ 223 | n->child.push_back(create_child(n, CtrlRestore)); 224 | }else if(CompilerAlgorithm == CompileDijkstra){ 225 | n->child.push_back(create_child(n, CtrlNotRestore)); 226 | }else if(CompilerAlgorithm == CompileRevSwaps){ 227 | n->child.push_back(create_child(n, CtrlRestore)); 228 | }else; 229 | 230 | if (n->child[0]->reliab < best_reliab){ 231 | solve(n->child[0], consider_measurements); 232 | } 233 | } 234 | 235 | if(n == root){ 236 | cout << "Best reliab:" << exp(-best_reliab) << endl; 237 | //print_trace(best_leaf, root); 238 | } 239 | 240 | 241 | } else { 242 | Gate *g = gate_order[n->gate_idx]; 243 | //Assume all the program qubits are measured at the leaf 244 | if (consider_measurements) { 245 | float measure_reliab = 0; 246 | for (auto qmap_entry : n->qubit_map) { 247 | measure_reliab = measure_reliab 248 | - log(M->m_reliab[qmap_entry.second]); 249 | } 250 | n->reliab = n->reliab + measure_reliab; 251 | } 252 | if (n->reliab < best_reliab) { 253 | best_reliab = n->reliab; 254 | best_leaf = n; 255 | } 256 | return; 257 | } 258 | } 259 | 260 | void Backtrack::init(std::map *initial_map, vector *top_order){ 261 | int i; 262 | for(i=0; isize(); i++){ 263 | Gate *Gi = (*top_order)[i]; 264 | if(typeid(*Gi) == typeid(CNOT)){ 265 | gate_order.push_back(Gi); 266 | } 267 | } 268 | best_reliab = 1000; 269 | root = new BacktrackNode; 270 | root->parent = 0; 271 | root->gate_idx = -1; 272 | root->reliab = 0; 273 | root->qubit_map = *initial_map; 274 | orig_mapping = initial_map; 275 | 276 | for(int i=0; iqubits.size(); i++){ 277 | root->hw_map[M->qubits[i]->id] = 0; 278 | } 279 | 280 | for(int i=0; iqubits.size(); i++){ 281 | Qubit *qi = C->qubits[i]; 282 | int hw_qubit = (*initial_map)[qi]; 283 | root->hw_map[hw_qubit] = qi; 284 | } 285 | } 286 | 287 | map BacktrackFiniteLookahead::solve(){ 288 | for(unsigned int i=0; i 0){ 296 | num_chunks += 1; 297 | } 298 | 299 | unsigned idx=0; 300 | double est_reliab = 1.0; 301 | vector > solution_dump; 302 | for(int i=0; i chunk; 304 | for(int j=0; j bsol = B.get_solution(0); 317 | solution_dump.push_back(bsol); 318 | for(auto item : bsol){ 319 | Gate *Gi = item.first; 320 | BacktrackSolution *Bi = item.second; 321 | final_solution[Gi] = Bi; 322 | } 323 | //adjust qubit mapping using last item's post perm 324 | qubit_mapping = final_solution[chunk.back()]->post_perm; 325 | double chunk_reliab = exp(-B.best_reliab); 326 | est_reliab *= chunk_reliab; 327 | B.cleanup(); 328 | } 329 | for(auto item : qubit_mapping){ 330 | int hw_qid = item.second; 331 | est_reliab *= M->m_reliab[hw_qid]; 332 | } 333 | cout << "EST_RELIAB:" << est_reliab << endl; 334 | 335 | return final_solution; 336 | } 337 | -------------------------------------------------------------------------------- /src/backtrack.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * backtrack.hpp 3 | * 4 | * Created on: Sep 10, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef BACKTRACK_HPP_ 9 | #define BACKTRACK_HPP_ 10 | 11 | #include "headers.hpp" 12 | #include "gate.hpp" 13 | #include "qubit.hpp" 14 | #include "machine.hpp" 15 | #include "circuit.hpp" 16 | 17 | class Circuit; 18 | 19 | enum swap_decision{ 20 | CtrlRestore, TargRestore, CtrlNotRestore, TargNotRestore 21 | }; 22 | 23 | 24 | class BacktrackNode{ 25 | public: 26 | int gate_idx; 27 | swap_decision decision; 28 | BacktrackNode* parent; 29 | vector child; 30 | std::map qubit_map; //this is a post-perm i.e., the decision has been applied 31 | std::map hw_map; 32 | float reliab; 33 | SwapInfo *s; 34 | }; 35 | 36 | 37 | struct BacktrackSolution{ 38 | std::map pre_perm; 39 | std::map post_perm; 40 | SwapInfo *sinfo; 41 | swap_decision decision; 42 | //BacktrackNode *bnode; 43 | }; 44 | 45 | 46 | class Backtrack{ 47 | public: 48 | Circuit *C; 49 | Machine *M; 50 | vector gate_order; 51 | BacktrackNode *root; 52 | 53 | BacktrackNode *best_leaf; 54 | float best_reliab; 55 | std::map *orig_mapping; 56 | vector all_nodes; 57 | 58 | Backtrack(Circuit *pC, Machine *pM){ 59 | C = pC; 60 | M = pM; 61 | } 62 | ~Backtrack(){ 63 | 64 | } 65 | void init(std::map *initial_map, vector *top_order); 66 | int is_leaf(BacktrackNode *n); 67 | void solve(BacktrackNode *n, int consider_measurements); 68 | BacktrackNode* create_child(BacktrackNode *parent, swap_decision option); 69 | void print_trace(BacktrackNode *n, BacktrackNode *root); 70 | void print_perm(map *qmap); 71 | map get_solution(int apply_first_gate_check); 72 | int check_if_backtracking_required(BacktrackNode *n); 73 | void cleanup(){ 74 | for(auto v : all_nodes){ 75 | delete v; 76 | } 77 | } 78 | }; 79 | 80 | /* take care of cnot empty chunks */ 81 | class BacktrackFiniteLookahead{ 82 | public: 83 | Circuit *C; 84 | Machine *M; 85 | vector input_gate_order; 86 | vector cx_order; 87 | map qubit_mapping; 88 | map final_solution; 89 | int chunk_size; 90 | 91 | BacktrackFiniteLookahead(Circuit *pC, Machine *pM, vector GateOrder, std::map InitialMapping, int chunkSize=20){ 92 | C = pC; 93 | M = pM; 94 | input_gate_order = GateOrder; 95 | qubit_mapping = InitialMapping; 96 | chunk_size = chunkSize; 97 | } 98 | 99 | map solve(); 100 | }; 101 | #endif /* BACKTRACK_HPP_ */ 102 | -------------------------------------------------------------------------------- /src/circuit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * circuit.cpp 3 | * 4 | * Created on: Sep 3, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "headers.hpp" 9 | #include "circuit.hpp" 10 | #include "qubit.hpp" 11 | #include "optimize_1q.hpp" 12 | 13 | void Circuit::load_from_file(string fname) { 14 | ifstream fileIn; 15 | cout << "Reading " << fname << endl; 16 | fileIn.open(fname.c_str()); 17 | int nQ, nG; 18 | fileIn >> nQ >> nG; 19 | int i; 20 | 21 | ProgQubit *pQ = 0; 22 | for (i = 0; i < nQ; i++){ 23 | pQ = new ProgQubit(i); 24 | qubits.push_back(pQ); 25 | } 26 | vector< vector* > gatePred; 27 | for (i = 0; i < nG; i++) { 28 | int gate_id; 29 | string gate_type; 30 | fileIn >> gate_id >> gate_type; 31 | Gate *pG = Gate::create_new_gate(gate_type); 32 | pG->id = gate_id; 33 | int nvars_check; 34 | fileIn >> nvars_check; 35 | assert(nvars_check == pG->nvars); 36 | 37 | int tmp; 38 | for (int j = 0; j < pG->nvars; j++) { 39 | fileIn >> tmp; 40 | pG->vars.push_back(qubits[tmp]); 41 | } 42 | 43 | vector * my_pred = new vector ; 44 | int npred; 45 | fileIn >> npred; 46 | for (int j = 0; j < npred; j++) { 47 | fileIn >> tmp; 48 | my_pred->push_back(tmp); 49 | } 50 | gatePred.push_back(my_pred); 51 | gates.push_back(pG); 52 | } 53 | for(i=0; ipred.push_back(pDep); 59 | pDep->succ.push_back(pG); 60 | } 61 | delete gatePred[i]; 62 | } 63 | fileIn.close(); 64 | } 65 | 66 | void Circuit::_add_dependency_for_gate(Gate *g, BacktrackSolution *bs){ 67 | SwapInfo *sinfo = bs->sinfo; 68 | vector *swap_seq; 69 | if(bs->decision == CtrlRestore || bs->decision == CtrlNotRestore){ 70 | swap_seq = sinfo->c2te_path; 71 | }else{ 72 | swap_seq = sinfo->t2ce_path; 73 | } 74 | if (swap_seq->size() > 1) { 75 | auto dep = can_overlap_set(g); 76 | set delete_set; 77 | //auto dep = require_dependency_edge(g, gate_order); 78 | vector dep_list; 79 | if (!dep.empty()) { 80 | for(auto d : dep) dep_list.push_back(d); 81 | for (unsigned int i = 0; i < dep_list.size() - 1; i++) { 82 | auto desc_set = descendants(dep_list[i]); 83 | for (unsigned int j = i + 1; j < dep_list.size(); j++) { 84 | if (desc_set.find(dep_list[j]) != desc_set.end()) { 85 | delete_set.insert(dep_list[j]); 86 | } 87 | } 88 | } 89 | for(auto d : dep){ 90 | if(delete_set.find(d) == delete_set.end()){ 91 | //insert dependency between g and d 92 | //Note: this should by default avoid cyclic dependencies between parallel cnots because of topological ordering of the gates 93 | /* 94 | g->succ.push_back(d); 95 | d->pred.push_back(g); 96 | cout << "added dep " << g->id << " to " << d->id << endl; 97 | sched_depends.push_back(make_pair(g, d)); 98 | */ 99 | g->pred.push_back(d); 100 | d->succ.push_back(g); 101 | cout << "added dep " << d->id << " to " << g->id << endl; 102 | sched_depends.push_back(make_pair(d, g)); 103 | 104 | } 105 | } 106 | } 107 | } 108 | 109 | } 110 | 111 | void Circuit::add_scheduling_dependency(vector *gate_order, map bsol){ 112 | for(auto g: *gate_order){ 113 | if(g->vars.size() == 1){ 114 | continue; 115 | }else if(g->vars.size() == 2){ 116 | BacktrackSolution *bs = bsol[g]; 117 | _add_dependency_for_gate(g, bs); 118 | } 119 | } 120 | } 121 | 122 | struct Vertex{ 123 | string name; 124 | }; 125 | 126 | void Circuit::print_dot_file(string fname){ 127 | 128 | typedef boost::adjacency_list CircuitGraph; 130 | 131 | typedef boost::graph_traits::vertex_descriptor vertex_descriptor; 132 | CircuitGraph cgraph; 133 | 134 | map V; 135 | for (auto g : gates) { 136 | Vertex *testv = new Vertex; 137 | stringstream vname; 138 | vname << g->id << " "; 139 | vname << g->printStr << " "; 140 | for(auto qb : g->vars){ 141 | vname << qb->id << " "; 142 | } 143 | testv->name = vname.str(); 144 | V[g] = boost::add_vertex(*testv, cgraph); 145 | } 146 | 147 | for (auto g : gates) { 148 | for (auto s : g->succ) { 149 | boost::add_edge(V[g], V[s], cgraph); 150 | } 151 | //for(auto p : g->pred){ 152 | // boost::add_edge(V[g], V[p], cgraph); 153 | //} 154 | } 155 | ofstream outFile; 156 | outFile.open(fname.c_str()); 157 | write_graphviz(outFile, cgraph, 158 | make_label_writer(boost::get(&Vertex::name, cgraph))); 159 | } 160 | 161 | int Circuit::check_use_qubit(Gate *g, Qubit *q) { 162 | if (find(g->vars.begin(), g->vars.end(), q) != g->vars.end()) { 163 | return 1; 164 | } else { 165 | return 0; 166 | } 167 | } 168 | 169 | void Circuit::replace_with_chain(vector in_gates, vector out_gates){ 170 | Gate *front, *back; 171 | /*cout << "replacing:\n"; 172 | for(auto in_g : in_gates) in_g->print(); 173 | cout << "with:\n"; 174 | for(auto out_g : out_gates) out_g->print(); 175 | cout << "\n";*/ 176 | 177 | if(!out_gates.empty()){ 178 | front = out_gates[0]; 179 | back = out_gates[out_gates.size()-1]; 180 | } 181 | 182 | //list of predecessors 183 | std::set pred_gates; 184 | for(auto g : in_gates){ 185 | for(auto p : g->pred){ 186 | pred_gates.insert(p); 187 | } 188 | } 189 | //remove in_gates from the set of predecessors 190 | for(auto g : in_gates){ 191 | pred_gates.erase(g); 192 | } 193 | 194 | //remove in_gates from the predecessors' succ list and add front 195 | for(auto p : pred_gates){ 196 | for(auto g : in_gates){ 197 | p->succ.erase(std::remove(p->succ.begin(), p->succ.end(), g), p->succ.end()); 198 | } 199 | if(out_gates.size()){ 200 | p->succ.push_back(front); 201 | front->pred.push_back(p); 202 | } 203 | } 204 | 205 | std::set succ_gates; 206 | for(auto g : in_gates){ 207 | for(auto s : g->succ){ 208 | succ_gates.insert(s); 209 | } 210 | } 211 | 212 | //remove in_gates from the set of successors 213 | for(auto g : in_gates){ 214 | succ_gates.erase(g); 215 | } 216 | 217 | for(auto p : pred_gates){ 218 | succ_gates.erase(p); 219 | } 220 | 221 | //remove in_gates from successors' pred list and add back 222 | for(auto s : succ_gates){ 223 | for(auto g : in_gates){ 224 | s->pred.erase(std::remove(s->pred.begin(), s->pred.end(), g), s->pred.end()); 225 | } 226 | if (!out_gates.empty()) { 227 | s->pred.push_back(back); 228 | back->succ.push_back(s); 229 | } 230 | } 231 | 232 | if (!out_gates.empty()) { 233 | //interlink the out gates 234 | for (unsigned int i = 0; i < out_gates.size()-1; i++) { 235 | Gate *g1 = out_gates[i]; 236 | Gate *g2 = out_gates[i + 1]; 237 | g1->succ.push_back(g2); 238 | g2->pred.push_back(g1); 239 | } 240 | for (auto g : out_gates) { 241 | gates.push_back(g); 242 | } 243 | } 244 | 245 | for(auto g : in_gates){ 246 | gates.erase(std::remove(gates.begin(), gates.end(), g), gates.end()); 247 | } 248 | //for(auto out_g : out_gates) out_g->print(); 249 | 250 | 251 | } 252 | 253 | void Circuit::optimize_1q_gate_sequence() { 254 | for(auto q : qubits){ 255 | cout << "Run extraction:" << q->id << endl; 256 | auto torder = topological_ordering(); 257 | vector run_of_1q_gates; 258 | for (auto g : *torder) { 259 | if (check_use_qubit(g, q)) { 260 | if(typeid(*g) != typeid(CNOT)){ 261 | run_of_1q_gates.push_back(g); 262 | } else{ 263 | if(run_of_1q_gates.size() > 0){ 264 | cout << "Gate run: "; 265 | for(auto it : run_of_1q_gates){ 266 | it->print(); 267 | } 268 | Optimize1QGates opt(run_of_1q_gates); 269 | opt.optimize(); 270 | vector new_gates = opt.get_optimized_gates(); 271 | for(auto ngate : new_gates){ 272 | ngate->vars.push_back(q); 273 | } 274 | //replace_with_chain(run_of_1q_gates, new_gates); 275 | } 276 | run_of_1q_gates.clear(); 277 | } 278 | } 279 | } 280 | } 281 | 282 | } 283 | 284 | vector *Circuit::topological_ordering(){ 285 | std::queue q; 286 | std::vector *ans = new std::vector; 287 | std::map in_degree; 288 | for(auto Gi : gates){ 289 | in_degree[Gi] = Gi->pred.size(); 290 | if(in_degree[Gi] == 0){ 291 | q.push(Gi); 292 | } 293 | } 294 | while(!q.empty()){ 295 | Gate *front = q.front(); 296 | q.pop(); 297 | ans->push_back(front); 298 | for(auto s : front->succ){ 299 | in_degree[s]--; 300 | if(in_degree[s] == 0) q.push(s); 301 | } 302 | } 303 | for(auto g : gates){ 304 | if(in_degree[g] != 0){ 305 | cout << "Warning\n"; 306 | g->print(); 307 | } 308 | //assert(in_degree[g] == 0); 309 | } 310 | return ans; 311 | } 312 | 313 | set Circuit::descendants(Gate *g){ 314 | map is_visited; 315 | for(auto g : gates){ 316 | is_visited[g->id] = -1; 317 | } 318 | std::queue bfs_queue; 319 | std::set ans; 320 | bfs_queue.push(g); 321 | is_visited[g->id] = 1; 322 | 323 | while(!bfs_queue.empty()){ 324 | Gate *f = bfs_queue.front(); 325 | bfs_queue.pop(); 326 | if(f != g){ 327 | ans.insert(f); 328 | } 329 | for(auto s : f->succ){ 330 | if(is_visited[s->id] != 1){ 331 | bfs_queue.push(s); 332 | is_visited[s->id] = 1; 333 | } 334 | } 335 | } 336 | return ans; 337 | } 338 | 339 | set Circuit::ancestors(Gate *g){ 340 | map is_visited; 341 | for(auto g : gates){ 342 | is_visited[g->id] = -1; 343 | } 344 | std::queue bfs_queue; 345 | std::set ans; 346 | bfs_queue.push(g); 347 | is_visited[g->id] = 1; 348 | while(!bfs_queue.empty()){ 349 | Gate *f = bfs_queue.front(); 350 | bfs_queue.pop(); 351 | if(f != g){ 352 | ans.insert(f); 353 | } 354 | for(auto p : f->pred){ 355 | if(is_visited[p->id] != 1){ 356 | bfs_queue.push(p); 357 | is_visited[p->id] = 1; 358 | } 359 | } 360 | } 361 | return ans; 362 | } 363 | 364 | int Circuit::is_descendant(Gate *g1, Gate *g2){ 365 | if(g1 == g2) return 0; 366 | set B = descendants(g1); 367 | for(auto it : B){ 368 | if(it == g2){ 369 | return 1; 370 | } 371 | } 372 | return 0; 373 | } 374 | 375 | set Circuit::can_overlap_set(Gate *g){ 376 | set A = ancestors(g); 377 | set B = descendants(g); 378 | B.insert(g); 379 | set all_gates; 380 | for(auto g : gates){ 381 | all_gates.insert(g); 382 | } 383 | 384 | for(set::iterator it = A.begin(); it != A.end(); it++){ 385 | all_gates.erase(*it); 386 | } 387 | for(set::iterator it = B.begin(); it != B.end(); it++){ 388 | all_gates.erase(*it); 389 | } 390 | #if 0 391 | //set transitive_deps; 392 | for(auto it1 = all_gates.begin(); it1 != all_gates.end(); it1++){ 393 | for(auto it2 = all_gates.begin(); it2 != all_gates.end(); it2++){ 394 | int is_d = is_descendant(*it1, *it2); 395 | if(is_d){ 396 | all_gates.erase(*it2); 397 | //transitive_deps.insert(*it2); 398 | } 399 | } 400 | } 401 | /* 402 | for(set::iterator it = transitive_deps.begin(); it != transitive_deps.end(); it++){ 403 | all_gates.erase(*it); 404 | } 405 | */ 406 | 407 | for(auto it1 = all_gates.begin(); it1 != all_gates.end(); it1++){ 408 | for(auto it2 = all_gates.begin(); it2 != all_gates.end(); it2++){ 409 | int is_d = is_descendant(*it1, *it2); 410 | assert(is_d == 0); 411 | } 412 | } 413 | #endif 414 | return all_gates; 415 | } 416 | 417 | //extra dependencies should be added only in the topological order, otherwise there will be cyclic dependencies 418 | set Circuit::require_dependency_edge(Gate *g, vector* gate_order){ 419 | set can_overlap = can_overlap_set(g); 420 | set req_overlap; 421 | //todo pick out hte right gates heres 422 | vector::iterator it; 423 | it = find(gate_order->begin(), gate_order->end(), g); 424 | if(it == gate_order->end()){ 425 | assert(0); 426 | } 427 | for(; it!=gate_order->end(); it++){ 428 | if(can_overlap.find(*it) != can_overlap.end()){ 429 | req_overlap.insert(*it); 430 | } 431 | } 432 | return req_overlap; 433 | } 434 | 435 | void Circuit::enforce_topological_ordering(vector* gate_order){ 436 | for(auto g : gates){ 437 | auto dep = require_dependency_edge(g, gate_order); 438 | for(auto d : dep){ 439 | //cout << g->id << " " << d->id << "needs dependency" << endl; 440 | if(g->nvars == 1 && d->nvars == 1){ 441 | continue; 442 | } 443 | g->succ.push_back(d); 444 | d->pred.push_back(g); 445 | } 446 | } 447 | #if 0 448 | for (auto q : qubits) { 449 | vector my_gates; 450 | for (auto g : *gate_order) { 451 | if (check_use_qubit(g, q)) { 452 | my_gates.push_back(g); 453 | } 454 | } 455 | for(int i=0; isucc.begin(), c->succ.end(), n) == c->succ.end()){ 459 | c->succ.push_back(n); 460 | } 461 | 462 | if(find(n->pred.begin(), n->pred.end(), c) == n->pred.end()){ 463 | n->pred.push_back(c); 464 | } 465 | } 466 | } 467 | #endif 468 | 469 | } 470 | 471 | 472 | void Circuit::duplicate_circuit(Circuit *C, map *old2new){ 473 | C->qubits = qubits; //same set of qubits 474 | C->gates.clear(); 475 | 476 | for(auto g_old : gates){ 477 | Gate *g_new = Gate::create_new_gate(g_old->printStr); 478 | g_new->vars = g_old->vars; 479 | C->gates.push_back(g_new); 480 | (*old2new)[g_old] = g_new; 481 | } 482 | for(auto g_old : gates){ 483 | Gate *g_new = (*old2new)[g_old]; 484 | for(unsigned int j=0; jpred.size(); j++){ 485 | g_new->pred.push_back((*old2new)[g_old->pred[j]]); 486 | } 487 | for (unsigned int j = 0; j < g_old->succ.size(); j++) { 488 | g_new->succ.push_back((*old2new)[g_old->succ[j]]); 489 | } 490 | } 491 | for(auto p : sched_depends){ 492 | Gate *old_g1 = p.first; 493 | Gate *old_g2 = p.second; 494 | Gate *new_g1 = (*old2new)[old_g1]; 495 | Gate *new_g2 = (*old2new)[old_g2]; 496 | C->sched_depends.push_back(make_pair(new_g1, new_g2)); 497 | } 498 | } 499 | /** 500 | * Re-write circuit using mapping and machine qubits 501 | */ 502 | Circuit* Circuit::rewrite_with_mapping(std::map *qubit_map, Machine *M){ 503 | Circuit *C = new Circuit(); 504 | assert(this->qubits.size() <= M->qubits.size()); 505 | C->qubits = M->qubits; // can use any hardware qubit 506 | 507 | map old2new; 508 | 509 | for(unsigned int i=0; igates.size(); i++){ 510 | Gate *g_old = this->gates[i]; 511 | Gate *g_new = Gate::create_new_gate(g_old->printStr); //TODO 512 | //g_new->id = g_old->id; 513 | C->gates.push_back(g_new); 514 | old2new[g_old] = g_new; 515 | } 516 | 517 | for(unsigned int i=0; igates.size(); i++){ 518 | Gate *g_old = this->gates[i]; 519 | Gate *g_new = C->gates[i]; 520 | for(int j=0; jnvars; j++){ 521 | int qid_new = (*qubit_map)[g_old->vars[j]]; 522 | g_new->vars.push_back(M->qubits[qid_new]); 523 | } 524 | } 525 | 526 | for(unsigned int i=0; igates.size(); i++){ 527 | Gate *g_old = this->gates[i]; 528 | Gate *g_new = C->gates[i]; 529 | for(unsigned int j=0; jpred.size(); j++){ 530 | g_new->pred.push_back(old2new[g_old->pred[j]]); 531 | } 532 | for (unsigned int j = 0; j < g_old->succ.size(); j++) { 533 | g_new->succ.push_back(old2new[g_old->succ[j]]); 534 | } 535 | } 536 | return C; 537 | } 538 | 539 | 540 | void Circuit::print_sched_depends(){ 541 | cout << "Scheduling dependencies:\n"; 542 | if(sched_depends.empty()){ 543 | cout << "No dependencies\n"; 544 | return; 545 | } 546 | for(auto p : sched_depends){ 547 | p.first->print(); 548 | cout << "-> "; 549 | p.second->print(); 550 | } 551 | cout << endl; 552 | } 553 | void Circuit::print_gates(){ 554 | cout << "Gates" << endl; 555 | for(auto g : gates){ 556 | g->print(); 557 | } 558 | } 559 | 560 | 561 | Circuit::~Circuit(){ 562 | for(auto g : gates){ 563 | delete g; 564 | } 565 | } 566 | -------------------------------------------------------------------------------- /src/circuit.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * circuit.hpp 3 | * 4 | * Created on: Sep 2, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef CIRCUIT_HPP_ 9 | #define CIRCUIT_HPP_ 10 | 11 | #include "headers.hpp" 12 | #include "qubit.hpp" 13 | #include "gate.hpp" 14 | #include "machine.hpp" 15 | #include "backtrack.hpp" 16 | 17 | class BacktrackSolution; 18 | 19 | class Moment{ 20 | public: 21 | int timestamp; 22 | vector gates; 23 | void operate(); 24 | void print_moment(); 25 | void generate_code(); 26 | }; 27 | 28 | class Circuit{ 29 | public: 30 | vector qubits; 31 | vector gates; 32 | vector moments; 33 | 34 | vector > sched_depends; 35 | 36 | void load_from_file(string fname); 37 | void load_from_openqasm(string fname); 38 | void create_moments(); 39 | void duplicate_circuit(Circuit *C, map *old2new); 40 | 41 | Circuit *rewrite_with_mapping(std::map *qubit_map, Machine *M); 42 | vector *topological_ordering(); 43 | set descendants(Gate *g); 44 | set ancestors(Gate *g); 45 | set can_overlap_set(Gate *g); 46 | set require_dependency_edge(Gate *g, vector* gate_order); 47 | void enforce_topological_ordering(vector *gate_order); 48 | void add_scheduling_dependency(vector *gate_order, map bsol); 49 | void _add_dependency_for_gate(Gate *g, BacktrackSolution *bs); 50 | void optimize_1q_gate_sequence(); 51 | void replace_with_chain(vector in_gates, vector out_gates); 52 | 53 | void print_sched_depends(); 54 | int check_use_qubit(Gate *g, Qubit *q); 55 | int is_descendant(Gate *g1, Gate *g2); 56 | void print_dot_file(string fname); 57 | 58 | void print_gates(); 59 | void print_moments(); 60 | void generate_code(); 61 | ~Circuit(); 62 | }; 63 | #endif /* CIRCUIT_HPP_ */ 64 | -------------------------------------------------------------------------------- /src/expt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * expt.cpp 3 | * 4 | * Created on: Sep 2, 2018 5 | * Author: prakash 6 | */ 7 | #include "headers.hpp" 8 | #include "circuit.hpp" 9 | #include "mapper.hpp" 10 | #include "machine.hpp" 11 | #include "pattern.hpp" 12 | #include "backtrack.hpp" 13 | #include "targetter.hpp" 14 | #include "optimize_1q.hpp" 15 | 16 | int CompilerAlgorithm; 17 | int ErrorScaleFactor=1; 18 | 19 | int MyGetTime(){ 20 | struct timespec ts_time_now; 21 | clock_gettime(CLOCK_MONOTONIC, &ts_time_now); 22 | return(ts_time_now.tv_sec); 23 | } 24 | 25 | 26 | void compile_and_print_for_machine(string progName, string outName, string machineName, int algorithm, 27 | int aerNQ=0, string aer_data_file="", string aer_partition_file="", int aer_num_partitions=0){ 28 | Circuit C; 29 | C.load_from_file(progName); 30 | int t1 = MyGetTime(); 31 | CompilerAlgorithm = algorithm; 32 | if(CompilerAlgorithm == CompileOpt){ 33 | cout << "Running CompileOpt\n"; 34 | }else if(CompilerAlgorithm == CompileDijkstra){ 35 | cout << "Running CompileDijkstra\n"; 36 | }else if(CompilerAlgorithm == CompileRevSwaps){ 37 | cout << "Running CompileRevSwaps\n"; 38 | }else assert(0); 39 | 40 | Machine M(machineName, aerNQ, aer_data_file, aer_partition_file, aer_num_partitions); 41 | Mapper pMapper(&M, &C); 42 | pMapper.set_config(MapSum, VarUnique); 43 | //pMapper.dummy_mapper(); 44 | pMapper.config.approx_factor = 1.001; 45 | pMapper.map_with_z3(); 46 | //pMapper.print_stats(); 47 | vector* torder; 48 | torder = C.topological_ordering(); 49 | C.enforce_topological_ordering(torder); 50 | 51 | map bsol; 52 | int t2 = MyGetTime(); 53 | 54 | int cx_count = 0; 55 | for(auto gi : C.gates){ 56 | if(gi->nvars == 2) cx_count++; 57 | } 58 | if (cx_count < 20) { 59 | Backtrack B(&C, &M); 60 | B.init(&pMapper.qubit_map, torder); 61 | B.solve(B.root, 1); 62 | if (CompilerAlgorithm == CompileOpt) { 63 | bsol = B.get_solution(1); 64 | } else { 65 | bsol = B.get_solution(0); 66 | } 67 | } else { 68 | BacktrackFiniteLookahead B(&C, &M, *torder, pMapper.qubit_map, 10); 69 | bsol = B.solve(); 70 | } 71 | C.add_scheduling_dependency(torder, bsol); 72 | vector* torder_new = C.topological_ordering(); //this ordering incorportes new scheduling edges 73 | Targetter Tgen(&M, &C, &pMapper.qubit_map, torder_new, bsol); 74 | int t3 = MyGetTime(); 75 | cout << "PROG " << progName << " MACHINE " << machineName << " MAPPER_TIME " << t2-t1 << " BACKTRACK_TIME " << t3-t2 << endl; 76 | 77 | Circuit *C_trans=0; 78 | Circuit *C_1q_opt=0; 79 | 80 | if(M.machine_name == "tion"){ 81 | C_trans = Tgen.map_to_trapped_ion(); 82 | OptimizeSingleQubitOps sq_opt(C_trans); 83 | C_1q_opt = sq_opt.test_optimize(); 84 | Tgen.print_code(C_1q_opt, outName); 85 | //Tgen.print_code(C_trans, outName); 86 | }else{ 87 | C_trans = Tgen.map_and_insert_swap_operations(); //We require a mapping to insert swaps 88 | OptimizeSingleQubitOps sq_opt(C_trans); 89 | C_1q_opt = sq_opt.test_optimize(); 90 | Tgen.print_code(C_1q_opt, outName); 91 | //Tgen.print_code(C_trans, outName); 92 | } 93 | 94 | if(C_trans) delete C_trans; 95 | if(C_1q_opt) delete C_1q_opt; 96 | delete torder; 97 | cout << "Done!\n"; 98 | } 99 | 100 | int main(int argc, char **argv){ 101 | //compile_and_print_for_machine("programs/T1.in", "output/test.qasm", "ibmqx5", 0); 102 | compile_and_print_for_machine(argv[1], argv[2], argv[3], atoi(argv[4])); 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /src/gate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * gate.cpp 3 | * 4 | * Created on: Sep 3, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "headers.hpp" 9 | #include "gate.hpp" 10 | 11 | int Gate::id_gen = 0; 12 | 13 | Gate* Gate::create_new_gate(string type){ 14 | Gate *pGate; 15 | if(type == "H"){ 16 | pGate = new H(); 17 | }else if(type == "CNOT"){ 18 | pGate = new CNOT(); 19 | }else if(type == "MeasZ"){ 20 | pGate = new MeasZ(); 21 | }else if(type == "X"){ 22 | pGate = new X(); 23 | }else if(type == "Y"){ 24 | pGate = new Y(); 25 | }else if(type == "Z"){ 26 | pGate = new Z(); 27 | }else if(type == "T"){ 28 | pGate = new T(); 29 | }else if(type == "Tdag"){ 30 | pGate = new Tdag(); 31 | }else if(type == "S"){ 32 | pGate = new S(); 33 | }else if(type == "Sdag"){ 34 | pGate = new Sdag(); 35 | }else if(type == "RX"){ 36 | pGate = new RX(); 37 | }else if(type == "RY"){ 38 | pGate = new RY(); 39 | }else if(type == "RZ"){ 40 | pGate = new RZ(); 41 | }else if(type == "XX"){ 42 | pGate = new XX(); 43 | }else if(type == "SWAP"){ 44 | pGate = new SWAP(); 45 | }else if(type == "U1"){ 46 | pGate = new U1(); 47 | }else if(type == "U2"){ 48 | pGate = new U2(); 49 | }else if(type == "U3"){ 50 | pGate = new U3(); 51 | }else if(type == "CZ"){ 52 | pGate = new CZ(); 53 | } 54 | else{ 55 | assert(0); 56 | } 57 | pGate->id = id_gen; 58 | id_gen++; 59 | return pGate; 60 | } 61 | void Gate::print() { 62 | cout << id << " " << printStr << " " << "Qubits: "; 63 | for (int i = 0; i < nvars; i++) 64 | cout << vars[i]->id << " "; 65 | cout << "Depends on: "; 66 | for (unsigned int i = 0; i < pred.size(); i++) 67 | cout << pred[i]->id << " "; 68 | cout << "Succeeded by: "; 69 | 70 | for (unsigned int i = 0; i < succ.size(); i++) 71 | cout << succ[i]->id << " "; 72 | cout << params; 73 | 74 | cout << endl; 75 | if (printStr == "U1") { 76 | cout << "lambda=" << lambda << "\n"; 77 | } 78 | if (printStr == "U2" || printStr == "U3") { 79 | cout << "theta=" << theta << "\n"; 80 | cout << "phi=" << phi << "\n"; 81 | cout << "lambda=" << lambda << "\n"; 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/gate.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * gate.hpp 3 | * 4 | * Created on: Sep 2, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef GATE_HPP_ 9 | #define GATE_HPP_ 10 | 11 | #include "headers.hpp" 12 | #include "qubit.hpp" 13 | 14 | class Gate{ 15 | public: 16 | static int id_gen; 17 | int id; 18 | int nvars; 19 | string printStr; 20 | std::vector vars; 21 | std::vector pred; 22 | std::vector succ; 23 | string params; 24 | 25 | double angle; 26 | double theta; 27 | double phi; 28 | double lambda; 29 | 30 | virtual void operate() = 0; 31 | virtual ~Gate(){}; 32 | Gate(){ 33 | id = 0; 34 | params = ""; 35 | } 36 | void print(); 37 | static Gate* create_new_gate(string type); 38 | }; 39 | 40 | class SingleQubitGate : public Gate{ 41 | public: 42 | SingleQubitGate(){ 43 | nvars = 1; 44 | } 45 | }; 46 | 47 | class TwoQubitGate : public Gate{ 48 | public: 49 | TwoQubitGate(){ 50 | nvars = 2; 51 | } 52 | }; 53 | 54 | class H : public SingleQubitGate{ 55 | public: 56 | H(){ 57 | printStr = "H"; 58 | } 59 | void operate(){ 60 | std::cout << "H gate\n"; 61 | } 62 | }; 63 | 64 | class X : public SingleQubitGate{ 65 | public: 66 | X(){ 67 | printStr = "X"; 68 | } 69 | void operate(){ 70 | std::cout << "X gate\n"; 71 | } 72 | }; 73 | 74 | class Y : public SingleQubitGate{ 75 | public: 76 | Y(){ 77 | printStr = "Y"; 78 | } 79 | void operate(){ 80 | std::cout << "Y gate\n"; 81 | } 82 | }; 83 | 84 | class Z : public SingleQubitGate{ 85 | public: 86 | Z(){ 87 | printStr = "Z"; 88 | } 89 | void operate(){ 90 | std::cout << "Z gate\n"; 91 | } 92 | }; 93 | 94 | class T : public SingleQubitGate{ 95 | public: 96 | T(){ 97 | printStr = "T"; 98 | } 99 | void operate(){ 100 | std::cout << "T gate\n"; 101 | } 102 | }; 103 | 104 | class Tdag : public SingleQubitGate{ 105 | public: 106 | Tdag(){ 107 | printStr = "Tdag"; 108 | } 109 | void operate(){ 110 | std::cout << "Tdag gate\n"; 111 | } 112 | }; 113 | 114 | class S : public SingleQubitGate{ 115 | public: 116 | S(){ 117 | printStr = "S"; 118 | } 119 | void operate(){ 120 | std::cout << "S gate\n"; 121 | } 122 | }; 123 | 124 | class Sdag : public SingleQubitGate{ 125 | public: 126 | Sdag(){ 127 | printStr = "Sdag"; 128 | } 129 | void operate(){ 130 | std::cout << "Sdag gate\n"; 131 | } 132 | }; 133 | 134 | class U1 : public SingleQubitGate{ 135 | public: 136 | U1(){ 137 | printStr = "U1"; 138 | } 139 | void operate(){ 140 | cout << "U1(" << lambda << ")\n"; 141 | } 142 | }; 143 | 144 | class U2 : public SingleQubitGate{ 145 | public: 146 | U2(){ 147 | printStr = "U2"; 148 | } 149 | void operate(){ 150 | cout << "U2(" << phi << "," << lambda << ")\n"; 151 | } 152 | }; 153 | 154 | class U3 : public SingleQubitGate{ 155 | public: 156 | U3(){ 157 | printStr = "U3"; 158 | } 159 | void operate(){ 160 | cout << "U3(" << theta << "," << phi << "," << lambda << ")\n"; 161 | } 162 | }; 163 | 164 | 165 | class RX : public SingleQubitGate{ 166 | public: 167 | RX(){ 168 | printStr = "RX"; 169 | } 170 | void operate(){ 171 | cout << "RX" << params.at(0) << vars[0]->id << params.at(1) << endl; 172 | } 173 | }; 174 | 175 | class RY : public SingleQubitGate{ 176 | public: 177 | RY(){ 178 | printStr = "RY"; 179 | } 180 | void operate(){ 181 | cout << "RY" << params.at(0) << vars[0]->id << params.at(1) << endl; 182 | 183 | } 184 | }; 185 | 186 | class RZ : public SingleQubitGate{ 187 | public: 188 | RZ(){ 189 | printStr = "RZ"; 190 | } 191 | void operate(){ 192 | cout << "RZ" << params.at(0) << vars[0]->id << params.at(1) << endl; 193 | 194 | } 195 | }; 196 | 197 | 198 | class MeasZ : public SingleQubitGate{ 199 | public: 200 | MeasZ(){ 201 | printStr = "MeasZ"; 202 | } 203 | void operate(){ 204 | cout << "MeasZ " << vars[0]->id << endl; 205 | 206 | } 207 | }; 208 | 209 | class CNOT : public TwoQubitGate{ 210 | public: 211 | CNOT(){ 212 | printStr = "CNOT"; 213 | } 214 | void operate(){ 215 | std::cout << "CNOT gate\n"; 216 | } 217 | }; 218 | 219 | class XX : public TwoQubitGate{ 220 | public: 221 | XX(){ 222 | printStr = "XX"; 223 | } 224 | void operate(){ 225 | cout << "XX" << params.at(0) << vars[0]->id << vars[1]->id << params.at(1) << endl; 226 | } 227 | }; 228 | 229 | class SWAP : public TwoQubitGate{ 230 | public: 231 | SWAP(){ 232 | printStr = "SWAP"; 233 | } 234 | void operate(){ 235 | cout << "SWAP" << vars[0]->id << vars[1]->id << endl; 236 | } 237 | }; 238 | 239 | class CZ : public TwoQubitGate{ 240 | public: 241 | CZ(){ 242 | printStr = "CZ"; 243 | } 244 | void operate(){ 245 | cout << "CZ" << vars[0]->id << vars[1]->id << endl; 246 | } 247 | }; 248 | 249 | #endif /* GATE_HPP_ */ 250 | -------------------------------------------------------------------------------- /src/headers.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * headers.hpp 3 | * 4 | * Created on: Sep 2, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef HEADERS_HPP_ 9 | #define HEADERS_HPP_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | /* Library Dependencies: Boost, Z3 */ 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "z3++.h" 37 | 38 | using namespace std; 39 | const double PI = 3.141592653589793238; 40 | 41 | 42 | enum CompileAlgorithm{ 43 | CompileOpt, CompileDijkstra, CompileRevSwaps 44 | }; 45 | 46 | extern int CompilerAlgorithm; 47 | extern int ErrorScaleFactor; 48 | 49 | #endif /* HEADERS_HPP_ */ 50 | -------------------------------------------------------------------------------- /src/machine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * machine.cpp 3 | * 4 | * Created on: Sep 6, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "headers.hpp" 9 | #include "machine.hpp" 10 | 11 | std::vector* Machine::compute_shortest_sequence(int source, int dest, 12 | std::vector &parents) { 13 | std::vector path; 14 | vertex_descriptor current = dest; 15 | while (current != source) { 16 | path.push_back(current); 17 | current = parents[current]; 18 | } 19 | path.push_back(source); 20 | std::vector *req_path = new std::vector; 21 | std::vector::reverse_iterator it; 22 | for (it = path.rbegin(); it != path.rend(); ++it) { 23 | req_path->push_back(*it); 24 | } 25 | return req_path; 26 | } 27 | 28 | vector< vector* >* Machine::compute_swap_paths_one_vertex(int q) { 29 | std::vector parents(boost::num_vertices(gswap_log)); 30 | std::vector distances(boost::num_vertices(gswap_log)); 31 | boost::dijkstra_shortest_paths(gswap_log, q, 32 | boost::predecessor_map(&parents[0]).distance_map(&distances[0])); 33 | vector < vector * > *req_vector = new vector < vector * >; 34 | 35 | boost::graph_traits < DirectedGraph >::vertex_iterator vertexIterator, vend; 36 | vector *reliab_vector1 = new vector; 37 | vector *reliab_vector2 = new vector; 38 | for (boost::tie(vertexIterator, vend) = boost::vertices(gswap_log); vertexIterator != vend; ++vertexIterator) 39 | { 40 | float d = distances[*vertexIterator]; 41 | if(d != 0){ 42 | reliab_vector1->push_back(d); 43 | reliab_vector2->push_back(log2act(d)); 44 | }else{ 45 | reliab_vector1->push_back(-1); //invalid case 46 | reliab_vector2->push_back(-1); //invalid case 47 | } 48 | } 49 | swap_log_reliab.push_back(reliab_vector1); 50 | t_reliab.push_back(reliab_vector2); 51 | 52 | for(int i=0; ipush_back(compute_shortest_sequence(q, qubits[i]->id, parents)); 54 | } 55 | return req_vector; 56 | } 57 | 58 | void Machine::compute_swap_paths(){ 59 | setup_topology(); 60 | for(int i=0; iid)); 62 | } 63 | 64 | //adjustment for the solver: adjust values in t_reliab for adjacent cx gates 65 | int i; 66 | int u, v; 67 | float cx_cost = 0, rev_cx_cost = 0; 68 | for (i = 0; i < edge_u.size(); i++) { 69 | u = edge_u[i]; 70 | v = edge_v[i]; 71 | cx_cost = edge_reliab[i]; 72 | if (machine_name != "ibmqx5" && machine_name != "ibmqx4" && machine_name != "ibmq_16_melbourne") { 73 | rev_cx_cost = edge_reliab[i]; 74 | } else { 75 | rev_cx_cost = edge_reliab[i] * s_reliab[u] * s_reliab[v] 76 | * s_reliab[u] * s_reliab[v]; 77 | } 78 | (*t_reliab[u])[v] = cx_cost; 79 | (*t_reliab[v])[u] = rev_cx_cost; 80 | } 81 | } 82 | 83 | void Machine::delete_swap_paths(){ 84 | for(int i=0; i* >* p1 = swap_path[i]; 86 | for(int j=0; j *p2 = (*p1)[j]; 88 | delete p2; 89 | } 90 | delete p1; 91 | delete t_reliab[i]; 92 | } 93 | } 94 | 95 | void Machine::print_swap_paths(){ 96 | for(int i=0; i* >* p1 = swap_path[i]; 98 | for(int j=0; j *p2 = (*p1)[j]; 101 | for(int k=0; ksize(); k++){ 102 | cout << (*p2)[k] << " "; 103 | } 104 | cout << "\n"; 105 | } 106 | } 107 | } 108 | 109 | int Machine::determine_entry_point(int q1, int q2){ 110 | assert(q1 != q2); 111 | //iterate through neighbors of q2, determine neighbor with best swap+cx cost 112 | int i; 113 | vector neighbors; 114 | for(i=0; i total_cost; 120 | int entry; 121 | for(i=0; ic = q1; 148 | s->t = q2; 149 | s->te = determine_entry_point(q1, q2); 150 | s->ce = determine_entry_point(q2, q1); 151 | assert(is_edge(s->te, s->t)); 152 | assert(is_edge(s->c, s->ce)); 153 | 154 | if(s->c == s->te) s->c2te_swap_reliab = 0; 155 | else s->c2te_swap_reliab = (*swap_log_reliab[s->c])[s->te]; 156 | 157 | if(s->t == s->ce) s->t2ce_swap_reliab = 0; 158 | else s->t2ce_swap_reliab = (*swap_log_reliab[s->t])[s->ce]; 159 | 160 | s->c2ce_cx_reliab = cx_log_reliab[make_pair(s->c, s->ce)]; 161 | s->te2t_cx_reliab = cx_log_reliab[make_pair(s->te, s->t)]; 162 | 163 | s->c2te_path = (*swap_path[s->c])[s->te]; 164 | s->t2ce_path = (*swap_path[s->t])[s->ce]; 165 | /* 166 | cout << "C:" << q1 << " T:" << q2 << " CE:" << s->ce << " TE:" << s->te << endl; 167 | cout << "C->TE: "; 168 | for(int i=0; i < (s->c2te_path)->size(); i++){ 169 | cout << (*(s->c2te_path))[i] << " "; 170 | } 171 | cout << endl; 172 | cout << "T->CE: "; 173 | for(int i=0; i < (s->t2ce_path)->size(); i++){ 174 | cout << (*(s->t2ce_path))[i] << " "; 175 | } 176 | cout << endl; 177 | */ 178 | } 179 | 180 | void Machine::test_swap_info(int i, int j){ 181 | SwapInfo *sij = (*(swap_info[i]))[j]; 182 | if(i==j) return; 183 | assert(sij->c == sij->c2te_path->at(0)); 184 | assert(sij->te == sij->c2te_path->at(sij->c2te_path->size()-1)); 185 | assert(sij->t == sij->t2ce_path->at(0)); 186 | assert(sij->ce == sij->t2ce_path->at(sij->t2ce_path->size()-1)); 187 | } 188 | 189 | void Machine::compute_swap_info(){ 190 | int i,j; 191 | for(i=0; i *pi = new vector; 193 | for(j=0; jc = -1; 199 | sij->t = -1; 200 | } 201 | pi->push_back(sij); 202 | } 203 | swap_info.push_back(pi); 204 | } 205 | for(i=0; i> q; 256 | assert(nQ == q); 257 | int i; 258 | int pos; 259 | float val; 260 | for(i=0; i> pos >> val; 262 | assert(pos == i); 263 | s_reliab.push_back(global_scale_value(val)); 264 | } 265 | } 266 | void Machine::read_m_reliability(string fname){ 267 | ifstream fileIn; 268 | fileIn.open(fname.c_str()); 269 | int q; 270 | fileIn >> q; 271 | assert(nQ == q); 272 | int i; 273 | int pos; 274 | float val; 275 | for(i=0; i> pos >> val; 277 | assert(pos == i); 278 | m_reliab.push_back(global_scale_value(val)); 279 | } 280 | } 281 | void Machine::read_t_reliability(string fname){ 282 | ifstream fileIn; 283 | fileIn.open(fname.c_str()); 284 | int pairs; 285 | fileIn >> pairs; 286 | int i; 287 | int idx1, idx2; 288 | float val; 289 | 290 | for(i=0; i> idx1 >> idx2 >> val; 292 | edge_u.push_back(idx1); 293 | edge_v.push_back(idx2); 294 | edge_reliab.push_back(global_scale_value(val)); 295 | } 296 | } 297 | void Machine::read_reliability(string basefname){ 298 | string s, m, t; 299 | s = basefname + "_S.rlb"; 300 | m = basefname + "_M.rlb"; 301 | t = basefname + "_T.rlb"; 302 | read_s_reliability(s); 303 | read_m_reliability(m); 304 | read_t_reliability(t); 305 | cout << "Read reliability\n"; 306 | } 307 | 308 | int Machine::is_edge(int q1, int q2) { 309 | std::pair edgePair = boost::edge(q1, 310 | q2, gswap_log); 311 | if (edgePair.second == true) { 312 | return 1; 313 | } else { 314 | return 0; 315 | } 316 | return 0; 317 | } 318 | 319 | void Machine::read_partition_data(string fname){ 320 | ifstream fileIn; 321 | fileIn.open(fname.c_str()); 322 | int part; 323 | 324 | for (unsigned i = 0; i < qubits.size(); i++) { 325 | fileIn >> part; 326 | qubits[i]->partition = part; 327 | } 328 | } 329 | 330 | void Machine::print_partition_data(){ 331 | for (unsigned i = 0; i < qubits.size(); i++) { 332 | cout << "Qubit " << qubits[i]->id << " " << qubits[i]->partition << "\n"; 333 | } 334 | } 335 | #if 0 336 | //deleted code 337 | std::cout << "distances and parents:" << std::endl; 338 | boost::graph_traits < DirectedGraph >::vertex_iterator vertexIterator, vend; 339 | for (boost::tie(vertexIterator, vend) = boost::vertices(gswap_log); vertexIterator != vend; ++vertexIterator) 340 | { 341 | std::cout << "distance(" << *vertexIterator << ") = " << distances[*vertexIterator] << ", "; 342 | std::cout << "parent(" << *vertexIterator << ") = " << parents[*vertexIterator] << std::endl; 343 | } 344 | std::cout << std::endl; 345 | 346 | 347 | 348 | #endif 349 | -------------------------------------------------------------------------------- /src/machine.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * machine.hpp 3 | * 4 | * Created on: Sep 3, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef MACHINE_HPP_ 9 | #define MACHINE_HPP_ 10 | 11 | #include "headers.hpp" 12 | #include "qubit.hpp" 13 | #include "gate.hpp" 14 | 15 | typedef boost::property EdgeWeightProperty; 16 | typedef boost::adjacency_list DirectedGraph; 18 | typedef boost::graph_traits::edge_iterator edge_iterator; 19 | typedef boost::property_map::type EdgeWeightMap; 20 | typedef boost::graph_traits::vertex_descriptor vertex_descriptor; 21 | typedef boost::graph_traits::edge_descriptor edge_descriptor; 22 | typedef std::pair Edge; 23 | 24 | //SwapInfo objects are created for a every pair of hardware qubits 25 | struct SwapInfo{ 26 | int c; 27 | int t; 28 | int ce; 29 | int te; 30 | float c2te_swap_reliab; 31 | float te2t_cx_reliab; 32 | float t2ce_swap_reliab; 33 | float c2ce_cx_reliab; 34 | vector *c2te_path; 35 | vector *t2ce_path; 36 | }; 37 | 38 | class Machine{ 39 | public: 40 | int nQ; 41 | std::vector qubits; 42 | string data_file; 43 | string machine_name; 44 | string partition_file; 45 | int num_partitions; 46 | Machine(string name, int aerNQ=0, string aer_data_file="", string aer_partition_file="", int aer_num_partitions=0){ 47 | machine_name = name; 48 | if(name == "ibmqx5"){ 49 | nQ = 16; 50 | data_file = "config/ibmqx5"; 51 | }else if(name == "ibmqx4"){ 52 | nQ = 5; 53 | data_file = "config/ibmqx4"; 54 | }else if(name == "ibmq_16_melbourne"){ 55 | nQ = 14; 56 | data_file = "config/ibmq_16_melbourne"; 57 | }else if(name == "tion"){ 58 | nQ = 5; 59 | data_file = "config/tion"; 60 | }else if(name == "agave"){ 61 | nQ = 4; 62 | data_file = "config/agave"; 63 | }else if(name == "Aspen1"){ 64 | nQ = 16; 65 | data_file = "config/Aspen1"; 66 | } 67 | else if(name == "Aspen3"){ 68 | nQ = 14; 69 | data_file = "config/Aspen3"; 70 | } 71 | else if(name == "RM4x8"){ 72 | nQ = 32; 73 | data_file = "config/RM4x8"; 74 | }else if(name == "RM8x8"){ 75 | nQ = 64; 76 | data_file = "config/RM8x8"; 77 | }else if(name == "RM8x9"){ 78 | nQ = 72; 79 | data_file = "config/RM8x9"; 80 | }else if(name == "RM8x16"){ 81 | nQ = 128; 82 | data_file = "config/RM8x16"; 83 | }else if(name == "dummy"){ 84 | nQ = 6; 85 | data_file = "config/dummy"; 86 | } 87 | else{ 88 | assert(name == "Aer"); 89 | nQ = aerNQ; 90 | data_file = aer_data_file; 91 | } 92 | for (int i = 0; i < nQ; i++) { 93 | HwQubit *hq = new HwQubit(i); 94 | qubits.push_back(hq); 95 | } 96 | read_reliability(data_file); 97 | compute_swap_paths(); 98 | print_swap_paths(); 99 | compute_swap_info(); 100 | } 101 | 102 | ~Machine(){ 103 | delete_swap_paths(); 104 | } 105 | 106 | /** 107 | * Data structures with actual reliabilities in range [0,1] 108 | */ 109 | vector s_reliab; //single qubit gate: Qx1 array 110 | vector m_reliab; //measurement operation: Qx1 array 111 | vector edge_u; 112 | vector edge_v; 113 | vector edge_reliab; 114 | vector< vector* > t_reliab; // two qubit gate: QxQ array pairwise swap/cx reliabilities depending on adjacency 115 | 116 | /** 117 | * Data structures with -log reliabilities 118 | */ 119 | map< pair,float > cx_log_reliab; 120 | vector< vector* > swap_log_reliab; // two qubit gate: QxQ array: pairwise swap reliabilities 121 | vector< vector< vector* >* > swap_path; //two qubit gate pairwise swap paths 122 | vector< vector* > swap_info; //info req. for backtracking 123 | DirectedGraph gswap_log; 124 | 125 | 126 | vector< pair > hw_cnot_directions; 127 | 128 | void read_s_reliability(string fname); 129 | void read_m_reliability(string fname); 130 | void read_t_reliability(string fname); 131 | void read_reliability(string basefname); 132 | void read_partition_data(string fname); 133 | int is_edge(int q1, int q2); 134 | 135 | private: 136 | void setup_topology(); 137 | vector< vector* >* compute_swap_paths_one_vertex(int q); 138 | std::vector* compute_shortest_sequence(int source, int dest, 139 | std::vector &parents); 140 | void compute_swap_paths(); 141 | void delete_swap_paths(); 142 | void print_swap_paths(); 143 | void print_partition_data(); 144 | void compute_swap_info(); 145 | void fill_swap_info(int q1, int q2, SwapInfo *s); 146 | int determine_entry_point(int q1, int q2); 147 | void test_swap_info(int i, int j); 148 | 149 | float log2act(float val){ 150 | return exp(-val); 151 | } 152 | }; 153 | 154 | 155 | 156 | #endif /* MACHINE_HPP_ */ 157 | -------------------------------------------------------------------------------- /src/mapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * mapper.cpp 3 | * 4 | * Created on: Sep 3, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "headers.hpp" 9 | #include "mapper.hpp" 10 | #include "circuit.hpp" 11 | 12 | using namespace z3; 13 | 14 | pair get_cx_pair(Gate *g){ 15 | assert(g->nvars == 2); 16 | int qid1, qid2; 17 | if(g->vars[0]->id <= g->vars[1]->id){ 18 | qid1 = g->vars[0]->id; 19 | qid2 = g->vars[1]->id; 20 | }else{ 21 | qid2 = g->vars[0]->id; 22 | qid1 = g->vars[1]->id; 23 | } 24 | return make_pair(qid1, qid2); 25 | } 26 | 27 | void Mapper::set_config(int obj_type, int var_type){ 28 | config.is_sum_objective = obj_type; 29 | config.is_var_unique = var_type; 30 | } 31 | 32 | void Mapper::dummy_mapper(){ 33 | for(int i=0; iqubits.size(); i++){ 34 | qubit_map[C->qubits[i]] = i; 35 | } 36 | } 37 | 38 | void Mapper::dummy_mapper_perm(int j){ 39 | int qubits[16]; 40 | for(int i=0; iqubits.size(); i++){ 41 | qubits[i] = i; 42 | } 43 | int c=0; 44 | do { 45 | if (c == j) { 46 | for (int i = 0; i < C->qubits.size(); i++) { 47 | qubit_map[C->qubits[i]] = qubits[i]; 48 | C->qubits[i]->id = qubits[i]; 49 | } 50 | break; 51 | } 52 | c++; 53 | } while ( std::next_permutation(qubits,qubits+C->qubits.size()) ); 54 | } 55 | 56 | int Mapper::log_reliab(float val) { 57 | assert(val > 0 && val <= 1.0); 58 | if(config.is_sum_objective == MapSum){ 59 | return int(1000 * log(val)); 60 | }else if(config.is_sum_objective == MapMin){ 61 | return int(1000 * val); 62 | }else assert(0); 63 | } 64 | 65 | z3::expr Mapper::reliab(Gate *g){ 66 | if(g->nvars == 2){ 67 | if(config.is_var_unique == VarMultiple){ 68 | return *hw_reliab[g->id]; 69 | }else if(config.is_var_unique == VarUnique){ 70 | pair my_pair = get_cx_pair(g); 71 | return *(all_cx_pairs[my_pair]); 72 | } 73 | }else{ 74 | return *hw_reliab[g->id]; 75 | } 76 | } 77 | 78 | void Mapper::create_solver_vars(){ 79 | ctx = new z3::context; 80 | opt = new z3::solver(*ctx); 81 | all_cx_pairs.clear(); 82 | 83 | int i; 84 | for (i = 0; i < C->qubits.size(); i++) { 85 | stringstream ss; 86 | ss << "q"; 87 | ss << C->qubits[i]->id; 88 | hw_loc[C->qubits[i]->id] = new z3::expr(ctx->int_const(ss.str().c_str())); 89 | } 90 | for (i = 0; i < C->gates.size(); i++) { 91 | stringstream ss; 92 | ss << "g"; 93 | ss << C->gates[i]->id; 94 | ss << "_reliab"; 95 | hw_reliab[C->gates[i]->id] = new expr(ctx->int_const(ss.str().c_str())); 96 | 97 | if (config.is_var_unique == VarUnique && (C->gates[i]->nvars == 2)) { 98 | pair my_pair = get_cx_pair(C->gates[i]); 99 | if (all_cx_pairs.find(my_pair) == all_cx_pairs.end()) { 100 | stringstream scx; 101 | scx << "cx" << my_pair.first << "_" << my_pair.second << "_reliab"; 102 | all_cx_pairs[my_pair] = new z3::expr(ctx->int_const(scx.str().c_str())); 103 | } 104 | } 105 | } 106 | } 107 | 108 | void Mapper::generate_constraints() { 109 | //mapping constraints 110 | int qcnt = C->qubits.size(); 111 | int gcnt = C->gates.size(); 112 | 113 | for (int i = 0; i < qcnt; i++) { 114 | Qubit *Qi = C->qubits[i]; 115 | expr cons = (loc(Qi) >= 0) && (loc(Qi) < M->nQ); 116 | opt->add(cons); 117 | } 118 | for (int i = 0; i < qcnt; i++) { 119 | Qubit *Qi = C->qubits[i]; 120 | for (int j = i + 1; j < qcnt; j++) { 121 | Qubit *Qj = C->qubits[j]; 122 | expr cons = (loc(Qi) != loc(Qj)); 123 | opt->add(cons); 124 | } 125 | } 126 | 127 | map< pair, int> cx_cnt; 128 | for(auto pairs : all_cx_pairs){ 129 | cx_cnt[pairs.first] = 0; 130 | } 131 | 132 | //reliability constraints 133 | for (int i = 0; i < gcnt; i++) { 134 | Gate *Gi = C->gates[i]; 135 | if (typeid(*Gi) == typeid(CNOT)) { 136 | Qubit *ctrl = Gi->vars[0]; 137 | Qubit *targ = Gi->vars[1]; 138 | if(config.is_var_unique == VarUnique){ 139 | if(cx_cnt[get_cx_pair(Gi)] > 0){ 140 | cx_cnt[get_cx_pair(Gi)]++; 141 | continue; 142 | //This is to avoid adding redundant reliability-set constraints for the same CNOT qubit pair 143 | }else{ 144 | cx_cnt[get_cx_pair(Gi)]++; 145 | } 146 | } 147 | for (int p1 = 0; p1 < M->nQ; p1++) { 148 | for (int p2 = 0; p2 < M->nQ; p2++) { 149 | if (p1 == p2) 150 | continue; 151 | expr is_loc = ((loc(ctrl) == p1) && (loc(targ) == p2)); 152 | if ((*(M->t_reliab[p1]))[p2] < 0) { 153 | assert(0); 154 | //opt->add(!is_loc); 155 | } else { 156 | //Constraints to specify the reliability based on mapping 157 | int r = log_reliab((*(M->t_reliab[p1]))[p2]); 158 | expr cons = implies(is_loc, reliab(Gi) == r); 159 | opt->add(cons); 160 | } 161 | } 162 | } 163 | } 164 | } 165 | 166 | 167 | for (int i = 0; i < gcnt; i++) { 168 | Gate *Gi = C->gates[i]; 169 | if (typeid(*Gi) == typeid(MeasZ)) { 170 | Qubit *Qi = Gi->vars[0]; 171 | for (int p1 = 0; p1 < M->nQ; p1++) { 172 | expr is_loc = (loc(Qi) == p1); 173 | int r = log_reliab(M->m_reliab[p1]); 174 | expr cons = implies(is_loc, reliab(Gi) == r); 175 | opt->add(cons); 176 | } 177 | 178 | } 179 | } 180 | 181 | //sum objective 182 | if (config.is_sum_objective == MapSum) { 183 | expr_vector opr_reliab(*ctx); 184 | int cnt = 0; 185 | for (int i = 0; i < gcnt; i++) { 186 | Gate *Gi = C->gates[i]; 187 | if (Gi->vars.size() == 2 || typeid(*Gi) == typeid(MeasZ)) { 188 | opr_reliab.push_back(reliab(Gi)); 189 | cnt++; 190 | } 191 | } 192 | expr s = sum(opr_reliab); 193 | opt->add(s >= (log_reliab(config.thresh) * cnt)); 194 | expr sum_test = s >= (log_reliab(config.thresh) * cnt); 195 | //cout << sum_test << endl; 196 | } else if(config.is_sum_objective == MapMin){ 197 | //individual objectives 198 | 199 | for(auto k1 : all_cx_pairs){ 200 | for(auto k2 : all_cx_pairs){ 201 | if(k1 == k2) continue; 202 | int cx1 = cx_cnt[k1.first]; 203 | int cx2 = cx_cnt[k2.first]; 204 | if (cx1 != 0 && cx2 != 0) { 205 | if (cx1 >= 2 * cx2) { 206 | opt->add(*(k1.second) >= *(k2.second)); 207 | //cout << "Adding freq. constraint:" << "(" << k1.first.first << " " << k1.first.second << "),(" << k2.first.first << " " << k2.first.second << ")" << "\n"; 208 | }else 209 | ; 210 | } 211 | } 212 | } 213 | for(auto pairs : all_cx_pairs){ 214 | cx_cnt[pairs.first] = 0; 215 | } 216 | for (int i = 0; i < gcnt; i++) { 217 | Gate *Gi = C->gates[i]; 218 | if (Gi->vars.size() == 2 || typeid(*Gi) == typeid(MeasZ)) { 219 | if(typeid(*Gi) == typeid(MeasZ)){ 220 | opt->add(reliab(Gi) >= log_reliab(config.thresh)); 221 | expr test = reliab(Gi) >= log_reliab(config.thresh); 222 | }else{ 223 | if(cx_cnt[get_cx_pair(Gi)] == 0){ 224 | opt->add(reliab(Gi) >= log_reliab(config.thresh)); 225 | cx_cnt[get_cx_pair(Gi)] = 1; 226 | expr test = reliab(Gi) >= log_reliab(config.thresh); 227 | } 228 | } 229 | } 230 | } 231 | } else { 232 | assert(0); 233 | } 234 | } 235 | 236 | void Mapper::solve_optimization(SolverOut &sp) { 237 | if (opt->check() == sat) { 238 | model m = opt->get_model(); 239 | sp.success = 1; 240 | for (unsigned int i = 0; i < C->qubits.size(); i++) { 241 | sp.current_map[C->qubits[i]] = m.eval(loc(C->qubits[i])) .get_numeral_int(); 242 | } 243 | } else { 244 | sp.success = 0; 245 | } 246 | stats solve_stats = opt->statistics(); 247 | accumulate_stats(solve_stats); 248 | } 249 | 250 | void Mapper::cleanup_solver(){ 251 | if(opt != 0){ 252 | delete opt; 253 | } 254 | if(ctx != 0){ 255 | delete ctx; 256 | } 257 | } 258 | 259 | SolverOut* Mapper::map_with_z3() { 260 | float low, mid, high; 261 | float approx; 262 | low = 0; 263 | high = 1; 264 | SolverOut *sol = 0; 265 | while (1) { 266 | mid = (low + high) / 2; 267 | SolverOut *out = solve_one_instance(mid); 268 | if (out->success == 1) { 269 | low = mid; 270 | if (sol != 0) 271 | delete sol; 272 | sol = out; 273 | } else { 274 | high = mid; 275 | delete out; 276 | } 277 | if (high / low <= config.approx_factor) 278 | break; 279 | } 280 | 281 | int i=0; 282 | cout << "Qubit Mapping\n"; 283 | for(i=0; iqubits.size(); i++){ 284 | qubit_map[C->qubits[i]] = sol->current_map[C->qubits[i]]; 285 | cout << "(" << C->qubits[i]->id << "," << qubit_map[C->qubits[i]] << ")" << endl; 286 | } 287 | return sol; 288 | } 289 | 290 | SolverOut* Mapper::solve_one_instance(float t){ 291 | cout << "Solving with thresh=" << t << endl; 292 | config.thresh = t; 293 | SolverOut *sp = new SolverOut; 294 | create_solver_vars(); 295 | generate_constraints(); 296 | solve_optimization(*sp); 297 | cleanup_solver(); 298 | return sp; 299 | } 300 | 301 | 302 | 303 | void Mapper::accumulate_stats(stats S){ 304 | int i; 305 | for(unsigned i=0; i current_map; 43 | int success; 44 | 45 | SolverOut(){ 46 | } 47 | }; 48 | 49 | class MapperStats{ 50 | public: 51 | int z3_arith_conflicts; 52 | int z3_conflicts; 53 | int z3_arith_add_rows; 54 | int z3_mk_clause; 55 | int z3_added_eqs; 56 | int z3_binary_propagations; 57 | int z3_restarts; 58 | int z3_decisions; 59 | }; 60 | 61 | 62 | class Mapper{ 63 | public: 64 | std::map qubit_map; 65 | Machine *M; 66 | Circuit *C; 67 | map hw_loc; 68 | map hw_reliab; 69 | z3::context *ctx; 70 | z3::solver *opt; 71 | SolverConfig config; 72 | MapperStats mapper_stats; 73 | 74 | map, z3::expr* > all_cx_pairs; 75 | 76 | z3::expr reliab(Gate *g); 77 | z3::expr loc(Qubit *q){ 78 | return *hw_loc[q->id]; 79 | } 80 | Mapper(Machine *machine, Circuit *circuit){ 81 | M = machine; 82 | C = circuit; 83 | ctx = 0; 84 | opt = 0; 85 | assert(C->qubits.size() <= M->qubits.size()); 86 | mapper_stats.z3_arith_conflicts = 0; 87 | mapper_stats.z3_conflicts = 0; 88 | mapper_stats.z3_arith_add_rows = 0; 89 | mapper_stats.z3_mk_clause = 0; 90 | mapper_stats.z3_added_eqs = 0; 91 | mapper_stats.z3_binary_propagations = 0; 92 | mapper_stats.z3_restarts = 0; 93 | mapper_stats.z3_decisions = 0; 94 | } 95 | 96 | ~Mapper(){ 97 | } 98 | 99 | void dummy_mapper(); 100 | SolverOut* map_with_z3(); 101 | SolverOut* solve_one_instance(float t); 102 | int log_reliab(float val); 103 | void dummy_mapper_perm(int j); 104 | void set_config(int obj_type, int var_type); 105 | void accumulate_stats(stats S); 106 | void print_stats(); 107 | private: 108 | void create_solver_vars(); 109 | void generate_constraints(); 110 | void solve_optimization(SolverOut &sp); 111 | void cleanup_solver(); 112 | }; 113 | 114 | #endif /* MAPPER_HPP_ */ 115 | -------------------------------------------------------------------------------- /src/optimize_1q.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * optimize_1q.cpp 3 | * 4 | * Created on: Sep 28, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "circuit.hpp" 9 | #include "optimize_1q.hpp" 10 | #include "quaternion.hpp" 11 | 12 | /** 13 | * This implementation is adapted from the corresponding pass in Qiskit 14 | * qiskit/transpiler/passes/optimize_1q_gates.py 15 | */ 16 | 17 | int is_multiple_of_2pi(double angle){ 18 | double thresh = 0.000001; 19 | if(fabs(angle) <= thresh) return 1; 20 | 21 | double tmp = angle; 22 | while(1){ 23 | tmp = tmp - 2*PI; 24 | if(fabs(tmp) <= thresh){ 25 | return 1; 26 | } 27 | if(tmp < 0){ 28 | return 0; 29 | } 30 | } 31 | } 32 | 33 | void print_rot_sequence(vector rot_seq){ 34 | for(auto g : rot_seq){ 35 | g->print(); 36 | } 37 | } 38 | 39 | URotate* Optimize1QGates::create_U1_gate(double lambda){ 40 | URotate *g = new URotate(); 41 | g->type = 1; 42 | g->theta = 0; 43 | g->phi = 0; 44 | g->lambda = lambda; 45 | } 46 | 47 | URotate* Optimize1QGates::create_U2_gate(double phi, double lambda){ 48 | URotate *g = new URotate(); 49 | g->type = 2; 50 | g->theta = PI/2.0; 51 | g->phi = phi; 52 | g->lambda = lambda; 53 | } 54 | 55 | URotate* Optimize1QGates::create_U3_gate(double theta, double phi, double lambda){ 56 | URotate *g = new URotate(); 57 | g->type = 3; 58 | g->theta = theta; 59 | g->phi = phi; 60 | g->lambda = lambda; 61 | } 62 | 63 | void Optimize1QGates::decompose(){ 64 | //cout << "optimizing...\n"; 65 | for(int i = in_gates.size()-1; i >= 0; i--){ 66 | Gate *g = in_gates[i]; 67 | if(typeid(*g) == typeid(X)){ 68 | rot_seq.push_back(create_U3_gate(PI, 0, PI)); 69 | }else if(typeid(*g) == typeid(Y)){ 70 | rot_seq.push_back(create_U3_gate(PI, PI/2.0, PI/2.0)); 71 | }else if(typeid(*g) == typeid(Z)){ 72 | rot_seq.push_back(create_U1_gate(PI)); 73 | }else if(typeid(*g) == typeid(H)){ 74 | rot_seq.push_back(create_U2_gate(0, PI)); 75 | }else if(typeid(*g) == typeid(S)){ 76 | rot_seq.push_back(create_U1_gate(PI/2)); 77 | }else if(typeid(*g) == typeid(Sdag)){ 78 | rot_seq.push_back(create_U1_gate(-PI/2)); 79 | }else if(typeid(*g) == typeid(T)){ 80 | rot_seq.push_back(create_U1_gate(PI/4)); 81 | }else if(typeid(*g) == typeid(Tdag)){ 82 | rot_seq.push_back(create_U1_gate(-PI/4)); 83 | }else if(typeid(*g) == typeid(RX)){ 84 | rot_seq.push_back( create_U3_gate(g->angle, -PI/2.0, PI/2.0)); 85 | }else if(typeid(*g) == typeid(RY)){ 86 | rot_seq.push_back( create_U3_gate(g->angle, 0, 0) ); 87 | }else if(typeid(*g) == typeid(RZ)){ 88 | rot_seq.push_back(create_U1_gate(g->angle)); 89 | }else{ 90 | assert(0); 91 | } 92 | } 93 | //print_rot_sequence(rot_seq); 94 | } 95 | 96 | void Optimize1QGates::yzy_to_zyz(double xi, double theta1, double theta2, double& thetap, double& phip, double& lambdap){ 97 | Quaternion* Q = Quaternion::make_quaternion_from_euler(theta1, xi, theta2, "yzy"); 98 | Q->to_zyz(); 99 | thetap = Q->e[1]; 100 | phip = Q->e[0]; 101 | lambdap = Q->e[2]; 102 | } 103 | 104 | void Optimize1QGates::merge_u3_gates(URotate* g1, URotate* g2){ 105 | double thetap, phip, lambdap; 106 | yzy_to_zyz(g1->lambda + g2->phi, g1->theta, g2->theta, thetap, phip, lambdap); 107 | 108 | g2->theta = thetap; 109 | g2->phi = g1->phi + phip; 110 | g2->lambda = g2->lambda + lambdap; 111 | } 112 | 113 | void Optimize1QGates::optimize(){ 114 | cout << setprecision(16); 115 | int prev_size=rot_seq.size(); 116 | while(1){ 117 | if(rot_seq.size() == 1) break; 118 | int m = rot_seq.size()-1; 119 | set marked_for_delete; 120 | for(int i=0; itype == 1 && g2->type == 1){ 127 | g2->type = 1; 128 | g2->theta = 0; 129 | g2->phi = 0; 130 | g2->lambda += g1->lambda; 131 | marked_for_delete.insert(g1); 132 | } 133 | //U1, U2 134 | else if(g1->type == 1 && g2->type == 2){ 135 | g2->type = 2; 136 | g2->theta = PI/2; 137 | g2->phi += g1->lambda; 138 | marked_for_delete.insert(g1); 139 | } 140 | //U2, U1 141 | else if(g1->type == 2 && g2->type == 1){ 142 | g2->type = 2; 143 | g2->theta = PI/2; 144 | g2->phi = g1->phi; 145 | g2->lambda += g1->lambda; 146 | marked_for_delete.insert(g1); 147 | } 148 | //U1, U3 149 | else if(g1->type == 1 && g2->type == 3){ 150 | g2->phi += g1->lambda; 151 | marked_for_delete.insert(g1); 152 | } 153 | //U3, U1 154 | else if(g1->type == 3 && g2->type == 1){ 155 | g2->type = 3; 156 | g2->theta = g1->theta; 157 | g2->phi = g1->phi; 158 | g2->lambda += g1->lambda; 159 | marked_for_delete.insert(g1); 160 | } 161 | //U2, U2 162 | else if(g1->type == 2 && g2->type == 2){ 163 | g2->type = 3; 164 | g2->theta = PI - g1->lambda - g2->phi; 165 | g2->phi = g1->phi + PI/2.0; 166 | g2->lambda = g2->lambda + PI/2.0; 167 | marked_for_delete.insert(g1); 168 | } 169 | //U2, U3 or U3, U2 or U3, U3 170 | else{ 171 | int case1, case2, case3; 172 | case1 = (g1->type == 2 && g2->type == 3); 173 | case2 = (g1->type == 3 && g2->type == 2); 174 | case3 = (g1->type == 3 && g2->type == 3); 175 | assert(case1 || case2 || case3); 176 | 177 | if(g1->type == 2) g1->theta = PI/2.0; 178 | if(g2->type == 2) g2->theta = PI/2.0; 179 | g1->type = 3; 180 | g2->type = 3; 181 | //cout << "merging u3s\n"; 182 | //g1->print(); 183 | //g2->print(); 184 | merge_u3_gates(g1, g2); 185 | //cout << "\t"; g2->print(); 186 | marked_for_delete.insert(g1); 187 | } 188 | 189 | if(g2->type != 1 && is_multiple_of_2pi(g2->theta)){ 190 | g2->type = 1; 191 | g2->lambda = g2->theta + g2->phi + g2->lambda; 192 | g2->theta = 0; 193 | g2->phi = 0; 194 | } 195 | if(g2->type == 3){ 196 | int f1 = is_multiple_of_2pi(g2->theta - (PI/2)); 197 | int f2 = is_multiple_of_2pi(g2->theta + (PI/2)); 198 | if(f1){ 199 | g2->type = 2; 200 | double new_theta, new_phi, new_lambda; 201 | new_theta = PI/2; 202 | new_phi = g2->phi; 203 | new_lambda = g2->lambda + g2->theta - PI/2; 204 | g2->theta = new_theta; 205 | g2->phi = new_phi; 206 | g2->lambda = new_lambda; 207 | } 208 | if(f2){ 209 | g2->type = 2; 210 | double new_theta, new_phi, new_lambda; 211 | new_theta = PI / 2; 212 | new_phi = g2->phi + PI; 213 | new_lambda = g2->lambda + g2->theta - PI / 2; 214 | g2->theta = new_theta; 215 | g2->phi = new_phi; 216 | g2->lambda = new_lambda; 217 | } 218 | } 219 | if(g2->type == 1){ 220 | if(is_multiple_of_2pi(g2->lambda)){ 221 | g2->lambda = 0; 222 | g2->theta = 0; 223 | g2->phi = 0; 224 | } 225 | } 226 | } 227 | for(auto urot : marked_for_delete){ 228 | rot_seq.erase(std::remove(rot_seq.begin(), rot_seq.end(), urot), rot_seq.end()); 229 | } 230 | if(rot_seq.size() == prev_size){ 231 | break; 232 | }else{ 233 | prev_size = rot_seq.size(); 234 | } 235 | } 236 | //cout << "after optimize\n"; 237 | //print_rot_sequence(rot_seq); 238 | } 239 | 240 | vector Optimize1QGates::get_optimized_gates(){ 241 | vector optimized_gates; 242 | for(int i=rot_seq.size()-1; i>=0; i--){ 243 | URotate *u = rot_seq[i]; 244 | Gate *g; 245 | if(u->type == 1){ 246 | g = Gate::create_new_gate("U1"); 247 | }else if(u->type == 2){ 248 | g = Gate::create_new_gate("U2"); 249 | }else if(u->type == 3){ 250 | g = Gate::create_new_gate("U3"); 251 | }else assert(0); 252 | g->theta = u->theta; 253 | g->phi = u->phi; 254 | g->lambda = u->lambda; 255 | optimized_gates.push_back(g); 256 | } 257 | return optimized_gates; 258 | } 259 | 260 | 261 | void OptimizeSingleQubitOps::optimize(){ 262 | for(auto it : runs){ 263 | //cout << "Procecssing run with head " << it.first->id << endl; 264 | Qubit *q = it.first->vars[0]; 265 | vector my_run = it.second; 266 | Optimize1QGates opt(my_run); 267 | opt.optimize(); 268 | vector new_gates = opt.get_optimized_gates(); 269 | for(auto ngate : new_gates){ 270 | ngate->vars.push_back(q); 271 | } 272 | C->replace_with_chain(my_run, new_gates); 273 | } 274 | } 275 | 276 | void OptimizeSingleQubitOps::extract_runs(){ 277 | //init: every gate in its own run 278 | for (auto g : C->gates) { 279 | if (g->nvars == 1 && typeid(*g) != typeid(MeasZ)) { 280 | vector g_set; 281 | g_set.push_back(g); 282 | runs[g] = g_set; 283 | } 284 | } 285 | vector top_order = *(C->topological_ordering()); 286 | for(auto it = top_order.rbegin(); it != top_order.rend(); it++){ 287 | Gate *g = *it; 288 | if(g->nvars != 1 || typeid(*g) == typeid(MeasZ)) continue; 289 | for(auto p : g->pred){ 290 | if(p->nvars != 1 || typeid(*p) == typeid(MeasZ)) continue; 291 | if(p->vars[0] == g->vars[0] && g->pred.size() == 1) { 292 | //p is my parent 293 | for(auto t : runs[g]){ 294 | runs[p].push_back(t); 295 | } 296 | auto run_it = runs.find(g); 297 | runs.erase(run_it); 298 | } 299 | } 300 | } 301 | /* 302 | for(auto it : runs){ 303 | cout << it.first->id << endl; 304 | for(auto g : it.second){ 305 | g->print(); 306 | } 307 | cout << endl; 308 | }*/ 309 | } 310 | 311 | vector OptimizeSingleQubitOps::get_optimized_layer(vector gate_list){ 312 | set qlist; 313 | for(auto g : gate_list){ 314 | assert(g->nvars == 1); 315 | qlist.insert(g->vars[0]); 316 | } 317 | vector return_list; 318 | for(auto q : qlist){ 319 | vector q_gate_list; 320 | for(auto g : gate_list){ 321 | if(g->vars[0] == q){ 322 | q_gate_list.push_back(g); 323 | } 324 | } 325 | Optimize1QGates opt(q_gate_list); 326 | opt.optimize(); 327 | vector new_gates = opt.get_optimized_gates(); 328 | for(auto ngate : new_gates){ 329 | ngate->vars.push_back(q); 330 | return_list.push_back(ngate); 331 | } 332 | } 333 | return return_list; 334 | } 335 | 336 | Circuit *OptimizeSingleQubitOps::test_optimize(){ 337 | vector top_order = *(C->topological_ordering()); 338 | vector *current_run = new vector; 339 | int dirty = 0; 340 | vector final_gate_list; 341 | for(auto g : top_order){ 342 | if(g->nvars == 2){ 343 | //for(auto pg : *current_run){ 344 | // pg->print(); 345 | //} 346 | //cout << "\n"; 347 | auto new_list = get_optimized_layer(*current_run); 348 | for (auto pg : new_list) { 349 | //pg->print(); 350 | final_gate_list.push_back(pg); 351 | } 352 | //cout << "\n"; 353 | Gate *new_gate = Gate::create_new_gate(g->printStr); 354 | new_gate->nvars = 2; 355 | new_gate->vars.push_back(g->vars[0]); 356 | new_gate->vars.push_back(g->vars[1]); 357 | if(typeid(*new_gate) == typeid(XX)){ 358 | new_gate->angle = g->angle; 359 | } 360 | final_gate_list.push_back(new_gate); 361 | delete current_run; 362 | current_run = new vector; 363 | dirty = 0; 364 | }else{ 365 | if(typeid(*g) != typeid(MeasZ)){ 366 | current_run->push_back(g); 367 | dirty = 1; 368 | } 369 | } 370 | } 371 | if(dirty){ 372 | auto new_list = get_optimized_layer(*current_run); 373 | for (auto pg : new_list) { 374 | final_gate_list.push_back(pg); 375 | } 376 | delete current_run; 377 | } 378 | for(unsigned int i=0; i < final_gate_list.size()-1; i++){ 379 | Gate *cur, *nxt; 380 | cur = final_gate_list[i]; 381 | nxt = final_gate_list[i+1]; 382 | cur->succ.push_back(nxt); 383 | nxt->pred.push_back(cur); 384 | } 385 | Circuit *newC = new Circuit; 386 | newC->qubits = C->qubits; 387 | newC->gates = final_gate_list; 388 | return newC; 389 | } 390 | -------------------------------------------------------------------------------- /src/optimize_1q.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * optimize_1q.hpp 3 | * 4 | * Created on: Sep 28, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef OPTIMIZE_1Q_HPP_ 9 | #define OPTIMIZE_1Q_HPP_ 10 | 11 | #include "headers.hpp" 12 | #include "circuit.hpp" 13 | #include "gate.hpp" 14 | 15 | class URotate{ 16 | public: 17 | URotate(){}; 18 | ~URotate(){}; 19 | int type; 20 | double theta; 21 | double phi; 22 | double lambda; 23 | void print(){ 24 | std::setprecision(10); 25 | if(type == 1) 26 | cout << "U1(" << lambda << ")\n"; 27 | else if(type == 2) 28 | cout << "U2(" << phi << "," << lambda << ")\n"; 29 | else if(type == 3) 30 | cout << "U3(" << theta << "," << phi << "," << lambda << ")\n"; 31 | else assert(0); 32 | } 33 | }; 34 | 35 | class Optimize1QGates{ 36 | public: 37 | vector in_gates; 38 | Optimize1QGates(vector gateSeq){ 39 | in_gates = gateSeq; 40 | decompose(); 41 | } 42 | vector rot_seq; 43 | vector out_gates; 44 | void decompose(); 45 | void optimize(); 46 | vector get_optimized_gates(); 47 | void merge_u3_gates(URotate* g1, URotate* g2); 48 | void yzy_to_zyz(double xi, double theta1, double theta2, double& thetap, double& phip, double& lambdap); 49 | 50 | URotate *create_U1_gate(double lambda); 51 | URotate *create_U2_gate(double phi, double lambda); 52 | URotate *create_U3_gate(double theta, double phi, double lambda); 53 | }; 54 | 55 | class OptimizeSingleQubitOps{ 56 | public: 57 | Circuit *C; 58 | map > runs; 59 | OptimizeSingleQubitOps(Circuit *c){ 60 | C = c; 61 | } 62 | void optimize(); 63 | void extract_runs(); 64 | Circuit* test_optimize(); 65 | vector get_optimized_layer(vector gate_list); 66 | }; 67 | 68 | #endif /* OPTIMIZE_1Q_HPP_ */ 69 | -------------------------------------------------------------------------------- /src/pattern.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * pattern.cpp 3 | * 4 | * Created on: Sep 4, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "headers.hpp" 9 | #include "pattern.hpp" 10 | #include "circuit.hpp" 11 | 12 | 13 | void delete_gate_from_vec(vector &vec, Gate *g){ 14 | vec.erase(std::remove(vec.begin(), vec.end(), g), vec.end()); 15 | } 16 | 17 | GateStub* PatternProcessor::get_gate_stub(string in_str){ 18 | GateStub *gs = new GateStub; 19 | vector tokens; 20 | stringstream check1(in_str); 21 | string intermediate; 22 | while (getline(check1, intermediate, ',')) { 23 | tokens.push_back(intermediate); 24 | } 25 | gs->gate_type = tokens[0]; 26 | int paramIdx; 27 | for (int i = 1; i < tokens.size(); i++){ 28 | if(tokens[i].find("params") == string::npos){ 29 | gs->qubit_order.push_back(stoi(tokens[i])); 30 | }else{ 31 | paramIdx = i; 32 | } 33 | } 34 | gs->params = tokens[paramIdx]; 35 | gs->params.erase(0, 7); 36 | gs->params.erase(gs->params.find(';')); 37 | return gs; 38 | } 39 | 40 | void PatternProcessor::load_one_pattern(ifstream &inFile){ 41 | string tmp; 42 | inFile >> tmp; 43 | if(tmp.find("Pattern") == string::npos){ 44 | return; 45 | } 46 | 47 | while(1){ 48 | inFile >> tmp; 49 | if(tmp.find("Search") != string::npos) break; 50 | } 51 | 52 | string search_string; 53 | inFile >> search_string; 54 | cout << "Pattern for " << search_string << endl; 55 | inFile >> tmp; //Action 56 | inFile >> tmp; //Replace 57 | 58 | Pattern *P = new Pattern; 59 | P->gate_type = search_string; 60 | 61 | while(1){ 62 | inFile >> tmp; 63 | if(tmp == "End") break; 64 | GateStub *gs = get_gate_stub(tmp); 65 | gs->print_stub(); 66 | } 67 | } 68 | 69 | void PatternProcessor::load_patterns_from_file(string fname){ 70 | ifstream inFile; 71 | inFile.open(fname.c_str()); 72 | cout << "Reading " << fname << endl; 73 | while(!inFile.eof()) 74 | this->load_one_pattern(inFile); 75 | } 76 | 77 | void PatternProcessor::load_test_patterns(){ 78 | //load pattern for H gate 79 | Pattern *p1 = new Pattern(); 80 | p1->id = 0; 81 | p1->name = "H Pattern"; 82 | p1->gate_type = "H"; //search for H 83 | ReplaceAction *a1 = new ReplaceAction(); 84 | a1->id = 0; 85 | a1->name = "H Implementation"; 86 | a1->repl.push_back(get_gate_stub("RY,0,params:+2;")); 87 | a1->repl.push_back(get_gate_stub("RX,0,params:+1;")); 88 | p1->action = a1; 89 | 90 | patterns.push_back(p1); 91 | 92 | Pattern *p2 = new Pattern(); 93 | p2->id = 1; 94 | p2->name = "CNOT Pattern"; 95 | p2->gate_type = "CNOT"; //search for H 96 | ReplaceAction *a2 = new ReplaceAction(); 97 | a2->id = 0; 98 | a2->name = "CNOT Implementation"; 99 | a2->repl.push_back(get_gate_stub("RY,0,params:+2;")); 100 | a2->repl.push_back(get_gate_stub("XX,0,1,params:+4;")); 101 | a2->repl.push_back(get_gate_stub("RY,0,params:-2;")); 102 | a2->repl.push_back(get_gate_stub("RX,1,params:-2;")); 103 | a2->repl.push_back(get_gate_stub("RZ,0,params:-2;")); 104 | p2->action = a2; 105 | 106 | patterns.push_back(p2); 107 | 108 | Pattern *p3 = new Pattern(); 109 | p3->id = 1; 110 | p3->name = "X Pattern"; 111 | p3->gate_type = "X"; //search for H 112 | ReplaceAction *a3 = new ReplaceAction(); 113 | a3->id = 2; 114 | a3->name = "X Implementation"; 115 | a3->repl.push_back(get_gate_stub("RX,0,params:+1;")); 116 | p3->action = a3; 117 | 118 | patterns.push_back(p3); 119 | } 120 | 121 | void PatternProcessor::apply(Circuit *C){ 122 | int i; 123 | for(i=0; iname << endl; 126 | int s = C->gates.size(); 127 | 128 | vector remove_gates; 129 | for(int j=0; jgates[j]->printStr == p->gate_type){ 131 | cout << "found a gate " << p->gate_type << endl; 132 | vector target_gates = {C->gates[j]}; 133 | p->action->act(C, &target_gates); 134 | remove_gates.push_back(C->gates[j]); 135 | } 136 | } 137 | 138 | for(int j=0; jgates, remove_gates[j]); 140 | } 141 | } 142 | } 143 | 144 | void ReplaceAction::act(Circuit *C, vector *in_gates){ 145 | cout << "applying action" << endl; 146 | assert(in_gates->size() == 1); 147 | vector out_gates; 148 | Gate *in_g = (*in_gates)[0]; 149 | if(repl.size() == 0) assert(0); //delete not allowed in this function 150 | for(int i=0; igate_type); 152 | cout << "created gate of type" << repl[i]->gate_type << endl; 153 | tmp->params = repl[i]->params; 154 | for(int j=0; jnvars; j++){ 155 | tmp->vars.push_back(in_g->vars[repl[i]->qubit_order[j]]); 156 | } 157 | out_gates.push_back(tmp); 158 | } 159 | //wire in dependencies to first gate 160 | Gate *first_gate = out_gates[0]; 161 | first_gate->pred = in_g->pred; 162 | //wite out dependencies to last gate 163 | Gate *last_gate = out_gates[out_gates.size()-1]; 164 | last_gate->succ = in_g->succ; 165 | //delete the node in_g 166 | //change connections of predecessors 167 | for(unsigned int i=0; ipred.size(); i++){ 168 | Gate *pred_g = in_g->pred[i]; 169 | delete_gate_from_vec(pred_g->succ, in_g); 170 | pred_g->succ.push_back(first_gate); 171 | } 172 | for(unsigned int i=0; isucc.size(); i++){ 173 | Gate *succ_g = in_g->succ[i]; 174 | delete_gate_from_vec(succ_g->pred, in_g); 175 | succ_g->pred.push_back(last_gate); 176 | } 177 | //delete_gate_from_vec(C->gates, in_g); 178 | for(unsigned int i=0; isucc.push_back(next); 182 | next->pred.push_back(current); 183 | } 184 | for(int i=0; igates.push_back(out_gates[i]); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/pattern.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * pattern.hpp 3 | * 4 | * Created on: Sep 4, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef PATTERN_HPP_ 9 | #define PATTERN_HPP_ 10 | 11 | #include "headers.hpp" 12 | #include "circuit.hpp" 13 | 14 | class GateStub{ 15 | public: 16 | string gate_type; 17 | vector qubit_order; 18 | string params; 19 | void print_stub(){ 20 | cout << "Type:" << gate_type << " Qubit order: "; 21 | for(int i=0; i *in_gates) = 0; 32 | }; 33 | 34 | class ReplaceAction : public Action{ 35 | public: 36 | vector repl; 37 | void act(Circuit *C, vector *in_gates); 38 | 39 | }; 40 | 41 | class Pattern{ 42 | public: 43 | int id; 44 | string name; 45 | string gate_type; //TODO patterns can be of many types: gate strings, gate motifs etc. 46 | Action *action; 47 | Pattern(){} 48 | }; 49 | 50 | 51 | class PatternProcessor{ 52 | public: 53 | vector patterns; 54 | void load_test_patterns(); 55 | void load_patterns_from_file(string fname); 56 | void load_one_pattern(ifstream &inFile); 57 | void apply(Circuit *C); 58 | GateStub* get_gate_stub(string in_str); 59 | }; 60 | #endif /* PATTERN_HPP_ */ 61 | -------------------------------------------------------------------------------- /src/quaternion.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * quaternion.cpp 3 | * 4 | * Created on: Oct 29, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "headers.hpp" 9 | #include "quaternion.hpp" 10 | 11 | /** 12 | * This implementation was adapted from the methods in Qiskit 13 | * qiskit/quantum_info/operators/quaternion.py 14 | */ 15 | 16 | void Quaternion::normalize(){ 17 | double norm=0; 18 | norm = sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2] + d[3]*d[3]); 19 | d[0] = d[0]/norm; 20 | d[1] = d[1]/norm; 21 | d[2] = d[2]/norm; 22 | d[3] = d[3]/norm; 23 | } 24 | 25 | Quaternion *Quaternion::make_quaternion_from_axis(double angle, const char& axis){ 26 | Quaternion *q = new Quaternion(0,0,0,0); 27 | if(axis == 'x'){ 28 | q->d[1] = 1; 29 | }else if(axis == 'y'){ 30 | q->d[2] = 1; 31 | }else if(axis == 'z'){ 32 | q->d[3] = 1; 33 | }else{ 34 | assert(0); 35 | } 36 | for(int i=0; i<4; i++){ 37 | q->d[i] = q->d[i]*sin(angle/2.0); 38 | } 39 | q->d[0] = cos(angle/2.0); 40 | return q; 41 | } 42 | 43 | Quaternion *Quaternion::multiply(Quaternion *q1, Quaternion *q2){ 44 | Quaternion *q = new Quaternion(0,0,0,0); 45 | double *a = q1->d; 46 | double *b = q2->d; 47 | q->d[0] = b[0] * a[0] - b[1] * a[1] - b[2] * a[2] - b[3] * a[3]; 48 | q->d[1] = b[0] * a[1] + b[1] * a[0] - b[2] * a[3] + b[3] * a[2]; 49 | q->d[2] = b[0] * a[2] + b[1] * a[3] + b[2] * a[0] - b[3] * a[1]; 50 | q->d[3] = b[0] * a[3] - b[1] * a[2] + b[2] * a[1] + b[3] * a[0]; 51 | q->normalize(); 52 | return q; 53 | } 54 | 55 | Quaternion *Quaternion::make_quaternion_from_euler(double angle1, double angle2, double angle3, string order){ 56 | Quaternion *Q1 = Quaternion::make_quaternion_from_axis(angle1, order[0]); 57 | Quaternion *Q2 = Quaternion::make_quaternion_from_axis(angle2, order[1]); 58 | Quaternion *Q3 = Quaternion::make_quaternion_from_axis(angle3, order[2]); 59 | Quaternion *q = Quaternion::multiply(Quaternion::multiply(Q1, Q2), Q3); 60 | q->normalize(); 61 | return q; 62 | } 63 | 64 | void Quaternion::to_matrix(){ 65 | normalize(); 66 | double w = d[0]; 67 | double x = d[1]; 68 | double y = d[2]; 69 | double z = d[3]; 70 | mat[0][0] = 1 - 2 * y * y - 2 * z * z; 71 | mat[0][1] = 2 * x * y - 2 * z * w; 72 | mat[0][2] = 2 * x * z + 2 * y * w; 73 | 74 | mat[1][0] = 2 * x * y + 2 * z * w; 75 | mat[1][1] = 1 - 2 * x * x - 2 * z * z; 76 | mat[1][2] = 2 * y * z - 2 * x * w; 77 | 78 | mat[2][0] = 2 * x * z - 2 * y * w; 79 | mat[2][1] = 2 * y * z + 2 * x * w; 80 | mat[2][2] = 1 - 2 * x * x - 2 * y * y; 81 | } 82 | 83 | void Quaternion::to_zyz(){ 84 | to_matrix(); 85 | e[0] = 0; 86 | e[1] = 0; 87 | e[2] = 0; 88 | if (mat[2][2] < 1) { 89 | if (mat[2][2] > -1) { 90 | e[0] = atan2(mat[1][2], mat[0][2]); 91 | e[1] = acos(mat[2][2]); 92 | e[2] = atan2(mat[2][1], -mat[2][0]); 93 | } else { 94 | e[0] = -atan2(mat[1][0], mat[1][1]); 95 | e[1] = PI; 96 | } 97 | }else{ 98 | e[0] = atan2(mat[1][0], mat[1][1]); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/quaternion.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * quaternion.hpp 3 | * 4 | * Created on: Oct 29, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef QUATERNION_HPP_ 9 | #define QUATERNION_HPP_ 10 | 11 | class Quaternion{ 12 | public: 13 | double d[4]; 14 | double e[3]; //euler angles 15 | double mat[3][3]; 16 | 17 | Quaternion(double w, double x, double y, double z){ 18 | d[0] = w; 19 | d[1] = x; 20 | d[2] = y; 21 | d[3] = z; 22 | } 23 | 24 | void normalize(); 25 | static Quaternion *make_quaternion_from_euler(double angle1, double angle2, double angle3, string order); 26 | static Quaternion *make_quaternion_from_axis(double angle, const char& axis); 27 | static Quaternion *multiply(Quaternion *q1, Quaternion *q2); 28 | void to_zyz(); 29 | void to_matrix(); 30 | }; 31 | 32 | 33 | 34 | #endif /* QUATERNION_HPP_ */ 35 | -------------------------------------------------------------------------------- /src/qubit.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * qubit.hpp 3 | * 4 | * Created on: Sep 2, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef QUBIT_HPP_ 9 | #define QUBIT_HPP_ 10 | 11 | class Qubit{ 12 | public: 13 | int id; 14 | int partition; 15 | Qubit(int qid){ 16 | id = qid; 17 | partition = 0; 18 | } 19 | }; 20 | 21 | class HwQubit: public Qubit{ 22 | public: 23 | HwQubit(int qid) : Qubit(qid){ 24 | } 25 | ~HwQubit(); 26 | }; 27 | 28 | class ProgQubit: public Qubit{ 29 | public: 30 | ProgQubit(int qid): Qubit(qid){ 31 | } 32 | ~ProgQubit(); 33 | }; 34 | 35 | #endif /* QUBIT_HPP_ */ 36 | -------------------------------------------------------------------------------- /src/targetter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * targetter.cpp 3 | * 4 | * Created on: Sep 14, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #include "targetter.hpp" 9 | 10 | void print_gate_seq(vector *v){ 11 | for(auto tmp : *v){ 12 | tmp->print(); 13 | } 14 | } 15 | void Targetter::map_single_qubit_gate(Gate *g, map current_map){ 16 | assert(g->vars.size() == 1); 17 | int hw_qubit_id = current_map[g->vars[0]]; 18 | Qubit *hwq = M->qubits[hw_qubit_id]; 19 | g->vars[0] = hwq; 20 | } 21 | 22 | void Targetter::map_two_qubit_gate_no_swap(Gate *g, map current_map){ 23 | assert(g->vars.size() == 2); 24 | int hw_qubit_id1 = current_map[g->vars[0]]; 25 | int hw_qubit_id2 = current_map[g->vars[1]]; 26 | Qubit *hwq1 = M->qubits[hw_qubit_id1]; 27 | Qubit *hwq2 = M->qubits[hw_qubit_id2]; 28 | g->vars[0] = hwq1; 29 | g->vars[1] = hwq2; 30 | } 31 | 32 | void Targetter::insert_swap_chain(vector &gate_seq, 33 | vector *swap_seq, SwapDirection dir) { 34 | if(swap_seq->size() <= 1) return; 35 | if (dir == ForwardSwap) { 36 | for (unsigned int i = 0; i < swap_seq->size()-1; i++) { 37 | Gate *g = Gate::create_new_gate("SWAP"); 38 | g->vars.push_back(M->qubits[swap_seq->at(i)]); 39 | g->vars.push_back(M->qubits[swap_seq->at(i + 1)]); 40 | gate_seq.push_back(g); 41 | } 42 | } else if (dir == ReverseSwap) { 43 | for (unsigned int i = swap_seq->size()-1; i > 0; i--) { 44 | Gate *g = Gate::create_new_gate("SWAP"); 45 | g->vars.push_back(M->qubits[swap_seq->at(i)]); 46 | g->vars.push_back(M->qubits[swap_seq->at(i - 1)]); 47 | gate_seq.push_back(g); 48 | } 49 | } 50 | } 51 | 52 | void Targetter::insert_two_qubit_op(vector &gate_seq, int ctrl, int targ){ 53 | Gate *g = Gate::create_new_gate("CNOT"); 54 | g->vars.push_back(M->qubits[ctrl]); 55 | g->vars.push_back(M->qubits[targ]); 56 | gate_seq.push_back(g); 57 | 58 | } 59 | 60 | void Targetter::copy_gate_connections_to_chain(Gate *g, vector &gate_seq, Circuit *I){ 61 | assert(gate_seq.size() >= 1); 62 | Gate *front = gate_seq.at(0); 63 | Gate *back = gate_seq.at(gate_seq.size()-1); 64 | //add front back connections 65 | front->pred = g->pred; 66 | for(auto d : g->pred){ 67 | d->succ.erase(remove(d->succ.begin(), d->succ.end(), g), d->succ.end()); 68 | d->succ.push_back(front); 69 | } 70 | back->succ = g->succ; 71 | for(auto d : g->succ){ 72 | d->pred.erase(remove(d->pred.begin(), d->pred.end(), g), d->pred.end()); 73 | d->pred.push_back(back); 74 | } 75 | //interlink each one 76 | Gate *g1, *g2; 77 | for(int i=0; isucc.push_back(g2); 81 | g2->pred.push_back(g1); 82 | } 83 | //how to handle sched_depends? 84 | //For the front gate - check if g is the target of any sched dependency 85 | //if yes, change g to front 86 | //For the back gate - check if g is the source of any sched dependency 87 | //if yes, change g to back 88 | vector > tmp_list = I->sched_depends; 89 | I->sched_depends.clear(); 90 | for(auto p : tmp_list){ 91 | g1 = p.first; 92 | g2 = p.second; 93 | if(g == g1){ 94 | I->sched_depends.push_back(make_pair(back, g2)); 95 | }else if(g == g2){ 96 | I->sched_depends.push_back(make_pair(g1, front)); 97 | }else{ 98 | I->sched_depends.push_back(make_pair(g1, g2)); 99 | } 100 | } 101 | } 102 | 103 | void Targetter::map_two_qubit_gate_to_swaps(Gate *g, BacktrackSolution *bs, Circuit *I, map *current_map){ 104 | assert((*current_map)[g->vars[0]] == bs->sinfo->c); 105 | assert((*current_map)[g->vars[1]] == bs->sinfo->t); 106 | for(auto qmap : *current_map){ 107 | int my_mapping = qmap.second; 108 | int expected_mapping = bs->pre_perm[qmap.first]; 109 | assert(my_mapping == expected_mapping); 110 | } 111 | SwapInfo *sinfo = bs->sinfo; 112 | vector gate_seq; 113 | 114 | #if 0 115 | g->print(); 116 | cout << "C" << bs->sinfo->c << endl; 117 | cout << "T" << bs->sinfo->t << endl; 118 | cout << "Dec" << bs->decision << endl; 119 | cout << "CE" << sinfo->ce << endl; 120 | cout << "TE" << sinfo->te << endl; 121 | #endif 122 | 123 | switch(bs->decision){ 124 | case CtrlRestore: 125 | insert_swap_chain(gate_seq, sinfo->c2te_path, ForwardSwap); 126 | insert_two_qubit_op(gate_seq, sinfo->te, sinfo->t); 127 | insert_swap_chain(gate_seq, sinfo->c2te_path, ReverseSwap); 128 | break; 129 | case TargRestore: 130 | insert_swap_chain(gate_seq, sinfo->t2ce_path, ForwardSwap); 131 | insert_two_qubit_op(gate_seq, sinfo->c, sinfo->ce); 132 | insert_swap_chain(gate_seq, sinfo->t2ce_path, ReverseSwap); 133 | break; 134 | case CtrlNotRestore: 135 | insert_swap_chain(gate_seq, sinfo->c2te_path, ForwardSwap); 136 | insert_two_qubit_op(gate_seq, sinfo->te, sinfo->t); 137 | break; 138 | case TargNotRestore: 139 | insert_swap_chain(gate_seq, sinfo->t2ce_path, ForwardSwap); 140 | insert_two_qubit_op(gate_seq, sinfo->c, sinfo->ce); 141 | break; 142 | default: 143 | assert(0); 144 | break; 145 | } 146 | /* 147 | //find set of qubits that this chain uses 148 | set overlap_set; 149 | for(auto Gi : gate_seq){ 150 | for(auto v : Gi->vars){ 151 | overlap_set.insert(v); 152 | } 153 | } 154 | 155 | //on these qubits, check for any parallel operations 156 | auto anc_gates = I->ancestors(g); 157 | 158 | //for each parallel operation, add a dependency to the head of this chain 159 | */ 160 | 161 | //add new gates to circuit I 162 | copy_gate_connections_to_chain(g, gate_seq, I); 163 | for(auto tmp_gate : gate_seq){ 164 | I->gates.push_back(tmp_gate); 165 | } 166 | I->gates.erase(remove(I->gates.begin(), I->gates.end(), g), I->gates.end()); 167 | for(auto qmap : bs->post_perm){ 168 | int expected_mapping = bs->post_perm[qmap.first]; 169 | (*current_map)[qmap.first] = expected_mapping; 170 | } 171 | } 172 | 173 | void Targetter::map_swaps_to_cnots(Gate *g, Circuit *I){ 174 | vector gate_seq; 175 | Gate *g1, *g2, *g3; 176 | g1 = Gate::create_new_gate("CNOT"); 177 | g2 = Gate::create_new_gate("CNOT"); 178 | g3 = Gate::create_new_gate("CNOT"); 179 | 180 | int qid1 = g->vars[0]->id; 181 | int qid2 = g->vars[1]->id; 182 | vector< pair > *dir = &(M->hw_cnot_directions); 183 | auto chk_1_2 = find(dir->begin(), dir->end(), make_pair(qid1, qid2)); 184 | auto chk_2_1 = find(dir->begin(), dir->end(), make_pair(qid2, qid1)); 185 | if(chk_1_2 != dir->end()){ 186 | g1->vars.push_back(g->vars[0]); 187 | g1->vars.push_back(g->vars[1]); 188 | g2->vars.push_back(g->vars[1]); 189 | g2->vars.push_back(g->vars[0]); 190 | g3->vars.push_back(g->vars[0]); 191 | g3->vars.push_back(g->vars[1]); 192 | }else{ 193 | g1->vars.push_back(g->vars[1]); 194 | g1->vars.push_back(g->vars[0]); 195 | g2->vars.push_back(g->vars[0]); 196 | g2->vars.push_back(g->vars[1]); 197 | g3->vars.push_back(g->vars[1]); 198 | g3->vars.push_back(g->vars[0]); 199 | } 200 | gate_seq.push_back(g1); 201 | gate_seq.push_back(g2); 202 | gate_seq.push_back(g3); 203 | copy_gate_connections_to_chain(g, gate_seq, I); 204 | for(auto tmp_gate : gate_seq){ 205 | I->gates.push_back(tmp_gate); 206 | } 207 | I->gates.erase(remove(I->gates.begin(), I->gates.end(), g), I->gates.end()); 208 | } 209 | 210 | void Targetter::map_cnots_to_cz(Gate *g, Circuit *I){ 211 | vector gate_seq; 212 | Gate *g1, *g2, *g3; 213 | g1 = Gate::create_new_gate("H"); 214 | g2 = Gate::create_new_gate("CZ"); 215 | g3 = Gate::create_new_gate("H"); 216 | 217 | g1->vars.push_back(g->vars[1]); 218 | g2->vars.push_back(g->vars[0]); 219 | g2->vars.push_back(g->vars[1]); 220 | g3->vars.push_back(g->vars[1]); 221 | 222 | gate_seq.push_back(g1); 223 | gate_seq.push_back(g2); 224 | gate_seq.push_back(g3); 225 | copy_gate_connections_to_chain(g, gate_seq, I); 226 | for(auto tmp_gate : gate_seq){ 227 | I->gates.push_back(tmp_gate); 228 | } 229 | I->gates.erase(remove(I->gates.begin(), I->gates.end(), g), I->gates.end()); 230 | } 231 | 232 | 233 | void Targetter::_external_link(Gate *g, vector gate_list, Circuit *I, int link_direction){ 234 | vector common_list; 235 | common_list = gate_list; 236 | for(auto p : I->sched_depends){ 237 | Gate *check_gate; 238 | Gate *add_gate; 239 | if(link_direction == Predecessor){ 240 | check_gate = p.second; 241 | add_gate = p.first; 242 | }else{ 243 | check_gate = p.first; 244 | add_gate = p.second; 245 | } 246 | if(check_gate == g){ 247 | if(find(common_list.begin(), common_list.end(), add_gate) == common_list.end()){ 248 | common_list.push_back(add_gate); 249 | } 250 | } 251 | } 252 | 253 | vector to_link; 254 | if(common_list.empty()){ //link to all gates in gate_list 255 | to_link = gate_list; 256 | }else{ 257 | to_link = common_list; 258 | } 259 | for(auto friend_gate : to_link){ 260 | if(link_direction == Predecessor){ 261 | g->pred.push_back(friend_gate); 262 | friend_gate->succ.push_back(g); 263 | }else{ 264 | g->succ.push_back(friend_gate); 265 | friend_gate->pred.push_back(g); 266 | } 267 | } 268 | } 269 | 270 | void Targetter::implement_hardware_directions_for_cnots(Gate *g, Circuit *I){ 271 | int qid1 = g->vars[0]->id; 272 | int qid2 = g->vars[1]->id; 273 | vector< pair > *dir = &(M->hw_cnot_directions); 274 | auto chk_1_2 = find(dir->begin(), dir->end(), make_pair(qid1, qid2)); 275 | auto chk_2_1 = find(dir->begin(), dir->end(), make_pair(qid2, qid1)); 276 | if(chk_1_2 != dir->end()){ 277 | return; //this cnot doesnt need modification 278 | }else{ 279 | assert(chk_2_1 != dir->end()); 280 | 281 | Gate *h1 = Gate::create_new_gate("H"); 282 | Gate *h2 = Gate::create_new_gate("H"); 283 | Gate *h3 = Gate::create_new_gate("H"); 284 | Gate *h4 = Gate::create_new_gate("H"); 285 | Gate *rev_cx = Gate::create_new_gate("CNOT"); 286 | h1->vars.push_back(g->vars[0]); 287 | h2->vars.push_back(g->vars[1]); 288 | rev_cx->vars.push_back(g->vars[1]); 289 | rev_cx->vars.push_back(g->vars[0]); 290 | h3->vars.push_back(g->vars[0]); 291 | h4->vars.push_back(g->vars[1]); 292 | 293 | //setup internal dependency 294 | h1->succ.push_back(rev_cx); 295 | h2->succ.push_back(rev_cx); 296 | rev_cx->pred.push_back(h1); 297 | rev_cx->pred.push_back(h2); 298 | 299 | rev_cx->succ.push_back(h3); 300 | rev_cx->succ.push_back(h4); 301 | h3->pred.push_back(rev_cx); 302 | h4->pred.push_back(rev_cx); 303 | 304 | vector > tmp_list = I->sched_depends; 305 | I->sched_depends.clear(); 306 | for(auto p : tmp_list){ 307 | Gate *g1 = p.first; 308 | Gate* g2 = p.second; 309 | if(g == g1){ //g is source 310 | I->sched_depends.push_back(make_pair(h3, g2)); 311 | I->sched_depends.push_back(make_pair(h4, g2)); 312 | }else if(g == g2){ //g is target 313 | I->sched_depends.push_back(make_pair(g1, h1)); 314 | I->sched_depends.push_back(make_pair(g1, h2)); 315 | }else{ 316 | I->sched_depends.push_back(make_pair(g1, g2)); 317 | } 318 | } 319 | 320 | //setup external dependency 321 | _external_link(h1, g->pred, I, Predecessor); 322 | _external_link(h2, g->pred, I, Predecessor); 323 | _external_link(h3, g->succ, I, Successor); 324 | _external_link(h4, g->succ, I, Successor); 325 | 326 | for(auto pred_gate : g->pred){ 327 | pred_gate->succ.erase(remove(pred_gate->succ.begin(), pred_gate->succ.end(), g), pred_gate->succ.end()); 328 | } 329 | for(auto succ_gate : g->succ){ 330 | succ_gate->pred.erase(remove(succ_gate->pred.begin(), succ_gate->pred.end(), g), succ_gate->pred.end()); 331 | } 332 | 333 | I->gates.push_back(h1); 334 | I->gates.push_back(h2); 335 | I->gates.push_back(rev_cx); 336 | I->gates.push_back(h3); 337 | I->gates.push_back(h4); 338 | I->gates.erase(remove(I->gates.begin(), I->gates.end(), g), I->gates.end()); 339 | } 340 | } 341 | 342 | Circuit* Targetter::map_and_insert_swap_operations(){ 343 | //C->print_sched_depends(); 344 | 345 | Circuit *I = new Circuit(); 346 | map *old2new = new map; 347 | C->duplicate_circuit(I, old2new); 348 | map current_map = *initial_map; 349 | 350 | for(auto old_gate : *gate_order){ 351 | Gate *new_gate = (*old2new)[old_gate]; 352 | if(old_gate->vars.size() == 1){ 353 | map_single_qubit_gate(new_gate, current_map); 354 | }else if(old_gate->vars.size() == 2){ 355 | BacktrackSolution *bs = bsol[old_gate]; 356 | map_two_qubit_gate_to_swaps(new_gate, bs, I, ¤t_map); 357 | } 358 | } 359 | 360 | final_map = current_map; 361 | 362 | //cout << "I dependencies:\n"; 363 | //I->print_sched_depends(); 364 | 365 | delete old2new; 366 | 367 | Circuit *J = new Circuit(); 368 | old2new = new map; 369 | I->duplicate_circuit(J, old2new); 370 | 371 | for(auto g : I->gates){ 372 | if(typeid(*g) == typeid(SWAP)){ 373 | map_swaps_to_cnots((*old2new)[g], J); 374 | } 375 | } 376 | 377 | 378 | //cout << "J dependencies:\n"; 379 | //J->print_sched_depends(); 380 | 381 | Circuit *K = new Circuit(); 382 | delete old2new; 383 | old2new = new map; 384 | J->duplicate_circuit(K, old2new); 385 | 386 | //cout << "K initial dependencies:\n"; 387 | //K->print_sched_depends(); 388 | 389 | //if ibmqx5:, 390 | 391 | for(auto g : J->gates){ 392 | if(typeid(*g) == typeid(CNOT)){ 393 | //cout << "CNT=" << cnt << endl << endl; 394 | if(M->machine_name == "ibmqx4" || M->machine_name == "ibmqx5" || M->machine_name == "ibmq_16_melbourne"){ 395 | implement_hardware_directions_for_cnots((*old2new)[g], K); 396 | }else if(M->machine_name == "agave" || M->machine_name == "Aspen1" || M->machine_name == "Aspen3"){ 397 | map_cnots_to_cz((*old2new)[g], K); 398 | }else; 399 | //stringstream fname; 400 | } 401 | } 402 | K->qubits = M->qubits; 403 | 404 | 405 | delete I; 406 | delete J; 407 | return K; 408 | } 409 | 410 | void Targetter::implement_gate_for_trapped_ion(Gate *g, Circuit *I){ 411 | vector pred_interface; 412 | vector succ_interface; 413 | vector new_gates; 414 | if(typeid(*g) == typeid(H)){ 415 | Gate *g1 = Gate::create_new_gate("RZ"); 416 | Gate *g2 = Gate::create_new_gate("RY"); 417 | g1->angle = PI; 418 | g2->angle = PI/2; 419 | g1->vars.push_back(g->vars[0]); 420 | g2->vars.push_back(g->vars[0]); 421 | g1->succ.push_back(g2); 422 | g2->pred.push_back(g1); 423 | pred_interface.push_back(g1); 424 | succ_interface.push_back(g2); 425 | new_gates.push_back(g1); 426 | new_gates.push_back(g2); 427 | }else if(typeid(*g) == typeid(X)){ 428 | Gate *g1 = Gate::create_new_gate("RX"); 429 | g1->angle = PI; 430 | g1->vars.push_back(g->vars[0]); 431 | pred_interface.push_back(g1); 432 | succ_interface.push_back(g1); 433 | new_gates.push_back(g1); 434 | }else if(typeid(*g) == typeid(Y)){ 435 | Gate *g1 = Gate::create_new_gate("RY"); 436 | g1->angle = PI; 437 | g1->vars.push_back(g->vars[0]); 438 | pred_interface.push_back(g1); 439 | succ_interface.push_back(g1); 440 | new_gates.push_back(g1); 441 | }else if(typeid(*g) == typeid(Z)){ 442 | Gate *g1 = Gate::create_new_gate("RZ"); 443 | g1->angle = PI; 444 | g1->vars.push_back(g->vars[0]); 445 | pred_interface.push_back(g1); 446 | succ_interface.push_back(g1); 447 | new_gates.push_back(g1); 448 | }else if(typeid(*g) == typeid(S)){ 449 | Gate *g1 = Gate::create_new_gate("RZ"); 450 | g1->angle = PI/2; 451 | g1->vars.push_back(g->vars[0]); 452 | pred_interface.push_back(g1); 453 | succ_interface.push_back(g1); 454 | new_gates.push_back(g1); 455 | }else if(typeid(*g) == typeid(Sdag)){ 456 | Gate *g1 = Gate::create_new_gate("RZ"); 457 | g1->angle = -PI/2; 458 | g1->vars.push_back(g->vars[0]); 459 | pred_interface.push_back(g1); 460 | succ_interface.push_back(g1); 461 | new_gates.push_back(g1); 462 | }else if(typeid(*g) == typeid(T)){ 463 | Gate *g1 = Gate::create_new_gate("RZ"); 464 | g1->angle = PI/4; 465 | g1->vars.push_back(g->vars[0]); 466 | pred_interface.push_back(g1); 467 | succ_interface.push_back(g1); 468 | new_gates.push_back(g1); 469 | }else if(typeid(*g) == typeid(Tdag)){ 470 | Gate *g1 = Gate::create_new_gate("RZ"); 471 | g1->angle = -PI/4; 472 | g1->vars.push_back(g->vars[0]); 473 | pred_interface.push_back(g1); 474 | succ_interface.push_back(g1); 475 | new_gates.push_back(g1); 476 | }else if(typeid(*g) == typeid(CNOT)){ 477 | if(1){ 478 | Gate *g1 = Gate::create_new_gate("RY"); 479 | Gate *g2 = Gate::create_new_gate("XX"); 480 | Gate *g3 = Gate::create_new_gate("RY"); 481 | Gate *g4 = Gate::create_new_gate("RX"); 482 | Gate *g5 = Gate::create_new_gate("RZ"); 483 | g1->angle = PI/2; 484 | g2->angle = PI/4; 485 | g3->angle = -PI/2; 486 | g4->angle = -PI/2; 487 | g5->angle = -PI/2; 488 | g1->vars.push_back(g->vars[0]); 489 | g2->vars.push_back(g->vars[0]); 490 | g2->vars.push_back(g->vars[1]); 491 | g3->vars.push_back(g->vars[0]); 492 | g4->vars.push_back(g->vars[1]); 493 | g5->vars.push_back(g->vars[0]); 494 | 495 | g1->succ.push_back(g2); 496 | g2->pred.push_back(g1); 497 | g2->succ.push_back(g3); 498 | g3->pred.push_back(g2); 499 | g2->succ.push_back(g4); 500 | g4->pred.push_back(g2); 501 | g3->succ.push_back(g5); 502 | g5->pred.push_back(g4); 503 | 504 | pred_interface.push_back(g1); 505 | pred_interface.push_back(g2); 506 | succ_interface.push_back(g4); 507 | succ_interface.push_back(g5); 508 | new_gates.push_back(g1); 509 | new_gates.push_back(g2); 510 | new_gates.push_back(g3); 511 | new_gates.push_back(g4); 512 | new_gates.push_back(g5); 513 | } 514 | if(0){ 515 | //buggy, not working 516 | Gate *g1 = Gate::create_new_gate("CNOT"); 517 | g1->vars.push_back(g->vars[0]); 518 | g1->vars.push_back(g->vars[1]); 519 | pred_interface.push_back(g1); 520 | succ_interface.push_back(g1); 521 | new_gates.push_back(g1); 522 | } 523 | } 524 | 525 | for (auto front_gate : pred_interface) 526 | _external_link(front_gate, g->pred, I, Predecessor); 527 | for (auto back_gate : succ_interface) 528 | _external_link(back_gate, g->succ, I, Successor); 529 | for(auto pred_gate : g->pred) 530 | pred_gate->succ.erase(remove(pred_gate->succ.begin(), pred_gate->succ.end(), g), pred_gate->succ.end()); 531 | for(auto succ_gate : g->succ) 532 | succ_gate->pred.erase(remove(succ_gate->pred.begin(), succ_gate->pred.end(), g), succ_gate->pred.end()); 533 | for(auto ngate : new_gates) 534 | I->gates.push_back(ngate); 535 | I->gates.erase(remove(I->gates.begin(), I->gates.end(), g), I->gates.end()); 536 | } 537 | 538 | Circuit* Targetter::map_to_trapped_ion(){ 539 | Circuit *I = new Circuit(); 540 | map *old2new = new map; 541 | C->duplicate_circuit(I, old2new); 542 | map current_map = *initial_map; 543 | 544 | for(auto old_gate : *gate_order){ 545 | Gate *new_gate = (*old2new)[old_gate]; 546 | if(old_gate->vars.size() == 1){ 547 | map_single_qubit_gate(new_gate, current_map); 548 | }else if(old_gate->vars.size() == 2){ 549 | BacktrackSolution *bs = bsol[old_gate]; 550 | map_two_qubit_gate_no_swap(new_gate, current_map); 551 | } 552 | } 553 | 554 | for(auto old_gate : *gate_order){ 555 | Gate *new_gate = (*old2new)[old_gate]; 556 | if(typeid(*new_gate) != typeid(MeasZ)){ 557 | implement_gate_for_trapped_ion(new_gate, I); 558 | } 559 | } 560 | return I; 561 | } 562 | 563 | void Targetter::print_header(ofstream &out_file){ 564 | if(M->machine_name == "ibmqx5"){ 565 | out_file << "OPENQASM 2.0;\n"; 566 | out_file << "include \"qelib1.inc\";\n"; 567 | out_file << "qreg q[16];\n"; 568 | out_file << "creg c[16];\n"; 569 | } 570 | if(M->machine_name == "ibmqx4"){ 571 | out_file << "OPENQASM 2.0;\n"; 572 | out_file << "include \"qelib1.inc\";\n"; 573 | out_file << "qreg q[5];\n"; 574 | out_file << "creg c[5];\n"; 575 | } 576 | if(M->machine_name == "ibmq_16_melbourne"){ 577 | out_file << "OPENQASM 2.0;\n"; 578 | out_file << "include \"qelib1.inc\";\n"; 579 | out_file << "qreg q[14];\n"; 580 | out_file << "creg c[14];\n"; 581 | } 582 | if(M->machine_name == "agave"){ 583 | out_file << "from pyquil import Program, get_qc\n"; 584 | out_file << "from pyquil.gates import *\n"; 585 | out_file << "import numpy as np\n"; 586 | out_file << "from collections import defaultdict\n"; 587 | out_file << "qc = get_qc(\"Aspen-1-16Q-A\", as_qvm=True)\n"; 588 | out_file << "p = Program()\n"; 589 | } 590 | if(M->machine_name == "Aspen1"){ 591 | out_file << "from pyquil import Program, get_qc\n"; 592 | out_file << "from pyquil.gates import *\n"; 593 | out_file << "import numpy as np\n"; 594 | out_file << "from collections import defaultdict\n"; 595 | out_file << "qc = get_qc(\"Aspen-1-16Q-A\", as_qvm=True)\n"; 596 | out_file << "p = Program()\n"; 597 | } 598 | if(M->machine_name == "Aspen3"){ 599 | out_file << "from pyquil import Program, get_qc\n"; 600 | out_file << "from pyquil.gates import *\n"; 601 | out_file << "import numpy as np\n"; 602 | out_file << "from collections import defaultdict\n"; 603 | out_file << "qc = get_qc(\"Aspen-3-14Q-A\", as_qvm=True)\n"; 604 | out_file << "p = Program()\n"; 605 | } 606 | if(M->machine_name == "Aer"){ 607 | out_file << "import pickle\n"; 608 | out_file << "from qiskit import QuantumRegister, ClassicalRegister\n"; 609 | out_file << "from qiskit import QuantumCircuit, execute, Aer, IBMQ\n"; 610 | out_file << "from qiskit.providers.aer import noise\n"; 611 | out_file << "from qiskit.providers.aer.noise import NoiseModel\n"; 612 | out_file << "from qiskit.providers.models import BackendProperties\n"; 613 | out_file << "from qiskit.providers.models.backendproperties import *\n"; 614 | out_file << "from numpy.random import choice\n"; 615 | out_file << "noise_data = pickle.load(open(\"/home/pmurali/code/aer_interface/Aer16.1_Sim.pkl\", 'rb'))\n"; 616 | out_file << "properties = noise_data[0]\n"; 617 | out_file << "coupling_map = noise_data[1]\n"; 618 | out_file << "noise_model = noise.device.basic_device_noise_model(properties, thermal_relaxation=False)\n"; 619 | out_file << "basis_gates = noise_model.basis_gates\n"; 620 | out_file << "q = QuantumRegister(16)\n"; 621 | out_file << "c = ClassicalRegister(16)\n"; 622 | out_file << "qc = QuantumCircuit(q, c)\n"; 623 | 624 | } 625 | } 626 | 627 | void Targetter::print_footer(ofstream &out_file) { 628 | if (M->machine_name == "agave") { 629 | //out_file << "x=qpu.run(p, [0, 1, 2, 3], 1024)\n"; 630 | //out_file << "print(x)\n"; 631 | out_file << "p.wrap_in_numshots_loop(10)\n"; 632 | out_file << "executable = qc.compile(p, to_native_gates=False, optimize=False)\n"; 633 | out_file << "print(executable)\n"; 634 | out_file << "bitstrings = qc.run(executable)\n"; 635 | out_file << "print(bitstrings)\n"; 636 | } 637 | if (M->machine_name == "Aspen1" || M->machine_name == "Aspen3") { 638 | out_file << "count = 8192\n"; 639 | out_file << "p.wrap_in_numshots_loop(count)\n"; 640 | out_file << "executable = qc.compile(p, to_native_gates=False, optimize=False)\n"; 641 | out_file << "print(executable)\n"; 642 | out_file << "bs = qc.run(executable)\n"; 643 | out_file << "outs = {}\n"; 644 | out_file << "for item in bs:\n"; 645 | out_file << " thisstr = \"\"\n"; 646 | out_file << " for i in item:\n"; 647 | out_file << " thisstr += str(i)\n"; 648 | out_file << " if not thisstr in outs:\n"; 649 | out_file << " outs[thisstr] = 1\n"; 650 | out_file << " else:\n"; 651 | out_file << " outs[thisstr] += 1\n"; 652 | out_file << "for key in outs:\n"; 653 | out_file << " print(key, float(outs[key])/count)\n"; 654 | } 655 | if (M->machine_name == "Aer"){ 656 | out_file << "backend = Aer.get_backend('qasm_simulator')\n"; 657 | out_file << "job_sim = execute(qc, backend, coupling_map=coupling_map, noise_model=noise_model, basis_gates=basis_gates, shots=1024)\n"; 658 | out_file << "sim_result = job_sim.result()\n"; 659 | out_file << "print(sim_result.get_counts(qc))\n"; 660 | } 661 | } 662 | void Targetter::print_measure_ops(ofstream &out_file){ 663 | if (M->machine_name == "ibmqx5" || M->machine_name == "ibmqx4" || M->machine_name == "ibmq_16_melbourne") { 664 | for (auto mapping : final_map) { 665 | Qubit *q = mapping.first; 666 | int hwq = mapping.second; 667 | out_file << "measure " << "q[" << hwq << "] -> c[" << q->id 668 | << "];\n"; 669 | } 670 | }else if(M->machine_name == "agave" || M->machine_name == "Aspen1"|| M->machine_name == "Aspen3"){ 671 | int num_qubits = C->qubits.size(); 672 | out_file << "ro = p.declare(\'ro\', \'BIT\'," << num_qubits << ")\n"; 673 | 674 | for (auto mapping : final_map) { 675 | Qubit *q = mapping.first; 676 | int hwq = mapping.second; 677 | if(M->machine_name == "Aspen1") hwq = aspen1_map[hwq]; 678 | if(M->machine_name == "Aspen3") hwq = aspen3_map[hwq]; 679 | 680 | out_file << "p += MEASURE(" << hwq << ", ro[" << q->id << "])\n"; 681 | } 682 | }else if(M->machine_name == "Aer"){ 683 | for (auto mapping : final_map) { 684 | Qubit *q = mapping.first; 685 | int hwq = mapping.second; 686 | out_file << "qc.measure(" << "q[" << hwq << "], c[" << q->id << "])\n"; 687 | } 688 | } 689 | } 690 | void Targetter::print_code(Circuit *I, string fname){ 691 | ofstream out_file; 692 | out_file.open(fname.c_str(), ofstream::out); 693 | cout << "fname:" << fname << endl; 694 | vector* torder = I->topological_ordering(); 695 | print_header(out_file); 696 | 697 | int cx_count=0; 698 | 699 | Gate *last_gate = torder->back(); 700 | int is_last_gate=0; 701 | for(auto g : *torder){ 702 | if(M->machine_name == "tion"){ 703 | if(g == last_gate) 704 | is_last_gate = 1; 705 | } 706 | if(g->vars.size() == 1){ 707 | print_one_qubit_gate(g, out_file, is_last_gate); 708 | }else if(g->vars.size() == 2){ 709 | print_two_qubit_gate(g, out_file, is_last_gate); 710 | cx_count++; 711 | }else{ 712 | assert(0); 713 | } 714 | } 715 | cout << "Num CX:" << cx_count << endl; 716 | print_measure_ops(out_file); 717 | print_footer(out_file); 718 | } 719 | 720 | void Targetter::print_one_qubit_gate(Gate *g, ofstream &out_file, int is_last_gate){ 721 | int qid = g->vars[0]->id; 722 | string gate_name; 723 | string tion_sep = "\n"; 724 | if(typeid(*g) == typeid(MeasZ)){ 725 | return; 726 | } 727 | if(M->machine_name == "Aer"){ 728 | gate_name = gate_print_ibm[typeid(*g)]; 729 | stringstream var_name; 730 | var_name << "q"; 731 | var_name << "["; 732 | var_name << qid; 733 | var_name << "]"; 734 | out_file << "qc." << gate_name << "(" << var_name.str() << ")\n"; 735 | } 736 | else if(M->machine_name == "ibmqx5" || M->machine_name == "ibmqx4" || M->machine_name == "ibmq_16_melbourne"){ 737 | if(typeid(*g) == typeid(U1) && g->lambda == 0){ 738 | return; 739 | } 740 | gate_name = gate_print_ibm[typeid(*g)]; 741 | out_file << gate_name; 742 | if(typeid(*g) == typeid(U1)){ 743 | out_file << setprecision(15) << "(" << g->lambda << ")"; 744 | }else if(typeid(*g) == typeid(U2)){ 745 | out_file << setprecision(15) << "(" << g->phi << "," << g->lambda << ")"; 746 | }else if(typeid(*g) == typeid(U3)){ 747 | out_file << setprecision(15) << "(" << g->theta << "," << g->phi << "," << g->lambda << ")"; 748 | }else; 749 | out_file << " "; 750 | stringstream var_name; 751 | var_name << "q"; 752 | var_name << "["; 753 | var_name << qid; 754 | var_name << "]"; 755 | out_file << var_name.str() << ";\n"; 756 | } 757 | else if(M->machine_name == "agave" || M->machine_name == "Aspen1" || M->machine_name == "Aspen3"){ 758 | if(M->machine_name == "Aspen1"){ 759 | qid = aspen1_map[qid]; 760 | } 761 | if(M->machine_name == "Aspen3"){ 762 | qid = aspen3_map[qid]; 763 | } 764 | 765 | if(typeid(*g) == typeid(U1)){ 766 | out_file << setprecision(15) << "p += RZ(" << g->lambda << "," << qid << ")\n"; 767 | }else if(typeid(*g) == typeid(U2)){ 768 | double ang1, ang2, ang3; 769 | ang1 = g->phi + PI/2; 770 | ang2 = PI/2; 771 | ang3 = g->lambda - PI/2; 772 | out_file << setprecision(15) << "p += RZ(" << ang3 << "," << qid << ")\n"; 773 | out_file << setprecision(15) << "p += RX(" << ang2 << "," << qid << ")\n"; 774 | out_file << setprecision(15) << "p += RZ(" << ang1 << "," << qid << ")\n"; 775 | }else if(typeid(*g) == typeid(U3)){ 776 | double ang1, ang2, ang3, ang4, ang5; 777 | ang1 = g->phi + 3*PI; 778 | ang2 = PI/2; 779 | ang3 = g->theta + PI; 780 | ang4 = PI/2; 781 | ang5 = g->lambda; 782 | out_file << setprecision(15) << "p += RZ(" << ang5 << "," << qid << ")\n"; 783 | out_file << setprecision(15) << "p += RX(" << ang4 << "," << qid << ")\n"; 784 | out_file << setprecision(15) << "p += RZ(" << ang3 << "," << qid << ")\n"; 785 | out_file << setprecision(15) << "p += RX(" << ang2 << "," << qid << ")\n"; 786 | out_file << setprecision(15) << "p += RZ(" << ang1 << "," << qid << ")\n"; 787 | }else{ 788 | gate_name = gate_print_rigetti[typeid(*g)]; 789 | out_file << "p += " << gate_name; 790 | out_file << "(" << qid << ")\n"; 791 | } 792 | } 793 | else if(M->machine_name == "tion"){ 794 | double fthresh = 0.0001; 795 | if(typeid(*g) == typeid(U1) || typeid(*g) == typeid(U2) || typeid(*g) == typeid(U3)){ 796 | double pitheta = remainder(g->theta/(PI), 2); 797 | double piphi = remainder(g->phi/(PI), 2); 798 | double pilambda = remainder(g->lambda/(PI), 2); 799 | //g->print(); 800 | if(typeid(*g) == typeid(U1)){ 801 | //Z(lambda) 802 | if (pilambda != 0 && fabs(pilambda) >= fthresh) { 803 | out_file << "AZ" << qid + 1; 804 | if (pilambda >= 0) 805 | out_file << "+"; 806 | else 807 | out_file << "-"; 808 | out_file << std::fixed << setprecision(4) << abs(pilambda); 809 | if(!is_last_gate) out_file << tion_sep; 810 | } 811 | }else{ 812 | //RZ(lambda) 813 | if (pilambda != 0 && fabs(pilambda) >= fthresh) { 814 | out_file << "AZ" << qid + 1; 815 | if (pilambda >= 0) 816 | out_file << "+"; 817 | else 818 | out_file << "-"; 819 | out_file << std::fixed << setprecision(4) << abs(pilambda); 820 | out_file << tion_sep; 821 | } 822 | //RY(theta) 823 | if (pitheta != 0 && fabs(pitheta) >= fthresh) { 824 | out_file << "RA" << qid + 1; 825 | if (pitheta >= 0) 826 | out_file << "+"; 827 | else 828 | out_file << "-"; 829 | out_file << std::fixed << setprecision(4) << abs(pitheta) << "," 830 | << 0.5; 831 | out_file << tion_sep; 832 | } 833 | //RZ(phi) 834 | if (piphi != 0 && fabs(piphi) >= fthresh) { 835 | out_file << "AZ" << qid + 1; 836 | if (piphi >= 0) 837 | out_file << "+"; 838 | else 839 | out_file << "-"; 840 | out_file << std::fixed << setprecision(4) << abs(piphi); 841 | if(!is_last_gate) out_file << tion_sep; 842 | } 843 | } 844 | } else { 845 | cout << "Warning: unoptimized trapped ion code printed\n"; 846 | gate_name = gate_print_tion[typeid(*g)]; 847 | out_file << gate_name; 848 | int pi_div_factor = floor(PI / g->angle); 849 | if (pi_div_factor >= 0) { 850 | out_file << "+"; 851 | } else { 852 | out_file << "-"; 853 | } 854 | out_file << qid + 1; 855 | out_file << abs(pi_div_factor) << tion_sep; 856 | } 857 | }else; 858 | 859 | } 860 | 861 | void Targetter::print_two_qubit_gate(Gate *g, ofstream &out_file, int is_last_gate){ 862 | int qid1 = g->vars[0]->id; 863 | int qid2 = g->vars[1]->id; 864 | string gate_name; 865 | string tion_sep = "\n"; 866 | if(M->machine_name == "Aer"){ 867 | gate_name = gate_print_ibm[typeid(*g)]; 868 | stringstream var_name1, var_name2; 869 | var_name1 << "q[" << qid1 << "]"; 870 | var_name2 << "q[" << qid2 << "]"; 871 | out_file << "qc." << gate_name << "(" << var_name1.str() << "," << var_name2.str() << ")\n"; 872 | } 873 | if(M->machine_name == "ibmqx5" || M->machine_name == "ibmqx4" || M->machine_name == "ibmq_16_melbourne"){ 874 | gate_name = gate_print_ibm[typeid(*g)]; 875 | out_file << gate_name << " "; 876 | stringstream var_name1, var_name2; 877 | var_name1 << "q[" << qid1 << "]"; 878 | var_name2 << "q[" << qid2 << "]"; 879 | out_file << var_name1.str() << "," << var_name2.str() << ";" << endl; 880 | }else if(M->machine_name == "agave" || M->machine_name == "Aspen1" || M->machine_name == "Aspen3"){ 881 | if(M->machine_name == "Aspen1"){ 882 | qid1 = aspen1_map[qid1]; 883 | qid2 = aspen1_map[qid2]; 884 | } 885 | if(M->machine_name == "Aspen3"){ 886 | qid1 = aspen3_map[qid1]; 887 | qid2 = aspen3_map[qid2]; 888 | } 889 | gate_name = gate_print_rigetti[typeid(*g)]; 890 | out_file << "p +=" << gate_name << "(" << qid1 << "," << qid2 << ")\n"; 891 | }else if(M->machine_name == "tion"){ 892 | if (typeid(*g) == typeid(CNOT)) { 893 | out_file << "CN" << qid1 + 1 << qid2 + 1; 894 | if (!is_last_gate){ 895 | out_file << tion_sep; 896 | } 897 | } else { 898 | gate_name = gate_print_tion[typeid(*g)]; 899 | out_file << gate_name; 900 | int pi_div_factor = floor(PI / g->angle); 901 | assert(pi_div_factor == 4 || pi_div_factor == -4); 902 | out_file << qid1 + 1 << qid2 + 1; 903 | if (pi_div_factor >= 0) { 904 | out_file << "+"; 905 | } else { 906 | out_file << "-"; 907 | } 908 | if (!is_last_gate) 909 | out_file << tion_sep; 910 | } 911 | } 912 | } 913 | 914 | void Targetter::init_gate_print_maps(){ 915 | gate_print_ibm[typeid(CNOT)] = "cx"; 916 | gate_print_ibm[typeid(H)] = "h"; 917 | gate_print_ibm[typeid(X)] = "x"; 918 | gate_print_ibm[typeid(Y)] = "y"; 919 | gate_print_ibm[typeid(Z)] = "z"; 920 | gate_print_ibm[typeid(T)] = "t"; 921 | gate_print_ibm[typeid(Tdag)] = "tdg"; 922 | gate_print_ibm[typeid(S)] = "s"; 923 | gate_print_ibm[typeid(Sdag)] = "sdg"; 924 | gate_print_ibm[typeid(MeasZ)] = "measure"; 925 | gate_print_ibm[typeid(U1)] = "u1"; 926 | gate_print_ibm[typeid(U2)] = "u2"; 927 | gate_print_ibm[typeid(U3)] = "u3"; 928 | 929 | 930 | gate_print_rigetti[typeid(CNOT)] = "CNOT"; 931 | gate_print_rigetti[typeid(CZ)] = "CZ"; 932 | gate_print_rigetti[typeid(H)] = "H"; 933 | gate_print_rigetti[typeid(X)] = "X"; 934 | gate_print_rigetti[typeid(Y)] = "Y"; 935 | gate_print_rigetti[typeid(Z)] = "Z"; 936 | gate_print_rigetti[typeid(T)] = "T"; 937 | gate_print_rigetti[typeid(Tdag)] = "RZ(-np.pi/4)"; 938 | gate_print_rigetti[typeid(S)] = "S"; 939 | gate_print_rigetti[typeid(Sdag)] = "RZ(-np.pi/2)"; 940 | gate_print_rigetti[typeid(MeasZ)] = "MEASURE"; 941 | 942 | gate_print_tion[typeid(XX)] = "XX"; 943 | gate_print_tion[typeid(RX)] = "RX"; 944 | gate_print_tion[typeid(RY)] = "RY"; 945 | gate_print_tion[typeid(RZ)] = "RZ"; 946 | 947 | aspen1_map[0] = 0; 948 | aspen1_map[1] = 1; 949 | aspen1_map[2] = 2; 950 | aspen1_map[3] = 3; 951 | aspen1_map[4] = 4; 952 | aspen1_map[5] = 5; 953 | aspen1_map[6] = 6; 954 | aspen1_map[7] = 7; 955 | 956 | aspen1_map[8] = 10; 957 | aspen1_map[9] = 11; 958 | aspen1_map[10] = 12; 959 | aspen1_map[11] = 13; 960 | aspen1_map[12] = 14; 961 | aspen1_map[13] = 15; 962 | aspen1_map[14] = 16; 963 | aspen1_map[15] = 17; 964 | 965 | aspen3_map[0] = 0; 966 | aspen3_map[1] = 1; 967 | aspen3_map[2] = 2; 968 | aspen3_map[3] = 3; 969 | aspen3_map[4] = 4; 970 | aspen3_map[5] = 5; 971 | aspen3_map[6] = 6; 972 | 973 | aspen3_map[7] = 10; 974 | aspen3_map[8] = 11; 975 | aspen3_map[9] = 12; 976 | aspen3_map[10] = 13; 977 | aspen3_map[11] = 14; 978 | aspen3_map[12] = 15; 979 | aspen3_map[13] = 16; 980 | 981 | } 982 | -------------------------------------------------------------------------------- /src/targetter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * targetter.hpp 3 | * 4 | * Created on: Sep 14, 2018 5 | * Author: prakash 6 | */ 7 | 8 | #ifndef TARGETTER_HPP_ 9 | #define TARGETTER_HPP_ 10 | 11 | #include "headers.hpp" 12 | #include "circuit.hpp" 13 | #include "backtrack.hpp" 14 | #include "machine.hpp" 15 | 16 | enum SwapDirection{ 17 | ForwardSwap, ReverseSwap 18 | }; 19 | 20 | enum LinkDirection{ 21 | Predecessor, Successor 22 | }; 23 | 24 | class Targetter{ 25 | public: 26 | Machine *M; 27 | Circuit *C; 28 | 29 | map *initial_map; 30 | map final_map; 31 | vector *gate_order; 32 | map bsol; 33 | 34 | unordered_map gate_print_ibm; 35 | unordered_map gate_print_rigetti; 36 | unordered_map gate_print_tion; 37 | 38 | map aspen1_map; 39 | map aspen3_map; 40 | 41 | Targetter(Machine *m, Circuit *c, map * initialMap, vector *gateOrder, map bSol){ 42 | M = m; 43 | C = c; 44 | initial_map = initialMap; 45 | gate_order = gateOrder; 46 | bsol = bSol; 47 | init_gate_print_maps(); 48 | } 49 | Circuit* map_and_insert_swap_operations(); 50 | Circuit *map_to_trapped_ion(); 51 | void implement_gate_for_trapped_ion(Gate *g, Circuit *I); 52 | 53 | void init_gate_print_maps(); 54 | void map_single_qubit_gate(Gate *g, map current_map); 55 | void map_two_qubit_gate_no_swap(Gate *g, map current_map); 56 | void map_two_qubit_gate_to_swaps(Gate *g, BacktrackSolution *bs, Circuit *I, map *current_map); 57 | void insert_swap_chain(vector &gate_seq, vector *swap_seq, SwapDirection dir); 58 | void insert_two_qubit_op(vector &gate_seq, int ctrl, int targ); 59 | void copy_gate_connections_to_chain(Gate *g, vector &gate_seq, Circuit *I); 60 | void map_swaps_to_cnots(Gate *g, Circuit *I); 61 | void map_cnots_to_cz(Gate *g, Circuit *I); 62 | void implement_hardware_directions_for_cnots(Gate *g, Circuit *I); 63 | void print_code(Circuit *I, string fname); 64 | void print_one_qubit_gate(Gate *g, ofstream &out_file, int is_last_gate); 65 | void print_two_qubit_gate(Gate *g, ofstream &out_file, int is_last_gate); 66 | void print_header(ofstream &out_file); 67 | void print_measure_ops(ofstream &out_file); 68 | void print_footer(ofstream &out_file); 69 | void _external_link(Gate *g, vector gate_list, Circuit *I, int link_direction); 70 | }; 71 | 72 | #endif /* TARGETTER_HPP_ */ 73 | --------------------------------------------------------------------------------