commit
2088d38610
@ -0,0 +1,25 @@
|
||||
set(projectq_CXXFLAGS "-fopenmp -O2 -ffast-mast -march=native -DINTRIN")
|
||||
set(projectq_CFLAGS "-fopenmp -O2 -ffast-mast -march=native -DINTRIN")
|
||||
|
||||
if(ENABLE_GITEE)
|
||||
set(REQ_URL "https://gitee.com/mirrors/ProjectQ/repository/archive/v0.5.1.tar.gz")
|
||||
set(MD5 "d874e93e56d3375f1c54c7dd1b731054")
|
||||
else()
|
||||
set(REQ_URL "https://github.com/ProjectQ-Framework/ProjectQ/archive/v0.5.1.tar.gz ")
|
||||
set(MD5 "13430199c253284df8b3d840f11d3560")
|
||||
endif()
|
||||
|
||||
if(ENABLE_CPU AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux"
|
||||
AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64")
|
||||
message("Include projectq simulator")
|
||||
mindspore_add_pkg(projectq
|
||||
VER 0.5.1
|
||||
HEAD_ONLY ./
|
||||
URL ${REQ_URL}
|
||||
MD5 ${MD5}
|
||||
PATCHES ${CMAKE_SOURCE_DIR}/third_party/patch/projectq/projectq.patch001
|
||||
)
|
||||
include_directories(${projectq_INC})
|
||||
else()
|
||||
message("Quantum simulation only support x86_64 linux platform.")
|
||||
endif()
|
@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "backend/kernel_compiler/cpu/quantum/pqc_cpu_kernel.h"
|
||||
|
||||
#include <omp.h>
|
||||
#include <utility>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include "utils/ms_utils.h"
|
||||
#include "runtime/device/cpu/cpu_device_address.h"
|
||||
#include "common/thread_pool.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace kernel {
|
||||
namespace {
|
||||
struct ComputeParam {
|
||||
float *encoder_data_cp{nullptr};
|
||||
float *ansatz_data_cp{nullptr};
|
||||
float *output_cp{nullptr};
|
||||
float *gradient_encoder_cp{nullptr};
|
||||
float *gradient_ansatz_cp{nullptr};
|
||||
mindquantum::BasicCircuit *circ_cp;
|
||||
mindquantum::BasicCircuit *herm_circ_cp;
|
||||
mindquantum::transformer::Hamiltonians *hams_cp;
|
||||
mindquantum::transformer::NamesType *encoder_params_names_cp;
|
||||
mindquantum::transformer::NamesType *ansatz_params_names_cp;
|
||||
std::vector<std::vector<std::shared_ptr<mindquantum::PQCSimulator>>> *tmp_sims_cp;
|
||||
bool dummy_circuit_cp{false};
|
||||
size_t result_len_cp{0};
|
||||
size_t encoder_g_len_cp{0};
|
||||
size_t ansatz_g_len_cp{0};
|
||||
};
|
||||
|
||||
void ComputerForwardBackward(const std::shared_ptr<ComputeParam> &input_params, size_t start, size_t end, size_t id) {
|
||||
MS_EXCEPTION_IF_NULL(input_params);
|
||||
MS_EXCEPTION_IF_NULL(input_params->encoder_data_cp);
|
||||
MS_EXCEPTION_IF_NULL(input_params->ansatz_data_cp);
|
||||
MS_EXCEPTION_IF_NULL(input_params->output_cp);
|
||||
MS_EXCEPTION_IF_NULL(input_params->gradient_encoder_cp);
|
||||
MS_EXCEPTION_IF_NULL(input_params->gradient_ansatz_cp);
|
||||
auto encoder_data = input_params->encoder_data_cp;
|
||||
auto ansatz_data = input_params->ansatz_data_cp;
|
||||
auto output = input_params->output_cp;
|
||||
auto gradient_encoder = input_params->gradient_encoder_cp;
|
||||
auto gradient_ansatz = input_params->gradient_ansatz_cp;
|
||||
auto circ = input_params->circ_cp;
|
||||
auto herm_circ = input_params->herm_circ_cp;
|
||||
auto hams = input_params->hams_cp;
|
||||
auto encoder_params_names = input_params->encoder_params_names_cp;
|
||||
auto ansatz_params_names = input_params->ansatz_params_names_cp;
|
||||
auto tmp_sims = input_params->tmp_sims_cp;
|
||||
auto dummy_circuit = input_params->dummy_circuit_cp;
|
||||
auto result_len = input_params->result_len_cp;
|
||||
auto encoder_g_len = input_params->encoder_g_len_cp;
|
||||
auto ansatz_g_len = input_params->ansatz_g_len_cp;
|
||||
MS_EXCEPTION_IF_NULL(hams);
|
||||
MS_EXCEPTION_IF_NULL(encoder_params_names);
|
||||
MS_EXCEPTION_IF_NULL(ansatz_params_names);
|
||||
MS_EXCEPTION_IF_NULL(tmp_sims);
|
||||
|
||||
if (end * hams->size() > result_len || end * encoder_params_names->size() * hams->size() > encoder_g_len ||
|
||||
end * ansatz_params_names->size() * hams->size() > ansatz_g_len) {
|
||||
MS_LOG(EXCEPTION) << "pqc error input size!";
|
||||
}
|
||||
mindquantum::ParameterResolver pr;
|
||||
for (size_t i = 0; i < ansatz_params_names->size(); i++) {
|
||||
pr.SetData(ansatz_params_names->at(i), ansatz_data[i]);
|
||||
}
|
||||
for (size_t n = start; n < end; ++n) {
|
||||
for (size_t i = 0; i < encoder_params_names->size(); i++) {
|
||||
pr.SetData(encoder_params_names->at(i), encoder_data[n * encoder_params_names->size() + i]);
|
||||
}
|
||||
auto sim = tmp_sims->at(id)[3];
|
||||
sim->SetZeroState();
|
||||
sim->Evolution(*circ, pr);
|
||||
auto calc_gradient_param = std::make_shared<mindquantum::CalcGradientParam>();
|
||||
calc_gradient_param->circuit_cp = circ;
|
||||
calc_gradient_param->circuit_hermitian_cp = herm_circ;
|
||||
calc_gradient_param->hamiltonians_cp = hams;
|
||||
calc_gradient_param->paras_cp = ≺
|
||||
calc_gradient_param->encoder_params_names_cp = encoder_params_names;
|
||||
calc_gradient_param->ansatz_params_names_cp = ansatz_params_names;
|
||||
calc_gradient_param->dummy_circuit_cp = dummy_circuit;
|
||||
|
||||
auto e0_grad1_grad_2 =
|
||||
sim->CalcGradient(calc_gradient_param, *tmp_sims->at(id)[0], *tmp_sims->at(id)[1], *tmp_sims->at(id)[2]);
|
||||
auto energy = e0_grad1_grad_2[0];
|
||||
auto grad_encoder = e0_grad1_grad_2[1];
|
||||
auto grad_ansatz = e0_grad1_grad_2[2];
|
||||
if (energy.size() != hams->size() || grad_encoder.size() != encoder_params_names->size() * hams->size() ||
|
||||
grad_ansatz.size() != ansatz_params_names->size() * hams->size()) {
|
||||
MS_LOG(EXCEPTION) << "pqc error evolution or batch size!";
|
||||
}
|
||||
for (size_t poi = 0; poi < hams->size(); poi++) {
|
||||
output[n * hams->size() + poi] = energy[poi];
|
||||
}
|
||||
for (size_t poi = 0; poi < encoder_params_names->size() * hams->size(); poi++) {
|
||||
gradient_encoder[n * hams->size() * encoder_params_names->size() + poi] = grad_encoder[poi];
|
||||
}
|
||||
for (size_t poi = 0; poi < ansatz_params_names->size() * hams->size(); poi++) {
|
||||
gradient_ansatz[n * hams->size() * ansatz_params_names->size() + poi] = grad_ansatz[poi];
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void PQCCPUKernel::InitPQCStructure(const CNodePtr &kernel_node) {
|
||||
n_threads_user_ = AnfAlgo::GetNodeAttr<int64_t>(kernel_node, mindquantum::kNThreads);
|
||||
n_qubits_ = AnfAlgo::GetNodeAttr<int64_t>(kernel_node, mindquantum::kNQubits);
|
||||
encoder_params_names_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::NamesType>(kernel_node, mindquantum::kEncoderParamsNames);
|
||||
ansatz_params_names_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::NamesType>(kernel_node, mindquantum::kAnsatzParamsNames);
|
||||
gate_names_ = AnfAlgo::GetNodeAttr<mindquantum::transformer::NamesType>(kernel_node, mindquantum::kGateNames);
|
||||
gate_matrix_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::ComplexMatrixsType>(kernel_node, mindquantum::kGateMatrix);
|
||||
gate_obj_qubits_ = AnfAlgo::GetNodeAttr<mindquantum::transformer::Indexess>(kernel_node, mindquantum::kGateObjQubits);
|
||||
gate_ctrl_qubits_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::Indexess>(kernel_node, mindquantum::kGateCtrlQubits);
|
||||
gate_params_names_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::ParasNameType>(kernel_node, mindquantum::kGateParamsNames);
|
||||
gate_coeff_ = AnfAlgo::GetNodeAttr<mindquantum::transformer::CoeffsType>(kernel_node, mindquantum::kGateCoeff);
|
||||
gate_requires_grad_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::RequiresType>(kernel_node, mindquantum::kGateRequiresGrad);
|
||||
hams_pauli_coeff_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::PaulisCoeffsType>(kernel_node, mindquantum::kHamsPauliCoeff);
|
||||
hams_pauli_word_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::PaulisWordsType>(kernel_node, mindquantum::kHamsPauliWord);
|
||||
hams_pauli_qubit_ =
|
||||
AnfAlgo::GetNodeAttr<mindquantum::transformer::PaulisQubitsType>(kernel_node, mindquantum::kHamsPauliQubit);
|
||||
}
|
||||
|
||||
void PQCCPUKernel::InitKernel(const CNodePtr &kernel_node) {
|
||||
MS_EXCEPTION_IF_NULL(kernel_node);
|
||||
std::vector<size_t> encoder_shape = AnfAlgo::GetInputDeviceShape(kernel_node, 0);
|
||||
std::vector<size_t> ansatz_shape = AnfAlgo::GetInputDeviceShape(kernel_node, 1);
|
||||
std::vector<size_t> result_shape = AnfAlgo::GetOutputDeviceShape(kernel_node, 0);
|
||||
std::vector<size_t> encoder_g_shape = AnfAlgo::GetOutputDeviceShape(kernel_node, 1);
|
||||
std::vector<size_t> ansatz_g_shape = AnfAlgo::GetOutputDeviceShape(kernel_node, 2);
|
||||
|
||||
if (encoder_shape.size() != 2 || ansatz_shape.size() != 1 || result_shape.size() != 2 ||
|
||||
encoder_g_shape.size() != 3 || ansatz_g_shape.size() != 3) {
|
||||
MS_LOG(EXCEPTION) << "pqc invalid input size";
|
||||
}
|
||||
result_len_ = result_shape[0] * result_shape[1];
|
||||
encoder_g_len_ = encoder_g_shape[0] * encoder_g_shape[1] * encoder_g_shape[2];
|
||||
ansatz_g_len_ = ansatz_g_shape[0] * ansatz_g_shape[1] * ansatz_g_shape[2];
|
||||
|
||||
n_samples_ = static_cast<unsigned>(encoder_shape[0]);
|
||||
InitPQCStructure(kernel_node);
|
||||
|
||||
dummy_circuit_ = !std::any_of(gate_requires_grad_.begin(), gate_requires_grad_.end(),
|
||||
[](const mindquantum::transformer::RequireType &rr) {
|
||||
return std::any_of(rr.begin(), rr.end(), [](const bool &r) { return r; });
|
||||
});
|
||||
|
||||
auto circs = mindquantum::transformer::CircuitTransfor(gate_names_, gate_matrix_, gate_obj_qubits_, gate_ctrl_qubits_,
|
||||
gate_params_names_, gate_coeff_, gate_requires_grad_);
|
||||
circ_ = circs[0];
|
||||
herm_circ_ = circs[1];
|
||||
|
||||
hams_ = mindquantum::transformer::HamiltoniansTransfor(hams_pauli_coeff_, hams_pauli_word_, hams_pauli_qubit_);
|
||||
|
||||
n_threads_user_ = common::ThreadPool::GetInstance().GetSyncRunThreadNum();
|
||||
if (n_samples_ < n_threads_user_) {
|
||||
n_threads_user_ = n_samples_;
|
||||
}
|
||||
for (size_t i = 0; i < n_threads_user_; i++) {
|
||||
tmp_sims_.push_back({});
|
||||
for (size_t j = 0; j < 4; j++) {
|
||||
auto tmp = std::make_shared<mindquantum::PQCSimulator>(1, n_qubits_);
|
||||
tmp_sims_.back().push_back(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PQCCPUKernel::Launch(const std::vector<kernel::AddressPtr> &inputs,
|
||||
const std::vector<kernel::AddressPtr> & /*workspace*/,
|
||||
const std::vector<kernel::AddressPtr> &outputs) {
|
||||
if (inputs.size() != 2 || outputs.size() != 3) {
|
||||
MS_LOG(EXCEPTION) << "pqc error input output size!";
|
||||
}
|
||||
auto encoder_data = reinterpret_cast<float *>(inputs[0]->addr);
|
||||
auto ansatz_data = reinterpret_cast<float *>(inputs[1]->addr);
|
||||
auto output = reinterpret_cast<float *>(outputs[0]->addr);
|
||||
auto gradient_encoder = reinterpret_cast<float *>(outputs[1]->addr);
|
||||
auto gradient_ansatz = reinterpret_cast<float *>(outputs[2]->addr);
|
||||
MS_EXCEPTION_IF_NULL(encoder_data);
|
||||
MS_EXCEPTION_IF_NULL(ansatz_data);
|
||||
MS_EXCEPTION_IF_NULL(output);
|
||||
MS_EXCEPTION_IF_NULL(gradient_encoder);
|
||||
MS_EXCEPTION_IF_NULL(gradient_ansatz);
|
||||
|
||||
std::vector<common::Task> tasks;
|
||||
std::vector<std::shared_ptr<ComputeParam>> thread_params;
|
||||
tasks.reserve(n_threads_user_);
|
||||
|
||||
size_t end = 0;
|
||||
size_t offset = n_samples_ / n_threads_user_;
|
||||
size_t left = n_samples_ % n_threads_user_;
|
||||
for (size_t i = 0; i < n_threads_user_; ++i) {
|
||||
auto params = std::make_shared<ComputeParam>();
|
||||
params->encoder_data_cp = encoder_data;
|
||||
params->ansatz_data_cp = ansatz_data;
|
||||
params->output_cp = output;
|
||||
params->gradient_encoder_cp = gradient_encoder;
|
||||
params->gradient_ansatz_cp = gradient_ansatz;
|
||||
params->circ_cp = &circ_;
|
||||
params->herm_circ_cp = &herm_circ_;
|
||||
params->hams_cp = &hams_;
|
||||
params->encoder_params_names_cp = &encoder_params_names_;
|
||||
params->ansatz_params_names_cp = &ansatz_params_names_;
|
||||
params->tmp_sims_cp = &tmp_sims_;
|
||||
params->dummy_circuit_cp = dummy_circuit_;
|
||||
params->result_len_cp = result_len_;
|
||||
params->encoder_g_len_cp = encoder_g_len_;
|
||||
params->ansatz_g_len_cp = ansatz_g_len_;
|
||||
size_t start = end;
|
||||
end = start + offset;
|
||||
if (i < left) {
|
||||
end += 1;
|
||||
}
|
||||
auto task = [¶ms, start, end, i]() {
|
||||
ComputerForwardBackward(params, start, end, i);
|
||||
return common::SUCCESS;
|
||||
};
|
||||
tasks.emplace_back(task);
|
||||
thread_params.emplace_back(params);
|
||||
}
|
||||
common::ThreadPool::GetInstance().SyncRun(tasks);
|
||||
return true;
|
||||
}
|
||||
} // namespace kernel
|
||||
} // namespace mindspore
|
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_PQC_CPU_KERNEL_H_
|
||||
#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_PQC_CPU_KERNEL_H_
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "backend/kernel_compiler/cpu/cpu_kernel.h"
|
||||
#include "backend/kernel_compiler/cpu/cpu_kernel_factory.h"
|
||||
#include "mindquantum/pqc_simulator.h"
|
||||
#include "mindquantum/transformer.h"
|
||||
#include "mindquantum/circuit.h"
|
||||
#include "mindquantum/parameter_resolver.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace kernel {
|
||||
class PQCCPUKernel : public CPUKernel {
|
||||
public:
|
||||
PQCCPUKernel() = default;
|
||||
~PQCCPUKernel() override = default;
|
||||
|
||||
void InitKernel(const CNodePtr &kernel_node) override;
|
||||
|
||||
bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
|
||||
const std::vector<AddressPtr> &outputs) override;
|
||||
|
||||
void InitPQCStructure(const CNodePtr &kernel_node);
|
||||
|
||||
private:
|
||||
size_t n_samples_;
|
||||
size_t n_threads_user_;
|
||||
bool dummy_circuit_;
|
||||
size_t result_len_;
|
||||
size_t encoder_g_len_;
|
||||
size_t ansatz_g_len_;
|
||||
|
||||
int64_t n_qubits_;
|
||||
mindquantum::BasicCircuit circ_;
|
||||
mindquantum::BasicCircuit herm_circ_;
|
||||
mindquantum::transformer::Hamiltonians hams_;
|
||||
std::vector<std::vector<std::shared_ptr<mindquantum::PQCSimulator>>> tmp_sims_;
|
||||
|
||||
// parameters
|
||||
mindquantum::transformer::NamesType encoder_params_names_;
|
||||
mindquantum::transformer::NamesType ansatz_params_names_;
|
||||
|
||||
// quantum circuit
|
||||
mindquantum::transformer::NamesType gate_names_;
|
||||
mindquantum::transformer::ComplexMatrixsType gate_matrix_;
|
||||
mindquantum::transformer::Indexess gate_obj_qubits_;
|
||||
mindquantum::transformer::Indexess gate_ctrl_qubits_;
|
||||
mindquantum::transformer::ParasNameType gate_params_names_;
|
||||
mindquantum::transformer::CoeffsType gate_coeff_;
|
||||
mindquantum::transformer::RequiresType gate_requires_grad_;
|
||||
|
||||
// hamiltonian
|
||||
mindquantum::transformer::PaulisCoeffsType hams_pauli_coeff_;
|
||||
mindquantum::transformer::PaulisWordsType hams_pauli_word_;
|
||||
mindquantum::transformer::PaulisQubitsType hams_pauli_qubit_;
|
||||
};
|
||||
|
||||
MS_REG_CPU_KERNEL(PQC,
|
||||
KernelAttr()
|
||||
.AddInputAttr(kNumberTypeFloat32)
|
||||
.AddInputAttr(kNumberTypeFloat32)
|
||||
.AddOutputAttr(kNumberTypeFloat32)
|
||||
.AddOutputAttr(kNumberTypeFloat32)
|
||||
.AddOutputAttr(kNumberTypeFloat32),
|
||||
PQCCPUKernel);
|
||||
} // namespace kernel
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_PQC_CPU_KERNEL_H_
|
@ -0,0 +1,10 @@
|
||||
if(ENABLE_CPU AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux"
|
||||
AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64")
|
||||
message("compiled mindquantum")
|
||||
file(GLOB_RECURSE _MINDQUANTUM_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cc")
|
||||
set_property(SOURCE ${_MINDQUANTUM_SRC_LIST} PROPERTY COMPILE_DEFINITIONS
|
||||
SUBMODULE_ID=mindspore::SubModuleId::SM_MINDQUANTUM)
|
||||
add_library(_mindspore_mindquantum_obj OBJECT ${_MINDQUANTUM_SRC_LIST})
|
||||
target_compile_options(_mindspore_mindquantum_obj PRIVATE -fopenmp -march=native -ffast-math)
|
||||
target_compile_definitions(_mindspore_mindquantum_obj PRIVATE INTRIN)
|
||||
endif()
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mindquantum/circuit.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
BasicCircuit::BasicCircuit() : gate_blocks_({}) {}
|
||||
|
||||
void BasicCircuit::AppendBlock() { gate_blocks_.push_back({}); }
|
||||
|
||||
void BasicCircuit::AppendNoneParameterGate(const std::string &name, Matrix m, Indexes obj_qubits, Indexes ctrl_qubits) {
|
||||
auto npg = std::make_shared<NoneParameterGate>(name, m, obj_qubits, ctrl_qubits);
|
||||
gate_blocks_.back().push_back(npg);
|
||||
}
|
||||
|
||||
void BasicCircuit::AppendParameterGate(const std::string &name, Indexes obj_qubits, Indexes ctrl_qubits,
|
||||
const ParameterResolver ¶s) {
|
||||
if (name == "RX") {
|
||||
auto pg_rx = std::make_shared<RXGate>(obj_qubits, ctrl_qubits, paras);
|
||||
gate_blocks_.back().push_back(pg_rx);
|
||||
} else if (name == "RY") {
|
||||
auto pg_ry = std::make_shared<RYGate>(obj_qubits, ctrl_qubits, paras);
|
||||
gate_blocks_.back().push_back(pg_ry);
|
||||
} else if (name == "RZ") {
|
||||
auto pg_rz = std::make_shared<RZGate>(obj_qubits, ctrl_qubits, paras);
|
||||
gate_blocks_.back().push_back(pg_rz);
|
||||
} else if (name == "XX") {
|
||||
auto pg_xx = std::make_shared<XXGate>(obj_qubits, ctrl_qubits, paras);
|
||||
gate_blocks_.back().push_back(pg_xx);
|
||||
} else if (name == "YY") {
|
||||
auto pg_yy = std::make_shared<YYGate>(obj_qubits, ctrl_qubits, paras);
|
||||
gate_blocks_.back().push_back(pg_yy);
|
||||
} else if (name == "ZZ") {
|
||||
auto pg_zz = std::make_shared<ZZGate>(obj_qubits, ctrl_qubits, paras);
|
||||
gate_blocks_.back().push_back(pg_zz);
|
||||
} else if (name == "PS") {
|
||||
auto pg_ps = std::make_shared<PhaseShiftGate>(obj_qubits, ctrl_qubits, paras);
|
||||
gate_blocks_.back().push_back(pg_ps);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
const GateBlocks &BasicCircuit::GetGateBlocks() const { return gate_blocks_; }
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_CCIRCUIT_H_
|
||||
#define MINDQUANTUM_ENGINE_CCIRCUIT_H_
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "mindquantum/gates/non_parameter_gate.h"
|
||||
#include "mindquantum/gates/gates.h"
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
using GateBlock = std::vector<std::shared_ptr<BasicGate>>;
|
||||
using GateBlocks = std::vector<GateBlock>;
|
||||
|
||||
class BasicCircuit {
|
||||
private:
|
||||
GateBlocks gate_blocks_;
|
||||
|
||||
public:
|
||||
BasicCircuit();
|
||||
void AppendBlock();
|
||||
void AppendNoneParameterGate(const std::string &, Matrix, Indexes, Indexes);
|
||||
void AppendParameterGate(const std::string &, Indexes, Indexes, const ParameterResolver &);
|
||||
const GateBlocks &GetGateBlocks() const;
|
||||
};
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_CCIRCUIT_H_
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mindquantum/gates/basic_gates.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
BasicGate::BasicGate(const std::string &name, bool is_parameter, const Indexes &obj_qubits, const Indexes &ctrl_qubits,
|
||||
const ParameterResolver ¶s)
|
||||
: name_(name), is_parameter_(is_parameter), obj_qubits_(obj_qubits), ctrl_qubits_(ctrl_qubits), paras_(paras) {}
|
||||
|
||||
Matrix BasicGate::GetMatrix(const ParameterResolver ¶s_out) {
|
||||
Matrix gate_matrix_tmp;
|
||||
return gate_matrix_tmp;
|
||||
}
|
||||
|
||||
Matrix BasicGate::GetDiffMatrix(const ParameterResolver ¶s_out) {
|
||||
Matrix gate_matrix_tmp;
|
||||
return gate_matrix_tmp;
|
||||
}
|
||||
|
||||
Matrix &BasicGate::GetBaseMatrix() { return gate_matrix_base_; }
|
||||
|
||||
const ParameterResolver &BasicGate::GetParameterResolver() const { return paras_; }
|
||||
|
||||
bool BasicGate::IsParameterGate() { return is_parameter_; }
|
||||
|
||||
Indexes BasicGate::GetObjQubits() { return obj_qubits_; }
|
||||
|
||||
Indexes BasicGate::GetCtrlQubits() { return ctrl_qubits_; }
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_BASIC_GATES_H_
|
||||
#define MINDQUANTUM_ENGINE_BASIC_GATES_H_
|
||||
#include <string>
|
||||
#include "mindquantum/parameter_resolver.h"
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
class BasicGate {
|
||||
private:
|
||||
std::string name_;
|
||||
bool is_parameter_;
|
||||
Matrix gate_matrix_base_;
|
||||
Indexes obj_qubits_;
|
||||
Indexes ctrl_qubits_;
|
||||
ParameterResolver paras_;
|
||||
|
||||
public:
|
||||
BasicGate();
|
||||
BasicGate(const std::string &, bool, const Indexes &, const Indexes &,
|
||||
const ParameterResolver ¶s = ParameterResolver());
|
||||
virtual Matrix GetMatrix(const ParameterResolver &);
|
||||
virtual Matrix GetDiffMatrix(const ParameterResolver &);
|
||||
virtual Matrix &GetBaseMatrix();
|
||||
const ParameterResolver &GetParameterResolver() const;
|
||||
bool IsParameterGate();
|
||||
Indexes GetObjQubits();
|
||||
Indexes GetCtrlQubits();
|
||||
};
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_BASIC_GATES_H_
|
@ -0,0 +1,154 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mindquantum/gates/gates.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
RXGate::RXGate(const Indexes &obj_qubits, const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: IntrinsicOneParaGate("RX", obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
RXGate::RXGate() : IntrinsicOneParaGate("RX", {}, {}, {}) {}
|
||||
|
||||
Matrix RXGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
Matrix result = {{{cos(theta / 2), 0}, {0, -sin(theta / 2)}}, {{0, -sin(theta / 2)}, {cos(theta / 2), 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix RXGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
Matrix result = {{{-sin(theta / 2) / 2, 0}, {0, -cos(theta / 2) / 2}},
|
||||
{{0, -cos(theta / 2) / 2}, {-sin(theta / 2) / 2, 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
RYGate::RYGate(const Indexes &obj_qubits, const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: IntrinsicOneParaGate("RY", obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
Matrix RYGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
Matrix result = {{{cos(theta / 2), 0}, {-sin(theta / 2), 0}}, {{sin(theta / 2), 0}, {cos(theta / 2), 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix RYGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
Matrix result = {{{-sin(theta / 2) / 2, 0}, {-cos(theta / 2) / 2, 0}},
|
||||
{{cos(theta / 2) / 2, 0}, {-sin(theta / 2) / 2, 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
RZGate::RZGate(const Indexes &obj_qubits, const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: IntrinsicOneParaGate("RZ", obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
Matrix RZGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
Matrix result = {{{cos(theta / 2), -sin(theta / 2)}, {0, 0}}, {{0, 0}, {cos(theta / 2), sin(theta / 2)}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix RZGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
Matrix result = {{{-sin(theta / 2) / 2, -cos(theta / 2) / 2}, {0, 0}},
|
||||
{{0, 0}, {-sin(theta / 2) / 2, cos(theta / 2) / 2}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
PhaseShiftGate::PhaseShiftGate(const Indexes &obj_qubits, const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: IntrinsicOneParaGate("PS", obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
Matrix PhaseShiftGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
Matrix result = {{{1, 0}, {0, 0}}, {{0, 0}, {cos(theta), sin(theta)}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix PhaseShiftGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
Matrix result = {{{0, 0}, {0, 0}}, {{0, 0}, {-sin(theta), cos(theta)}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
XXGate::XXGate(const Indexes &obj_qubits, const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: IntrinsicOneParaGate("XX", obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
Matrix XXGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
double c = cos(theta);
|
||||
double s = sin(theta);
|
||||
|
||||
Matrix result = {{{c, 0}, {0, 0}, {0, 0}, {0, -s}},
|
||||
{{0, 0}, {c, 0}, {0, -s}, {0, 0}},
|
||||
{{0, 0}, {0, -s}, {c, 0}, {0, 0}},
|
||||
{{0, -s}, {0, 0}, {0, 0}, {c, 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix XXGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
double c = cos(theta);
|
||||
double s = sin(theta);
|
||||
|
||||
Matrix result = {{{-s, 0}, {0, 0}, {0, 0}, {0, -c}},
|
||||
{{0, 0}, {-s, 0}, {0, -c}, {0, 0}},
|
||||
{{0, 0}, {0, -c}, {-s, 0}, {0, 0}},
|
||||
{{0, -c}, {0, 0}, {0, 0}, {-s, 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
YYGate::YYGate(const Indexes &obj_qubits, const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: IntrinsicOneParaGate("YY", obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
Matrix YYGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
double c = cos(theta);
|
||||
double s = sin(theta);
|
||||
|
||||
Matrix result = {{{c, 0}, {0, 0}, {0, 0}, {0, s}},
|
||||
{{0, 0}, {c, 0}, {0, -s}, {0, 0}},
|
||||
{{0, 0}, {0, -s}, {c, 0}, {0, 0}},
|
||||
{{0, s}, {0, 0}, {0, 0}, {c, 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix YYGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
double c = cos(theta);
|
||||
double s = sin(theta);
|
||||
|
||||
Matrix result = {{{-s, 0}, {0, 0}, {0, 0}, {0, c}},
|
||||
{{0, 0}, {-s, 0}, {0, -c}, {0, 0}},
|
||||
{{0, 0}, {0, -c}, {-s, 0}, {0, 0}},
|
||||
{{0, c}, {0, 0}, {0, 0}, {-s, 0}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
ZZGate::ZZGate(const Indexes &obj_qubits, const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: IntrinsicOneParaGate("ZZ", obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
Matrix ZZGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
double c = cos(theta);
|
||||
double s = sin(theta);
|
||||
|
||||
Matrix result = {{{c, -s}, {0, 0}, {0, 0}, {0, 0}},
|
||||
{{0, 0}, {c, s}, {0, 0}, {0, 0}},
|
||||
{{0, 0}, {0, 0}, {c, s}, {0, 0}},
|
||||
{{0, 0}, {0, 0}, {0, 0}, {c, -s}}};
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix ZZGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
double c = cos(theta);
|
||||
double s = sin(theta);
|
||||
|
||||
Matrix result = {{{-s, -c}, {0, 0}, {0, 0}, {0, 0}},
|
||||
{{0, 0}, {-s, c}, {0, 0}, {0, 0}},
|
||||
{{0, 0}, {0, 0}, {-s, c}, {0, 0}},
|
||||
{{0, 0}, {0, 0}, {0, 0}, {-s, -c}}};
|
||||
return result;
|
||||
}
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_GATES_H_
|
||||
#define MINDQUANTUM_ENGINE_GATES_H_
|
||||
#include "mindquantum/gates/intrinsic_one_para_gate.h"
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
class RXGate : public IntrinsicOneParaGate {
|
||||
Matrix GetIntrinsicMatrix(CalcType) override;
|
||||
Matrix GetIntrinsicDiffMatrix(CalcType) override;
|
||||
|
||||
public:
|
||||
RXGate(const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
RXGate();
|
||||
};
|
||||
|
||||
class RYGate : public IntrinsicOneParaGate {
|
||||
Matrix GetIntrinsicMatrix(CalcType) override;
|
||||
Matrix GetIntrinsicDiffMatrix(CalcType) override;
|
||||
|
||||
public:
|
||||
RYGate(const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
};
|
||||
|
||||
class RZGate : public IntrinsicOneParaGate {
|
||||
Matrix GetIntrinsicMatrix(CalcType) override;
|
||||
Matrix GetIntrinsicDiffMatrix(CalcType) override;
|
||||
|
||||
public:
|
||||
RZGate(const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
};
|
||||
|
||||
class PhaseShiftGate : public IntrinsicOneParaGate {
|
||||
Matrix GetIntrinsicMatrix(CalcType) override;
|
||||
Matrix GetIntrinsicDiffMatrix(CalcType) override;
|
||||
|
||||
public:
|
||||
PhaseShiftGate(const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
};
|
||||
|
||||
class XXGate : public IntrinsicOneParaGate {
|
||||
Matrix GetIntrinsicMatrix(CalcType) override;
|
||||
Matrix GetIntrinsicDiffMatrix(CalcType) override;
|
||||
|
||||
public:
|
||||
XXGate(const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
};
|
||||
|
||||
class YYGate : public IntrinsicOneParaGate {
|
||||
Matrix GetIntrinsicMatrix(CalcType) override;
|
||||
Matrix GetIntrinsicDiffMatrix(CalcType) override;
|
||||
|
||||
public:
|
||||
YYGate(const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
};
|
||||
|
||||
class ZZGate : public IntrinsicOneParaGate {
|
||||
Matrix GetIntrinsicMatrix(CalcType) override;
|
||||
Matrix GetIntrinsicDiffMatrix(CalcType) override;
|
||||
|
||||
public:
|
||||
ZZGate(const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
};
|
||||
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_GATES_H_
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mindquantum/gates/intrinsic_one_para_gate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
Matrix IntrinsicOneParaGate::GetIntrinsicMatrix(CalcType theta) {
|
||||
Matrix gate_matrix_tmp;
|
||||
return gate_matrix_tmp;
|
||||
}
|
||||
|
||||
Matrix IntrinsicOneParaGate::GetIntrinsicDiffMatrix(CalcType theta) {
|
||||
Matrix gate_matrix_tmp;
|
||||
return gate_matrix_tmp;
|
||||
}
|
||||
|
||||
IntrinsicOneParaGate::IntrinsicOneParaGate(const std::string &name, const Indexes &obj_qubits,
|
||||
const Indexes &ctrl_qubits, const ParameterResolver ¶s)
|
||||
: ParameterGate(name, obj_qubits, ctrl_qubits, paras) {}
|
||||
|
||||
CalcType IntrinsicOneParaGate::LinearCombination(const ParameterResolver ¶s_in,
|
||||
const ParameterResolver ¶s_out) {
|
||||
CalcType result = 0;
|
||||
auto ¶s_in_data = paras_in.GetData();
|
||||
auto ¶s_out_data = paras_out.GetData();
|
||||
for (ParaType::const_iterator i = paras_in_data.begin(); i != paras_in_data.end(); ++i) {
|
||||
result = result + paras_out_data.at(i->first) * (i->second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Matrix IntrinsicOneParaGate::GetMatrix(const ParameterResolver ¶s_out) {
|
||||
return GetIntrinsicMatrix(LinearCombination(GetParameterResolver(), paras_out));
|
||||
}
|
||||
Matrix IntrinsicOneParaGate::GetDiffMatrix(const ParameterResolver ¶s_out) {
|
||||
return GetIntrinsicDiffMatrix(LinearCombination(GetParameterResolver(), paras_out));
|
||||
}
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_INTRINSIC_ONE_PARAGATE_H_
|
||||
#define MINDQUANTUM_ENGINE_INTRINSIC_ONE_PARAGATE_H_
|
||||
#include <string>
|
||||
#include "mindquantum/gates/parameter_gate.h"
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
class IntrinsicOneParaGate : public ParameterGate {
|
||||
virtual Matrix GetIntrinsicMatrix(CalcType);
|
||||
virtual Matrix GetIntrinsicDiffMatrix(CalcType);
|
||||
|
||||
public:
|
||||
IntrinsicOneParaGate();
|
||||
IntrinsicOneParaGate(const std::string &, const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
CalcType LinearCombination(const ParameterResolver &, const ParameterResolver &);
|
||||
Matrix GetMatrix(const ParameterResolver &) override;
|
||||
Matrix GetDiffMatrix(const ParameterResolver &) override;
|
||||
};
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_INTRINSIC_ONE_PARAGATE_H_
|
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mindquantum/gates/non_parameter_gate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
NoneParameterGate::NoneParameterGate(const std::string &name, const Matrix &gate_matrix, const Indexes &obj_qubits,
|
||||
const Indexes &ctrl_qubits)
|
||||
: BasicGate(name, false, obj_qubits, ctrl_qubits), gate_matrix_(gate_matrix) {}
|
||||
|
||||
Matrix &NoneParameterGate::GetBaseMatrix() { return gate_matrix_; }
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_NON_PARAMETER_GATE_H_
|
||||
#define MINDQUANTUM_ENGINE_NON_PARAMETER_GATE_H_
|
||||
#include <string>
|
||||
#include "mindquantum/gates/basic_gates.h"
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
class NoneParameterGate : public BasicGate {
|
||||
private:
|
||||
Matrix gate_matrix_;
|
||||
|
||||
public:
|
||||
NoneParameterGate(const std::string &, const Matrix &, const Indexes &, const Indexes &);
|
||||
Matrix &GetBaseMatrix() override;
|
||||
};
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_NON_PARAMETER_GATE_H_
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mindquantum/gates/parameter_gate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
ParameterGate::ParameterGate(const std::string &name, const Indexes &obj_qubits, const Indexes &ctrl_qubits,
|
||||
const ParameterResolver ¶s)
|
||||
: BasicGate(name, true, obj_qubits, ctrl_qubits, paras) {}
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_PARAMETER_GATE_H_
|
||||
#define MINDQUANTUM_ENGINE_PARAMETER_GATE_H_
|
||||
#include <string>
|
||||
#include "mindquantum/gates/basic_gates.h"
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
class ParameterGate : public BasicGate {
|
||||
public:
|
||||
ParameterGate();
|
||||
ParameterGate(const std::string &, const Indexes &, const Indexes &, const ParameterResolver &);
|
||||
};
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_PARAMETER_GATE_H_
|
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mindquantum/hamiltonian.h"
|
||||
|
||||
#include <utility>
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
Hamiltonian::Hamiltonian() {}
|
||||
Hamiltonian::Hamiltonian(const sparse::GoodHamilt &ham, Index n) : ham_(ham), n_qubits_(n) {}
|
||||
|
||||
sparse::DequeSparseHam Hamiltonian::TransHamiltonianPhaseOne(int n_thread1, const sparse::GoodHamilt &ham, Index n) {
|
||||
sparse::DequeSparseHam ham_sparse;
|
||||
ham_sparse.resize(ham.size());
|
||||
int step = 0;
|
||||
#pragma omp parallel for schedule(static) num_threads(n_thread1)
|
||||
for (Index i = 0; i < ham.size(); i++) {
|
||||
auto > = ham.at(i);
|
||||
if (gt.second[0].first.size() == 0) {
|
||||
ham_sparse[i] = sparse::IdentitySparse(n) * gt.first.first * gt.second[0].second;
|
||||
} else {
|
||||
ham_sparse[i] = sparse::GoodTerm2Sparse(gt, n);
|
||||
}
|
||||
if ((++step) % 20 == 0) std::cout << "\r" << step << "\t/" << ham.size() << "\tfinshed" << std::flush;
|
||||
}
|
||||
std::cout << "\ncalculate hamiltonian phase1 finished\n";
|
||||
return ham_sparse;
|
||||
}
|
||||
|
||||
int Hamiltonian::TransHamiltonianPhaseTwo(sparse::DequeSparseHam &ham_sparse, int n_thread2, int n_split) {
|
||||
int n = ham_sparse.size();
|
||||
while (n > 1) {
|
||||
int half = n / 2 + n % 2;
|
||||
std::cout << "n: " << n << "\t, half: " << half << "\n";
|
||||
if (n < n_split) {
|
||||
break;
|
||||
}
|
||||
#pragma omp parallel for schedule(static) num_threads(half)
|
||||
for (int i = half; i < n; i++) {
|
||||
ham_sparse[i - half] += ham_sparse[i];
|
||||
}
|
||||
ham_sparse.erase(ham_sparse.end() - half + n % 2, ham_sparse.end());
|
||||
n = half;
|
||||
}
|
||||
std::cout << "total: " << ham_sparse.size() << " phase2 finished\n";
|
||||
return n;
|
||||
}
|
||||
|
||||
void Hamiltonian::SparseHamiltonian(int n_thread1, int n_thread2, int n_split) {
|
||||
ham_sparse_ = Hamiltonian::TransHamiltonianPhaseOne(n_thread1, ham_, n_qubits_);
|
||||
final_size_ = Hamiltonian::TransHamiltonianPhaseTwo(ham_sparse_, n_thread2, n_split);
|
||||
}
|
||||
|
||||
void Hamiltonian::SetTermsDict(Simulator::TermsDict const &d) {
|
||||
td_ = d;
|
||||
Simulator::ComplexTermsDict().swap(ctd_);
|
||||
for (auto &term : td_) {
|
||||
ComplexType coeff = {term.second, 0};
|
||||
ctd_.push_back(std::make_pair(term.first, coeff));
|
||||
}
|
||||
}
|
||||
|
||||
void Hamiltonian::Sparsed(bool s) { ham_sparsed_ = s; }
|
||||
const Simulator::ComplexTermsDict &Hamiltonian::GetCTD() const { return ctd_; }
|
||||
const Simulator::TermsDict &Hamiltonian::GetTD() const { return td_; }
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_CHAMILTONIAN_H_
|
||||
#define MINDQUANTUM_ENGINE_CHAMILTONIAN_H_
|
||||
#include "projectq/backends/_sim/_cppkernels/simulator.hpp"
|
||||
#include "mindquantum/gates/basic_gates.h"
|
||||
#include "mindquantum/sparse.h"
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
class Hamiltonian {
|
||||
private:
|
||||
sparse::GoodHamilt ham_;
|
||||
Index n_qubits_;
|
||||
sparse::DequeSparseHam ham_sparse_;
|
||||
Simulator::TermsDict td_;
|
||||
Simulator::ComplexTermsDict ctd_;
|
||||
int final_size_ = 1;
|
||||
bool ham_sparsed_ = false;
|
||||
|
||||
public:
|
||||
Hamiltonian();
|
||||
Hamiltonian(const sparse::GoodHamilt &, Index);
|
||||
sparse::DequeSparseHam TransHamiltonianPhaseOne(int, const sparse::GoodHamilt &, Index);
|
||||
int TransHamiltonianPhaseTwo(sparse::DequeSparseHam &, int, int);
|
||||
void SparseHamiltonian(int, int, int);
|
||||
void SetTermsDict(Simulator::TermsDict const &);
|
||||
void Sparsed(bool);
|
||||
const Simulator::ComplexTermsDict &GetCTD() const;
|
||||
const Simulator::TermsDict &GetTD() const;
|
||||
};
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_CHAMILTONIAN_H_
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mindquantum/parameter_resolver.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
ParameterResolver::ParameterResolver()
|
||||
: data_(ParaType()), no_grad_parameters_(ParaSetType()), requires_grad_parameters_(ParaSetType()) {}
|
||||
|
||||
ParameterResolver::ParameterResolver(const ParaType &data, const ParaSetType &no_grad_parameters,
|
||||
const ParaSetType &requires_grad_parameters)
|
||||
: data_(data), no_grad_parameters_(no_grad_parameters), requires_grad_parameters_(requires_grad_parameters) {}
|
||||
|
||||
const ParaType &ParameterResolver::GetData() const { return data_; }
|
||||
const ParaSetType &ParameterResolver::GetRequiresGradParameters() const { return requires_grad_parameters_; }
|
||||
void ParameterResolver::SetData(const std::string &name, const CalcType &value) { data_[name] = value; }
|
||||
void ParameterResolver::InsertNoGrad(const std::string &name) { no_grad_parameters_.insert(name); }
|
||||
void ParameterResolver::InsertRequiresGrad(const std::string &name) { requires_grad_parameters_.insert(name); }
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDQUANTUM_ENGINE_PARAMETER_RESOLVER_H_
|
||||
#define MINDQUANTUM_ENGINE_PARAMETER_RESOLVER_H_
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "mindquantum/utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
|
||||
class ParameterResolver {
|
||||
public:
|
||||
ParameterResolver();
|
||||
ParameterResolver(const ParaType &, const ParaSetType &, const ParaSetType &);
|
||||
const ParaType &GetData() const;
|
||||
const ParaSetType &GetRequiresGradParameters() const;
|
||||
void SetData(const std::string &, const CalcType &);
|
||||
void InsertNoGrad(const std::string &);
|
||||
void InsertRequiresGrad(const std::string &);
|
||||
|
||||
private:
|
||||
ParaType data_;
|
||||
ParaSetType no_grad_parameters_;
|
||||
ParaSetType requires_grad_parameters_;
|
||||
};
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
||||
#endif // MINDQUANTUM_ENGINE_PARAMETER_RESOLVER_H_
|
@ -0,0 +1,192 @@
|
||||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mindquantum/pqc_simulator.h"
|
||||
|
||||
#include <omp.h>
|
||||
#include <numeric>
|
||||
|
||||
namespace mindspore {
|
||||
namespace mindquantum {
|
||||
PQCSimulator::PQCSimulator() : Simulator(1), n_qubits_(1) {
|
||||
PQCSimulator::AllocateAll();
|
||||
for (Index i = 0; i < n_qubits_; i++) {
|
||||
ordering_.push_back(i);
|
||||
}
|
||||
len_ = (1UL << n_qubits_);
|
||||
}
|
||||
|
||||
PQCSimulator::PQCSimulator(Index seed = 1, Index N = 1) : Simulator(seed), n_qubits_(N) {
|
||||
PQCSimulator::AllocateAll();
|
||||
for (Index i = 0; i < n_qubits_; i++) {
|
||||
ordering_.push_back(i);
|
||||
}
|
||||
len_ = (1UL << n_qubits_);
|
||||
}
|
||||
|
||||
void PQCSimulator::ApplyGate(std::shared_ptr<BasicGate> g, const ParameterResolver ¶s, bool diff) {
|
||||
if (g->IsParameterGate()) {
|
||||
if (diff) {
|
||||
PQCSimulator::apply_controlled_gate(g->GetDiffMatrix(paras), g->GetObjQubits(), g->GetCtrlQubits());
|
||||
} else {
|
||||
PQCSimulator::apply_controlled_gate(g->GetMatrix(paras), g->GetObjQubits(), g->GetCtrlQubits());
|
||||
}
|
||||
} else {
|
||||
PQCSimulator::apply_controlled_gate(g->GetBaseMatrix(), g->GetObjQubits(), g->GetCtrlQubits());
|
||||
}
|
||||
}
|
||||
|
||||
void PQCSimulator::ApplyBlock(const GateBlock &b, const mindquantum::ParameterResolver ¶s) {
|
||||
for (auto &g : b) {
|
||||
PQCSimulator::ApplyGate(g, paras, false);
|
||||
}
|
||||
PQCSimulator::run();
|
||||
}
|
||||
|
||||
void PQCSimulator::ApplyBlocks(const GateBlocks &bs, const ParameterResolver ¶s) {
|
||||
for (auto &b : bs) {
|
||||
PQCSimulator::ApplyBlock(b, paras);
|
||||
}
|
||||
}
|
||||
|
||||
void PQCSimulator::Evolution(BasicCircuit const &circuit, ParameterResolver const ¶s) {
|
||||
PQCSimulator::ApplyBlocks(circuit.GetGateBlocks(), paras);
|
||||
}
|
||||
|
||||
CalcType PQCSimulator::Measure(Index mask1, Index mask2, bool apply) {
|
||||
CalcType out = 0;
|
||||
#pragma omp parallel for reduction(+ : out) schedule(static)
|
||||
for (unsigned i = 0; i < (1UL << n_qubits_); i++) {
|
||||
if (((i & mask1) == mask1) && ((i | mask2) == mask2)) {
|
||||
out = out + std::real(vec_[i]) * std::real(vec_[i]) + std::imag(vec_[i]) * std::imag(vec_[i]);
|
||||
} else if (apply) {
|
||||
vec_[i] = 0;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<std::vector<float>> PQCSimulator::CalcGradient(const std::shared_ptr<CalcGradientParam> &input_params,
|
||||
PQCSimulator &s_left, PQCSimulator &s_right,
|
||||
PQCSimulator &s_right_tmp) {
|
||||
// Suppose the simulator already evaluate the circuit.
|
||||
auto circuit = input_params->circuit_cp;
|
||||
auto circuit_hermitian = input_params->circuit_hermitian_cp;
|
||||
auto hamiltonians = input_params->hamiltonians_cp;
|
||||
auto paras = input_params->paras_cp;
|
||||
auto encoder_params_names = input_params->encoder_params_names_cp;
|
||||
auto ansatz_params_names = input_params->ansatz_params_names_cp;
|
||||
auto dummy_circuit_ = input_params->dummy_circuit_cp;
|
||||
auto &circ_gate_blocks = circuit->GetGateBlocks();
|
||||
auto &circ_herm_gate_blocks = circuit_hermitian->GetGateBlocks();
|
||||
std::map<std::string, size_t> poi;
|
||||
for (size_t i = 0; i < encoder_params_names->size(); i++) {
|
||||
poi[encoder_params_names->at(i)] = i;
|
||||
}
|
||||
for (size_t i = 0; i < ansatz_params_names->size(); i++) {
|
||||
poi[ansatz_params_names->at(i)] = i + encoder_params_names->size();
|
||||
}
|
||||
if (circ_gate_blocks.size() == 0 || circ_herm_gate_blocks.size() == 0) {
|
||||
MS_LOG(EXCEPTION) << "Empty quantum circuit!";
|
||||
}
|
||||
unsigned len = circ_gate_blocks.at(0).size();
|
||||
std::vector<float> grad(hamiltonians->size() * poi.size(), 0);
|
||||
std::vector<float> e0(hamiltonians->size(), 0);
|
||||
|
||||
// #pragma omp parallel for
|
||||
for (size_t h_index = 0; h_index < hamiltonians->size(); h_index++) {
|
||||
auto &hamiltonian = hamiltonians->at(h_index);
|
||||
s_right.set_wavefunction(vec_, ordering_);
|
||||
s_left.set_wavefunction(s_right.vec_, ordering_);
|
||||
s_left.apply_qubit_operator(hamiltonian.GetCTD(), ordering_);
|
||||
e0[h_index] = static_cast<float>(ComplexInnerProduct(vec_, s_left.vec_, len_).real());
|
||||
if (dummy_circuit_) {
|
||||
continue;
|
||||
}
|
||||
for (unsigned i = 0; i < len; i++) {
|
||||
if ((!circ_herm_gate_blocks.at(0)[i]->IsParameterGate()) ||
|
||||
(circ_herm_gate_blocks.at(0)[i]->GetParameterResolver().GetRequiresGradParameters().size() == 0)) {
|
||||
s_left.ApplyGate(circ_herm_gate_blocks.at(0)[i], *paras, false);
|
||||
s_right.ApplyGate(circ_herm_gate_blocks.at(0)[i], *paras, false);
|
||||
} else {
|
||||
s_right.ApplyGate(circ_herm_gate_blocks.at(0)[i], *paras, false);
|
||||
s_right.run();
|
||||
s_right_tmp.set_wavefunction(s_right.vec_, ordering_);
|
||||
s_right_tmp.ApplyGate(circ_gate_blocks.at(0)[len - 1 - i], *paras, true);
|
||||
s_right_tmp.run();
|
||||
s_left.run();
|
||||
ComplexType gi = 0;
|
||||
if (circ_herm_gate_blocks.at(0)[i]->GetCtrlQubits().size() == 0) {
|
||||
gi = ComplexInnerProduct(s_left.vec_, s_right_tmp.vec_, len_);
|
||||
} else {
|
||||
gi = ComplexInnerProductWithControl(s_left.vec_, s_right_tmp.vec_, len_,
|
||||
GetControlMask(circ_herm_gate_blocks.at(0)[i]->GetCtrlQubits()));
|
||||
}
|
||||
for (auto &it : circ_herm_gate_blocks.at(0)[i]->GetParameterResolver().GetRequiresGradParameters()) {
|
||||
grad[h_index * poi.size() + poi[it]] -= static_cast<float>(
|
||||
2 * circ_herm_gate_blocks.at(0)[i]->GetParameterResolver().GetData().at(it) * std::real(gi));
|
||||
}
|
||||
s_left.ApplyGate(circ_herm_gate_blocks.at(0)[i], *paras, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<float> grad1;
|
||||
std::vector<float> grad2;
|
||||
for (size_t i = 0; i < hamiltonians->size(); i++) {
|
||||
for (size_t j = 0; j < poi.size(); j++) {
|
||||
if (j < encoder_params_names->size()) {
|
||||
grad1.push_back(grad[i * poi.size() + j]);
|
||||
} else {
|
||||
grad2.push_back(grad[i * poi.size() + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {e0, grad1, grad2};
|
||||
}
|
||||
|
||||
void PQCSimulator::AllocateAll() {
|
||||
for (unsigned i = 0; i < n_qubits_; i++) {
|
||||
Simulator::allocate_qubit(i);
|
||||
}
|
||||
}
|
||||
void PQCSimulator::DeallocateAll() {
|
||||
for (unsigned i = 0; i < n_qubits_; i++) {
|
||||
Simulator::deallocate_qubit(i);
|
||||
}
|
||||
}
|
||||
void PQCSimulator::SetState(const StateVector &wavefunction) { Simulator::set_wavefunction(wavefunction, ordering_); }
|
||||
|
||||
std::size_t PQCSimulator::GetControlMask(Indexes const &ctrls) {
|
||||
std::size_t ctrlmask =
|
||||
std::accumulate(ctrls.begin(), ctrls.end(), 0, [&](Index a, Index b) { return a | (1UL << ordering_[b]); });
|
||||
return ctrlmask;
|
||||
}
|
||||
|
||||
void PQCSimulator::ApplyHamiltonian(const Hamiltonian &ham) {
|
||||
Simulator::apply_qubit_operator(ham.GetCTD(), ordering_);
|
||||
}
|
||||
|
||||
CalcType PQCSimulator::GetExpectationValue(const Hamiltonian &ham) {
|
||||
return Simulator::get_expectation_value(ham.GetTD(), ordering_);
|
||||
}
|
||||
void PQCSimulator::SetZeroState() {
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (size_t i = 0; i < len_; i++) {
|
||||
vec_[i] = {0, 0};
|
||||
}
|
||||
vec_[0] = {1, 0};
|
||||
}
|
||||
} // namespace mindquantum
|
||||
} // namespace mindspore
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue