Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Cirq backend #83

Draft
wants to merge 39 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b084b92
cuQuantum バックエンドのひながたを追加
yasuhito Jan 24, 2022
986ca60
Merge branch 'main' into cuquantum-backend
yasuhito Feb 5, 2022
c6b1d9f
.
yasuhito Feb 6, 2022
0cf403d
fix ci
yasuhito Feb 6, 2022
30e19fb
fix
yasuhito Feb 6, 2022
7b2dea5
fix
yasuhito Feb 6, 2022
b810357
fix
yasuhito Feb 6, 2022
46c4bb1
Merge branch 'main' into cuquantum-backend
yasuhito Feb 6, 2022
2a1ef27
fix serviceworker's path
yasuhito Feb 7, 2022
18d3924
data-update-url
yasuhito Feb 7, 2022
f816668
renaming cuQuantum to cirq (refs #77)
yasuhito Feb 12, 2022
dba674b
Merge branch 'main' into cuquantum-backend
yasuhito Feb 12, 2022
bdea060
fix broken html
yasuhito Feb 13, 2022
7c5350d
Cuquantum backend (#84)
nakatamaho Feb 14, 2022
7bb5803
Now cirq backend works very similar to qni.
nakatamaho Apr 4, 2022
cf3d18e
update URLs
nakatamaho Apr 4, 2022
a8ab02f
Cirq backend (#193)
nakatamaho Apr 5, 2022
421f5ce
Added support for bloch sphere peeking hypothetical gate.
nakatamaho Apr 8, 2022
54c5112
update comment
nakatamaho Apr 8, 2022
2f0604f
ignore null steps from the upstream
nakatamaho Apr 8, 2022
fbf403b
* invalid or null steps are now converted into I gate.
nakatamaho Apr 8, 2022
0b6d540
Merge branch 'main' into cirq-backend
yasuhito Apr 8, 2022
98a7095
some code cleanups
nakatamaho Apr 8, 2022
4621a5a
Merge branch 'cirq-backend' of github.com:qniapp/qni into cirq-backend
nakatamaho Apr 8, 2022
bf1fc9d
.
nakatamaho Apr 8, 2022
98f18fa
treat dummy identity gates as the same as Qni's
nakatamaho Apr 10, 2022
196a365
cleanup
nakatamaho Apr 10, 2022
7387f1b
more cleanup
nakatamaho Apr 10, 2022
32590ed
Appropreately place dummy gates for bloch sphere gates
nakatamaho Apr 10, 2022
3a6f1e5
fix for bloch sphere gate
nakatamaho Apr 10, 2022
c988b56
now we migrate to qni.app
nakatamaho Apr 11, 2022
2211ed5
fix for counting the gate indices for |1>
nakatamaho Apr 11, 2022
395b834
fix swap gate
nakatamaho Apr 11, 2022
68ff317
add support for Controlled Z gate
nakatamaho Apr 12, 2022
545d381
add support for controlled CZ gate
nakatamaho Apr 12, 2022
66d1c14
Fix CZ gate when the number of target bits is two.
nakatamaho Apr 13, 2022
a2f7da3
conditional classical gate application support for + and Z gate.
nakatamaho Apr 15, 2022
97d0152
fix bug for counting the number of measrement devices.
nakatamaho Apr 15, 2022
078cef2
Merge branch 'main' into cirq-backend
yasuhito Apr 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ jobs:
POSTGRES_PASSWORD: postgres
- run: lerna bootstrap
- run: yarn build
- name: javascript:build
run: |-
cd apps/www
bundle exec rails javascript:build
- name: css:build
run: |-
cd apps/www
bundle exec rails css:build
- run: yarn test:ci
env:
RAILS_ENV: test
Expand Down
106 changes: 106 additions & 0 deletions Dockerfile_cirq_backend
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# 1. The Qniapp is built as follows:
# $ git clone https://github.com/qniapp/qni.git
# $ cd qni
# $ git fetch origin cirq-backend
# $ git checkout cirq-backend
# $ docker build -f Dockerfile_cirq_backend . -t qni_cirq_backend
# 2. Then run by:
# $ docker run -p 3000:3000 --gpus all --rm -it qni_cirq_backend
# 3. access http://127.0.0.1:3000 in your browser

# Troubleshooting
# If the port 3000 is already used, change 3000 to 4000 (for example)
# $ docker run -p 4000:3000 --gpus all --rm -it qni_cirq_backend
# and access http://127.0.0.1:4000 in your browser

FROM nvidia/cuda:11.5.1-devel-ubuntu20.04

RUN apt update
RUN apt -y upgrade
RUN apt install -y sudo
ENV DEBIAN_FRONTEND=noninteractive
RUN apt install -y tzdata
# set your timezone
ENV TZ Asia/Tokyo
RUN echo "${TZ}" > /etc/timezone \
&& rm /etc/localtime \
&& ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata

RUN apt install -y build-essential
RUN apt install -y git wget time curl libssl-dev zlib1g-dev libpq-dev
RUN apt install -y redis-server
RUN apt install -y ng-common ng-cjk emacs-nox
RUN apt install -y postgresql postgresql-contrib

## cuda
RUN apt -y install cuda-drivers
RUN wget https://developer.download.nvidia.com/compute/cuquantum/redist/cuquantum/linux-x86_64/cuquantum-linux-x86_64-22.03.0.40-archive.tar.xz
RUN tar xvfJ cuquantum-linux-x86_64-22.03.0.40-archive.tar.xz -C /tmp
RUN cd /tmp/cuquantum-linux-x86_64-22.03.0.40-archive ; tar cf - . | (cd /usr/local; tar vxf -)

## node.js
RUN apt install -y nodejs npm && npm install n -g && n stable && apt purge -y nodejs npm

## npm
RUN curl -qL https://www.npmjs.com/install.sh | sh

## yarn
RUN npm install -g yarn

## ruby
RUN wget https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.tar.gz && tar xvfz ruby-2.7.4.tar.gz && cd ruby-2.7.4 && ./configure && make && make install

## python3
RUN apt install -y python3 python3-pip
RUN sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1

ARG DOCKER_UID=1000
ARG DOCKER_USER=docker
ARG DOCKER_PASSWORD=docker
RUN useradd -u $DOCKER_UID -m $DOCKER_USER --shell /bin/bash && echo "$DOCKER_USER:$DOCKER_PASSWORD" | chpasswd && echo "$DOCKER_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

USER ${DOCKER_USER}
RUN echo "\n\
[user]\n\
email = ${GIT_EMAIL}\n\
name = ${GIT_NAME}\n\
" > /home/$DOCKER_USER/.gitconfig

SHELL ["/bin/bash", "-l", "-c"]

# qsim
ENV PATH=/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/$DOCKER_USER/.rbenv/bin:/home/$DOCKER_USER/.local/bin
# for qsimcirq
ENV CUQUANTUM_DIR=/usr/local
RUN cd /home/$DOCKER_USER && pip3 install pybind11 pytest numpy sympy cirq
RUN cd /home/$DOCKER_USER && git clone https://github.com/quantumlib/qsim.git && cd qsim && make # && make run-py-tests # to use gpu qsim must be build locally

RUN cd /home/$DOCKER_USER && echo "cd /home/$DOCKER_USER" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && git clone https://github.com/rbenv/rbenv.git ~/.rbenv
RUN cd /home/$DOCKER_USER && git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
RUN cd /home/$DOCKER_USER && echo "export PATH=$PATH:$HOME/.rbenv/bin" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && echo "export CUQUANTUM_DIR=/usr/local" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && echo "export LANG=C.UTF-8" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && echo "export LC_CTYPE=C.UTF-8" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && echo "export LD_LIBRARY_PATH=${CUQUANTUM_DIR}/lib64:${LD_LIBRARY_PATH}" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && git clone https://github.com/qniapp/qni.git
RUN cd /home/$DOCKER_USER && cd qni && git fetch origin cirq-backend
RUN cd /home/$DOCKER_USER && cd qni && git checkout cirq-backend
RUN cd /home/$DOCKER_USER && cd qni && git log -1

## settings for rails
RUN cd /home/$DOCKER_USER && cd qni/apps/www && bundle config set path 'vendor/cache' && bundle install && yarn install
RUN cd /home/$DOCKER_USER && cd qni && yarn build && cd apps/www && ./bin/rails css:build && ./bin/rails javascript:build

## settings for postgresql
RUN sudo -u postgres service postgresql start && sudo -u postgres psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" && sudo -u postgres createdb -O docker docker
RUN cd /home/$DOCKER_USER && sudo -u postgres service postgresql start && cd qni/apps/www && ./bin/rails db:create && ./bin/rails db:migrate && ./bin/rails db:fixtures:load

RUN cd /home/$DOCKER_USER && echo -e "#!/usr/bin/env bash\n\
export PYTHONPATH=/home/docker/qsim/ \n\
sudo -u postgres service postgresql start \n\
cd /home/${DOCKER_USER} ; source ~/.bashrc ; cd qni/apps/www \n\
./bin/rails s -b 0.0.0.0" > /tmp/startup.sh
RUN chmod 744 /tmp/startup.sh
#ENTRYPOINT ["/bin/sh", "-c", "/tmp/startup.sh"]
105 changes: 105 additions & 0 deletions Dockerfile_cuquantum
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# 1. The Qniapp is built as follows:
# $ git clone https://github.com/qniapp/qni.git
# $ cd qni
# $ docker build -f Dockerfile_cuquantum . -t qni_cuquantum
# 2. Then run by:
# $ docker run -p 3000:3000 --gpus all --rm -it qni_cuquantum
# 3. access http://127.0.0.1:3000 in your browser

# Troubleshooting
# If the port 3000 is already used, change 3000 to 4000 (for example)
# $ docker run -p 4000:3000 --gpus all --rm -it qni_cuquantum
# and access http://127.0.0.1:4000 in your browser

FROM nvidia/cuda:11.5.1-devel-ubuntu20.04

RUN apt update
RUN apt -y upgrade
RUN apt install -y sudo
ENV DEBIAN_FRONTEND=noninteractive
RUN apt install -y tzdata
# set your timezone
ENV TZ Asia/Tokyo
RUN echo "${TZ}" > /etc/timezone \
&& rm /etc/localtime \
&& ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata

RUN apt install -y build-essential
RUN apt install -y git wget time curl libssl-dev zlib1g-dev libpq-dev
RUN apt install -y redis-server
RUN apt install -y ng-common ng-cjk emacs-nox
RUN apt install -y postgresql postgresql-contrib

## cuda
RUN apt -y install cuda-drivers
RUN apt -y install libcutensor1 libcutensor-dev libcutensor-doc
RUN wget https://developer.download.nvidia.com/compute/cuquantum/redist/cuquantum/linux-x86_64/cuquantum-linux-x86_64-22.03.0.40-archive.tar.xz
RUN tar xvfJ cuquantum-linux-x86_64-22.03.0.40-archive.tar.xz -C /tmp
RUN cd /tmp/cuquantum-linux-x86_64-22.03.0.40-archive ; tar cf - . | (cd /usr/local; tar vxf -)

## node.js
RUN apt install -y nodejs npm && npm install n -g && n stable && apt purge -y nodejs npm

## npm
RUN curl -qL https://www.npmjs.com/install.sh | sh

## yarn
RUN npm install -g yarn

## ruby
RUN wget https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.tar.gz && tar xvfz ruby-2.7.4.tar.gz && cd ruby-2.7.4 && ./configure && make && make install

## python3
RUN apt install -y python3 python3-pip
RUN sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1

ARG DOCKER_UID=1000
ARG DOCKER_USER=docker
ARG DOCKER_PASSWORD=docker
RUN useradd -u $DOCKER_UID -m $DOCKER_USER --shell /bin/bash && echo "$DOCKER_USER:$DOCKER_PASSWORD" | chpasswd && echo "$DOCKER_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

USER ${DOCKER_USER}
RUN echo "\n\
[user]\n\
email = ${GIT_EMAIL}\n\
name = ${GIT_NAME}\n\
" > /home/$DOCKER_USER/.gitconfig

SHELL ["/bin/bash", "-l", "-c"]

# cuQuantum
ENV CUQUANTUM_ROOT=/usr/local
ENV CUSTATEVEC_ROOT=/usr/local
ENV CUTENSOR_ROOT=/usr
ENV CUDA_PATH=/usr/local/cuda
ENV CUQUANTUM_IGNORE_SOLVER=1
RUN cd /home/$DOCKER_USER && pip3 install cupy-cuda115 numpy scipy cython
RUN cd /home/$DOCKER_USER && git clone https://github.com/NVIDIA/cuQuantum.git && cd cuQuantum/python && pip3 install -v .

# Qni
RUN cd /home/$DOCKER_USER && echo "cd /home/$DOCKER_USER" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && git clone https://github.com/rbenv/rbenv.git ~/.rbenv
RUN cd /home/$DOCKER_USER && git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
RUN cd /home/$DOCKER_USER && echo "export PATH=$PATH:$HOME/.rbenv/bin" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && echo "export CUQUANTUM_ROOT=/usr/local" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && echo "export LD_LIBRARY_PATH=${CUQUANTUM_ROOT}/lib64:${LD_LIBRARY_PATH}" >> ~/.bashrc
RUN cd /home/$DOCKER_USER && git clone https://github.com/nakatamaho/qni.git
RUN cd /home/$DOCKER_USER && cd qni && git fetch origin cuquantum-backend
RUN cd /home/$DOCKER_USER && cd qni && git checkout cuquantum-backend

## settings for rails
RUN cd /home/$DOCKER_USER && cd qni/apps/www && bundle config set path 'vendor/cache' && bundle install && yarn install
RUN cd /home/$DOCKER_USER && cd qni && yarn build && cd apps/www && ./bin/rails css:build && ./bin/rails javascript:build

## settings for postgresql
RUN sudo -u postgres service postgresql start && sudo -u postgres psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" && sudo -u postgres createdb -O docker docker
RUN cd /home/$DOCKER_USER && sudo -u postgres service postgresql start && cd qni/apps/www && ./bin/rails db:create && ./bin/rails db:migrate && ./bin/rails db:fixtures:load

RUN cd /home/$DOCKER_USER && echo -e "#!/usr/bin/env bash\n\
export PYTHONIOENCODING=utf-8 \n\
sudo -u postgres service postgresql start \n\
cd /home/${DOCKER_USER} ; source ~/.bashrc ; cd qni/apps/www \n\
./bin/rails s -b 0.0.0.0" > /tmp/startup.sh
RUN chmod 744 /tmp/startup.sh
ENTRYPOINT ["/bin/sh", "-c", "/tmp/startup.sh"]
1 change: 1 addition & 0 deletions apps/www/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ gem 'better_html'
gem 'bootsnap', '>= 1.4.2', require: false
gem 'grover'
gem 'serviceworker-rails'
gem 'pycall'

group :development, :test do
gem 'byebug', platforms: %i[mri mingw x64_mingw]
Expand Down
2 changes: 2 additions & 0 deletions apps/www/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ GEM
public_suffix (4.0.6)
puma (5.6.4)
nio4r (~> 2.0)
pycall (1.4.1)
racc (1.6.0)
rack (2.2.3)
rack-mini-profiler (2.3.3)
Expand Down Expand Up @@ -297,6 +298,7 @@ DEPENDENCIES
listen (>= 3.0.5, < 3.2)
pg
puma (~> 5.6)
pycall
rack-mini-profiler
rails (~> 6.1)
rbtrace
Expand Down
75 changes: 63 additions & 12 deletions apps/www/app/assets/javascripts/serviceworker.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,77 @@ self.addEventListener(
const steps = e.data.steps
const targets = e.data.targets
const simulator = new Simulator('0'.repeat(qubitCount))
const backend = e.data.backend

Util.notNull(qubitCount)
Util.notNull(stepIndex)
Util.notNull(steps)
Util.notNull(targets)

steps.forEach((operations, i) => {
simulator.runStep(operations)

self.postMessage({
type: 'step',
step: i,
amplitudes: i === stepIndex ? simulator.amplitudes(targets) : [],
blochVectors: simulator.blochVectors,
measuredBits: simulator.measuredBits,
flags: simulator.flags
})
})
if (backend) {
const json = e.data.json
Util.notNull(json)

runBackend(json, qubitCount, stepIndex, steps, targets, backend)
} else {
runQniSimulator(qubitCount, stepIndex, steps, targets)
}

self.postMessage({type: 'finish'})
},
false
)

function runQniSimulator(qubitCount, stepIndex, steps, targets) {
const simulator = new Simulator('0'.repeat(qubitCount))

steps.forEach((operations, i) => {
simulator.runStep(operations)

self.postMessage({
type: 'step',
step: i,
amplitudes: i === stepIndex ? simulator.amplitudes(targets) : {},
blochVectors: simulator.blochVectors,
measuredBits: simulator.measuredBits,
flags: simulator.flags
})
})
}

function runBackend(json, qubitCount, stepIndex, steps, targets, backend) {
const params = new URLSearchParams({
id: json,
qubitCount: qubitCount,
stepIndex: stepIndex,
steps: JSON.stringify(steps),
targets: targets,
backend: backend
})

fetch(`/backend.json?${params}`, {
method: 'GET'
})
.then(response => {
if (!response.ok) {
throw new Error("Failed to connect to Qni's backend endpoint.")
}
return response.json()
})
.then(response => {
for (let i = 0; i < response.length; i++) {
const stepResult = response[i]
self.postMessage({
type: 'step',
step: i,
amplitudes: stepResult['amplitudes'],
blochVectors: stepResult['blochVectors'],
measuredBits: stepResult['measuredBits'],
flags: {}
})
}
})
.catch(error => {
console.error(error)
})
}
20 changes: 20 additions & 0 deletions apps/www/app/controllers/backend_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'cirq'

class BackendController < ApplicationController
# rubocop:disable Metrics/AbcSize
def show
backend = params[:backend]
circuit_id = params[:id]
qubit_count = params[:qubitCount].to_i
step_index = params[:stepIndex].to_i
steps = params[:steps] ? JSON.parse(params[:steps]) : []
targets = params[:targets].split(',').map(&:to_i) if params[:targets]

raise "Unsupported backend: #{backend}" unless backend == 'cirq'

@step_results =
Cirq.new(circuit_id: circuit_id, qubit_count: qubit_count, step_index: step_index, steps: steps, targets: targets)
.run
end
# rubocop:enable Metrics/AbcSize
end
3 changes: 3 additions & 0 deletions apps/www/app/controllers/cirq_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class CirqController < ApplicationController
def show; end
end
10 changes: 2 additions & 8 deletions apps/www/app/models/concerns/routing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@
module Routing
extend ActiveSupport::Concern

included do
include Rails.application.routes.url_helpers
end
included { include Rails.application.routes.url_helpers }

def default_url_options
if Rails.env.production?
{ host: 'qniapp.net' }
else
{ host: 'localhost', port: 3000 }
end
Rails.env.production? ? { host: 'qniapp.net' } : { host: 'localhost', port: 3000 }
end
end
1 change: 1 addition & 0 deletions apps/www/app/views/backend/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @step_results
Loading