38 #include <tbb/enumerable_thread_specific.h> 40 extern "C" int LAPACKE_dgesv(
int matrix_layout,
int n,
int nrhs,
double *a,
int lda,
int *ipiv,
double *b,
int ldb);
153 max_layer_num.insert( std::pair<int, int>(it->first, it->second) );
178 std::uniform_int_distribution<> distrib_int(0, INT_MAX);
179 id = distrib_int(
gen);
191 #elif defined __GROQ__ 222 max_layer_num.insert( std::pair<int, int>(it->first, it->second) );
245 std::uniform_int_distribution<> distrib_int(0, INT_MAX);
246 id = distrib_int(
gen);
256 #elif defined __GROQ__ 291 if (
this == &other ) {
295 Decomposition_Base::operator=(other);
345 std::string
filename(
"costfuncs_and_entropy.txt");
351 const char* c_filename = filename.c_str();
353 errno_t err = fopen_s(&pFile, c_filename,
"a");
358 pFile = fopen(c_filename,
"a");
362 fputs (
"File error",stderr);
363 std::string error(
"Cannot open file.");
369 std::uniform_int_distribution<> distrib(0,
qbit_num-2);
371 memset(input_state.
get_data(), 0, (input_state.
size()*2)*
sizeof(
double) );
372 input_state[0].real = 1.0;
414 for (
int qbit=0; qbit<
qbit_num; qbit++) {
453 double d = 1.0/decomposed_matrix.
cols;
459 double d = 1.0/decomposed_matrix.
cols;
473 std::string err(
"Optimization_Interface::optimization_problem: Cost function variant not implmented.");
487 std::stringstream sstream;
488 sstream <<
"***************************************************************" << std::endl;
489 sstream <<
"Final fine tuning of the parameters in the " <<
qbit_num <<
"-qubit decomposition" << std::endl;
490 sstream <<
"***************************************************************" << std::endl;
556 std::string error(
"Optimization_Interface::solve_layer_optimization_problem: unimplemented optimization algorithm");
578 std::uniform_real_distribution<> distrib_prob(0.0, 1.0);
579 std::uniform_real_distribution<> distrib_real(-2*
M_PI, 2*
M_PI);
583 if (
config.count(
"Randomized_Radius") > 0 ) {
584 config[
"Randomized_Radius"].get_property( radius_loc );
592 int changed_parameters = 0;
595 output[jdx] = (
cost_fnc!=
VQE) ? input[jdx] + distrib_real(
gen)*std::sqrt(f0)*radius_loc : input[jdx] + distrib_real(
gen)*radius_loc;
596 changed_parameters++;
599 output[jdx] = input[jdx];
637 std::stringstream sstream;
638 sstream <<
"Optimization_Interface::optimization_problem: Number of free paramaters should be " <<
parameter_num <<
", but got " << parameters.
size() << std::endl;
640 std::string err(
"Optimization_Interface::optimization_problem: Wrong number of parameters.");
648 const bool use_float_cost_path =
false;
649 if ( use_float_cost_path &&
use_float ) {
650 static tbb::enumerable_thread_specific<Matrix_real_float> parameters_float_tls;
651 static tbb::enumerable_thread_specific<Matrix_float> matrix_new_tls;
654 parameters.
copy_to(parameters_float);
660 static tbb::enumerable_thread_specific<Matrix> matrix_new_tls;
661 Matrix& matrix_new = matrix_new_tls.local();
688 if ( ret_temp != NULL ) {
690 (*ret_temp)[0].real = trace_temp.
real;
691 (*ret_temp)[0].imag = trace_temp.
imag;
692 double d = 1.0/matrix_new.
cols;
693 return 1 - d*d*(trace_temp.
real*trace_temp.
real + trace_temp.
imag*trace_temp.
imag);
698 double d = 1.0/matrix_new.
cols;
699 if ( ret_temp != NULL ) {
700 for (
int idx=0; idx<3; idx++) {
701 (*ret_temp)[idx].real = ret[idx].real;
702 (*ret_temp)[idx].imag = ret[idx].imag;
708 double d = 1.0/matrix_new.
cols;
709 if ( ret_temp != NULL ) {
710 for (
int idx=0; idx<4; idx++) {
711 (*ret_temp)[idx].real = ret[idx].real;
712 (*ret_temp)[idx].imag = ret[idx].imag;
719 if ( ret_temp != NULL ) {
721 (*ret_temp)[0].real = trace_temp.
real;
722 (*ret_temp)[0].imag = trace_temp.
imag;
723 double d = matrix_new.
cols;
724 return 1.0-((trace_temp.
real*trace_temp.
real+trace_temp.
imag*trace_temp.
imag)/d+1)/(d+1);
730 std::string err(
"Optimization_Interface::optimization_problem: Cost function variant not implmented.");
752 if ( ret_temp != NULL ) {
753 (*ret_temp)[0].real =
static_cast<float>(trace_temp.
real);
754 (*ret_temp)[0].imag =
static_cast<float>(trace_temp.
imag);
756 double d = 1.0/matrix_new.
cols;
757 return 1 - d*d*(trace_temp.
real*trace_temp.
real + trace_temp.
imag*trace_temp.
imag); }
760 if ( ret_temp != NULL ) {
761 (*ret_temp)[0].real =
static_cast<float>(trace_temp.
real);
762 (*ret_temp)[0].imag =
static_cast<float>(trace_temp.
imag);
764 double d = matrix_new.
cols;
765 return 1.0-((trace_temp.
real*trace_temp.
real+trace_temp.
imag*trace_temp.
imag)/d+1)/(d+1); }
776 std::string err(
"Optimization_Interface::calculate_cost_function(Matrix_float&): Cost function variant not implmented.");
789 Optimization_Interface::optimization_problem_batched_DFE( std::vector<Matrix_real>& parameters_vec) {
792 Matrix_real cost_fnc_mtx(parameters_vec.size(), 1);
794 int gatesNum, gateSetNum, redundantGateSets;
795 DFEgate_kernel_type* DFEgates = convert_to_batched_DFE_gates( parameters_vec, gatesNum, gateSetNum, redundantGateSets );
809 int mpi_starting_gateSetIdx = gateSetNum/
world_size * current_rank;
822 int bytes = mpi_trace_DFE_mtx.
size()*
sizeof(double);
823 MPI_Allgather(mpi_trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, MPI_COMM_WORLD);
836 for (
int idx=0; idx<parameters_vec.size(); idx++ ) {
837 cost_fnc_mtx[idx] = 1-trace_DFE_mtx[idx*3]/
Umtx.
cols;
841 for (
int idx=0; idx<parameters_vec.size(); idx++ ) {
846 for (
int idx=0; idx<parameters_vec.size(); idx++ ) {
851 std::string err(
"Optimization_Interface::optimization_problem_batched: Cost function variant not implmented for DFE.");
880 throw std::string(
"Optimization_Interface::optimization_problem_Groq should be implemented in derrived classes.");
894 Optimization_Interface::optimization_problem_batched_Groq( std::vector<Matrix_real>& parameters_vec) {
896 int task_num = parameters_vec.
size();
906 int chosen_device = 0;
908 for(
int idx=0; idx<task_num; idx++ ) {
909 cost_fnc_mtx[idx] = optimization_problem_Groq( parameters_vec[idx], chosen_device );
915 for(
int idx=0; idx<task_num; idx=idx+2 ) {
916 tbb::parallel_invoke(
917 [&]() { cost_fnc_mtx[idx] = optimization_problem_Groq( parameters_vec[idx], 0 ); },
918 [&]() {
if ( (idx+1) < task_num ) cost_fnc_mtx[idx+1] = optimization_problem_Groq( parameters_vec[idx+1], 1 ); }
924 throw std::string(
"Unsupported number of Groq accelerators.");
947 return optimization_problem_batched_DFE( parameters_vec );
949 #elif defined __GROQ__ 951 return optimization_problem_batched_Groq( parameters_vec );
956 Matrix_real cost_fnc_mtx(static_cast<int>(parameters_vec.size()), 1);
964 int batch_element_num = parameters_vec.size();
965 int mpi_batch_element_num = batch_element_num /
world_size;
966 int mpi_batch_element_remainder = batch_element_num %
world_size;
968 if ( mpi_batch_element_remainder > 0 ) {
969 std::string err(
"Optimization_Interface::optimization_problem_batched: The size of the batch should be divisible with the number of processes.");
973 int mpi_starting_batchIdx = mpi_batch_element_num * current_rank;
976 Matrix_real cost_fnc_mtx_loc(mpi_batch_element_num, 1);
978 auto calculate_local_batch_element = [&](
int idx) {
982 if ( parallel == 0 ) {
983 for (
int idx=0; idx<mpi_batch_element_num; ++idx) {
984 calculate_local_batch_element(idx);
989 tbb::parallel_for( tbb::blocked_range<int>(0, (
int)mpi_batch_element_num, work_batch), [&](tbb::blocked_range<int> r) {
990 for (
int idx=r.begin(); idx<r.end(); ++idx) {
991 calculate_local_batch_element(idx);
1000 int bytes = cost_fnc_mtx_loc.
size()*
sizeof(double);
1001 MPI_Allgather(cost_fnc_mtx_loc.
get_data(), bytes, MPI_BYTE, cost_fnc_mtx.
get_data(), bytes, MPI_BYTE, MPI_COMM_WORLD);
1006 auto calculate_batch_element = [&](
int idx) {
1010 if ( parallel == 0 ) {
1011 for (
int idx=0; idx<(
int)parameters_vec.size(); ++idx) {
1012 calculate_batch_element(idx);
1017 tbb::parallel_for( tbb::blocked_range<int>(0, (
int)parameters_vec.size(), work_batch), [&](tbb::blocked_range<int> r) {
1018 for (
int idx=r.begin(); idx<r.end(); ++idx) {
1019 calculate_batch_element(idx);
1028 return cost_fnc_mtx;
1052 const bool use_float_cost_path =
false;
1054 static tbb::enumerable_thread_specific<Matrix_real_float> parameters_float_tls;
1055 static tbb::enumerable_thread_specific<Matrix_float> matrix_new_tls;
1056 static tbb::enumerable_thread_specific<Matrix_float> ret_temp_float_tls;
1059 Matrix_float& ret_temp_float = ret_temp_float_tls.local();
1060 parameters.
copy_to(parameters_float);
1062 instance->Gates_block::apply_to( parameters_float, matrix_new );
1069 static tbb::enumerable_thread_specific<Matrix> matrix_new_tls;
1070 Matrix& matrix_new = matrix_new_tls.local();
1072 instance->Gates_block::apply_to( parameters, matrix_new );
1166 const bool use_float_combined_cost_path =
false;
1167 if ( use_float_combined_cost_path && instance->
get_use_float() ) {
1168 static tbb::enumerable_thread_specific<Matrix_real_float> parameters_float_tls;
1170 parameters.
copy_to(parameters_float);
1172 static tbb::enumerable_thread_specific<std::vector<Matrix_float>> combined_result_tls;
1173 std::vector<Matrix_float>& combined_result = combined_result_tls.local();
1174 instance->Gates_block::apply_to_combined( parameters_float, Umtx_loc, parallel, combined_result );
1191 auto calculate_gradient_component = [&](
int idx) {
1193 Matrix_float& deriv_mtx = combined_result[
static_cast<size_t>(idx) + 1];
1200 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*deriv_tmp[1]*correction1_scale - 1.0);
1205 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*(deriv_tmp[1]*correction1_scale + deriv_tmp[2]*
correction2_scale) - 1.0);
1209 double d = 1.0/deriv_mtx.
cols;
1211 grad_comp = -2.0*d*d*trace_tmp[0].real*deriv_tmp.
real-2.0*d*d*trace_tmp[0].imag*deriv_tmp.
imag;
1215 double d = deriv_mtx.
cols;
1217 grad_comp = -2.0/d/(d+1)*trace_tmp[0].
real*deriv_tmp.
real-2.0/d/(d+1)*trace_tmp[0].imag*deriv_tmp.
imag;
1236 double d = 1.0/deriv64.
cols;
1237 grad_comp = -2.0*d*d*(trace_tmp64[0].real*deriv_tmp[0].real+trace_tmp64[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*correction1_scale*(trace_tmp64[1].real*deriv_tmp[1].real+trace_tmp64[1].imag*deriv_tmp[1].imag));
1241 double d = 1.0/deriv64.
cols;
1242 grad_comp = -2.0*d*d*(trace_tmp64[0].real*deriv_tmp[0].real+trace_tmp64[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*(correction1_scale*(trace_tmp64[1].real*deriv_tmp[1].real+trace_tmp64[1].imag*deriv_tmp[1].imag) + correction2_scale*(trace_tmp64[2].
real*deriv_tmp[2].
real+trace_tmp64[2].imag*deriv_tmp[2].imag)));
1247 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1250 grad[idx] = grad_comp;
1253 if ( parallel == 0 ) {
1254 for (
int idx=0; idx<parameter_num_loc; ++idx) {
1255 calculate_gradient_component(idx);
1259 int work_batch = 10;
1260 tbb::parallel_for( tbb::blocked_range<int>(0,parameter_num_loc,work_batch), [&](tbb::blocked_range<int> r) {
1261 for (
int idx=r.begin(); idx<r.end(); ++idx) {
1262 calculate_gradient_component(idx);
1268 std::stringstream sstream;
1269 sstream << *f0 << std::endl;
1270 instance->
print(sstream, 5);
1281 int gatesNum, redundantGateSets, gateSetNum;
1282 DFEgate_kernel_type* DFEgates = instance->convert_to_DFE_gates_with_derivates( parameters, gatesNum, gateSetNum, redundantGateSets );
1291 int mpi_gateSetNum = gateSetNum / instance->world_size;
1292 int mpi_starting_gateSetIdx = gateSetNum/instance->world_size * instance->current_rank;
1300 calcqgdKernelDFE( Umtx_loc.
rows, Umtx_loc.
cols, DFEgates+mpi_starting_gateSetIdx*gatesNum, gatesNum, mpi_gateSetNum, trace_offset_loc, mpi_trace_DFE_mtx.
get_data() );
1303 int bytes = mpi_trace_DFE_mtx.
size()*
sizeof(double);
1304 MPI_Allgather(mpi_trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, MPI_COMM_WORLD);
1317 std::stringstream sstream;
1318 sstream << *f0 <<
" " << 1.0 - trace_DFE_mtx[0]/Umtx_loc.
cols <<
" " << trace_DFE_mtx[1]/Umtx_loc.
cols <<
" " << trace_DFE_mtx[2]/Umtx_loc.
cols << std::endl;
1319 instance->
print(sstream, 5);
1323 *f0 = 1-trace_DFE_mtx[0]/Umtx_loc.
cols;
1326 *f0 = 1 - (trace_DFE_mtx[0] + std::sqrt(prev_cost_fnv_val)*trace_DFE_mtx[1]*
correction1_scale)/Umtx_loc.
cols;
1329 *f0 = 1 - (trace_DFE_mtx[0] + std::sqrt(prev_cost_fnv_val)*(trace_DFE_mtx[1]*correction1_scale + trace_DFE_mtx[2]*
correction2_scale))/Umtx_loc.
cols;
1332 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1339 for (
int idx=0; idx<parameter_num_loc; idx++) {
1342 grad[idx] = -trace_DFE_mtx[3*(idx+1)]/Umtx_loc.
cols;
1345 grad[idx] = -(trace_DFE_mtx[3*(idx+1)] + std::sqrt(prev_cost_fnv_val)*trace_DFE_mtx[3*(idx+1)+1]*correction1_scale)/Umtx_loc.
cols;
1348 grad[idx] = -(trace_DFE_mtx[3*(idx+1)] + std::sqrt(prev_cost_fnv_val)*(trace_DFE_mtx[3*(idx+1)+1]*correction1_scale + trace_DFE_mtx[3*(idx+1)+2]*
correction2_scale))/Umtx_loc.
cols;
1351 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1373 tbb::tick_count t0_CPU = tbb::tick_count::now();
1379 static tbb::enumerable_thread_specific<std::vector<Matrix>> combined_result_tls;
1380 std::vector<Matrix>& combined_result = combined_result_tls.local();
1382 Matrix& matrix_new = combined_result[0];
1394 auto calculate_gradient_component = [&](
int idx) {
1396 Matrix& deriv_mtx = combined_result[
static_cast<size_t>(idx) + 1];
1403 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*deriv_tmp[1]*correction1_scale - 1.0);
1408 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*(deriv_tmp[1]*correction1_scale + deriv_tmp[2]*
correction2_scale) - 1.0);
1412 double d = 1.0/deriv_mtx.
cols;
1414 grad_comp = -2.0*d*d*trace_tmp[0].real*deriv_tmp.
real-2.0*d*d*trace_tmp[0].imag*deriv_tmp.
imag;
1419 double d = 1.0/deriv_mtx.
cols;
1420 grad_comp = -2.0*d*d* (trace_tmp[0].real*deriv_tmp[0].real+trace_tmp[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*correction1_scale*(trace_tmp[1].real*deriv_tmp[1].real+trace_tmp[1].imag*deriv_tmp[1].imag));
1425 double d = 1.0/deriv_mtx.
cols;
1426 grad_comp = -2.0*d*d* (trace_tmp[0].real*deriv_tmp[0].real+trace_tmp[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*(correction1_scale*(trace_tmp[1].real*deriv_tmp[1].real+trace_tmp[1].imag*deriv_tmp[1].imag) + correction2_scale*(trace_tmp[2].
real*deriv_tmp[2].
real+trace_tmp[2].imag*deriv_tmp[2].imag)));
1444 double d = deriv_mtx.
cols;
1446 grad_comp = -2.0/d/(d+1)*trace_tmp[0].
real*deriv_tmp.
real-2.0/d/(d+1)*trace_tmp[0].imag*deriv_tmp.
imag;
1450 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1454 grad[idx] = grad_comp;
1457 if ( parallel == 0 ) {
1458 for (
int idx=0; idx<parameter_num_loc; ++idx) {
1459 calculate_gradient_component(idx);
1463 int work_batch = 10;
1464 tbb::parallel_for( tbb::blocked_range<int>(0,parameter_num_loc,work_batch), [&](tbb::blocked_range<int> r) {
1465 for (
int idx=r.begin(); idx<r.end(); ++idx) {
1466 calculate_gradient_component(idx);
1473 std::stringstream sstream;
1474 sstream << *f0 << std::endl;
1475 instance->
print(sstream, 5);
1529 static tbb::enumerable_thread_specific<std::vector<Matrix>> combined_result_tls;
1530 std::vector<Matrix>& combined_result = combined_result_tls.local();
1532 combined_result[0].copy_to(Umtx);
1533 Umtx_deriv.resize(combined_result.size() - 1);
1534 for (
size_t idx = 1; idx < combined_result.size(); ++idx) {
1535 combined_result[idx].copy_to(Umtx_deriv[idx - 1]);
1581 std::stringstream sstream;
1582 sstream <<
"Optimization_Interface::set_cost_function_variant: Cost function variant set to " <<
cost_fnc << std::endl;
1688 std::string error(
"Optimization_Interface::set_optimizer: unimplemented optimization algorithm");
1797 std::string error(
"Optimization_Interface::set_trace_offset: trace offset must be smaller or equal to the difference of the rows and columns in the input unitary.");
1806 std::stringstream sstream;
1807 sstream <<
"Optimization_Interface::set_trace_offset: trace offset set to " <<
trace_offset << std::endl;
1816 Optimization_Interface::upload_Umtx_to_DFE() {
optimization_aglorithms alg
The optimization algorithm to be used in the optimization.
bool adaptive_eta
logical variable indicating whether adaptive learning reate is used in the ADAM algorithm ...
Header file of single-precision complex array storage with automatic and thread safe reference counti...
Header file for a class containing basic methods for the decomposition process.
void set_osr_params(std::vector< std::vector< int >> use_cuts_in, int osr_rank_in, bool use_softmax_in)
int id
unique id indentifying the instance of the class
void export_current_cost_fnc(double current_minimum)
Call to print out into a file the current cost function and the second Rényi entropy on the subsyste...
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
Class to store single-precision real arrays and properties.
int get_num_iters()
Get the number of processed iterations during the optimization process.
void set_optimizer(optimization_aglorithms alg_in)
Call to set the optimizer engine to be used in solving the optimization problem.
void solve_layer_optimization_problem_AGENTS(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the AGENT algorithm.
Matrix get_Umtx()
Call to retrive a pointer to the unitary to be transformed.
void set_custom_gate_structure(Gates_block *gate_structure_in)
Call to set custom layers to the gate structure that are intended to be used in the subdecomposition...
int init_groq_sv_lib(const int reserved_device_num, int initialize_id_in)
Call to allocated Groq cards for calculations.
std::map< int, int > identical_blocks
A map of <int n: int num> indicating that how many identical successive blocks should be used in the ...
Matrix_real get_cost_function_with_correction(const Matrix &matrix, int qbit_num, int trace_offset=0)
Call co calculate the cost function of the optimization process, and the first correction to the cost...
void add_gate(Gate *gate)
Append a general gate to the list of gates.
int stride
The column stride of the array. (The array elements in one row are a_0, a_1, ... a_{cols-1}, 0, 0, 0, 0. The number of zeros is stride-cols)
Matrix to_float64() const
Convert to double precision.
static void optimization_problem_combined_unitary(Matrix_real parameters, void *void_instance, Matrix &Umtx, std::vector< Matrix > &Umtx_deriv)
Call to calculate both the effect of the circuit on th eunitary and it's gradient componets...
double correction1_scale
prefactor of the single-bitflip errors in the cost function. (see Eq. (21) in arXiv:2210.09191)
bool use_float
Selects float32 circuit application for parameter/unitary/state data.
double get_correction2_scale()
Call to get the prefactor of the two-bitflip errors in the cost function.
cost_function_type cost_fnc
The chosen variant of the cost function.
Matrix get_deriv_sum_of_squares(Matrix &matrix)
void add_u1(int target_qbit)
Append a U1 gate to the list of gates.
Matrix_real_float optimized_parameters_mtx_float
Float32 optimized parameters used by the hot gate-application path.
void release_gates()
Call to release the stored gates.
int get_accelerator_num()
Get the number of accelerators to be reserved on DFEs on users demand.
std::vector< std::vector< int > > use_cuts
cuts used for OSR entanglement cost function
double optimization_problem(double *parameters)
Evaluate the optimization problem of the optimization.
double get_osr_entanglement_test(Matrix &matrix, std::vector< std::vector< int >> &use_cuts, int rank=-1, bool use_softmax=false)
void solve_layer_optimization_problem_GRAD_DESCEND(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the GRAD_DESCEND (line search in the direct...
void set_trace_offset(int trace_offset_in)
Set the trace offset used in the evaluation of the cost function.
double prev_cost_fnv_val
the previous value of the cost funtion to be used to evaluate bitflip errors in the cost funtion (see...
std::atomic< int > number_of_iters
number of iterations
int trace_offset
The offset in the first columns from which the "trace" is calculated. In this case Tr(A) = sum_(i-off...
double calculate_cost_function(Matrix &matrix_new, Matrix *ret_temp=NULL)
Calculate the current cost function value from an already transformed matrix.
std::map< int, int > max_layer_num
A map of <int n: int num> indicating that how many layers should be used in the subdecomposition proc...
void set_random_shift_count_max(int random_shift_count_max_in)
Call to set the maximal number of parameter randomization tries to escape a local minimum...
void increment_num_iters(int delta=1)
Atomically increment the tracked number of optimization iterations.
scalar * get_data() const
Call to get the pointer to the stored data.
virtual double optimization_problem_non_static(Matrix_real parameters, void *void_instance)
The optimization problem of the final optimization.
double correction2_scale
prefactor of the double-bitflip errors in the cost function. (see Eq. (21) in arXiv:2210.09191)
cost_function_type get_cost_function_variant()
Call to get the variant of the cost function used in the calculations.
int get_trace_offset()
Get the trace ffset used in the evaluation of the cost function.
void init_dfe_lib_and_upload(const int accelerator_num, int qbit_num, int initialize_id_in, Matrix &input)
Initialize the DFE library if needed and upload the input matrix while holding the writer lock...
void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the gates stored in the block of gates.
int max_outer_iterations
Maximal number of iterations allowed in the optimization process.
Matrix_real get_cost_function_with_correction2(const Matrix &matrix, int qbit_num, int trace_offset=0)
Call co calculate the cost function of the optimization process, and the first correction to the cost...
int osr_rank
rank used for OSR entanglement cost function
optimization_aglorithms
implemented optimization strategies
int LAPACKE_dgesv(int matrix_layout, int n, int nrhs, double *a, int lda, int *ipiv, double *b, int ldb)
bool use_softmax
logical variable indicating whether to use softmax or average in the OSR entanglement cost function ...
std::string project_name
the name of the project
void set_max_inner_iterations(int max_inner_iterations_in)
Call to set the maximal number of iterations for which an optimization engine tries to solve the opti...
void solve_layer_optimization_problem_BAYES_AGENTS(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via Bayes & Agents algorithm.
gate_type type
The type of the operation (see enumeration gate_type)
QGD_Complex16 get_trace(Matrix &matrix)
Call to calculate the real and imaginary parts of the trace.
double get_infidelity(Matrix &matrix)
Call to calculate infidelity.
double get_second_Renyi_entropy(Matrix_real ¶meters_mtx, Matrix &input_state, matrix_base< int > &qbit_list)
Call to evaluate the seconf Rényi entropy.
int accelerator_num
number of utilized accelerators
int rows
The number of rows.
int cols
The number of columns.
Matrix get_deriv_osr_entanglement(Matrix &matrix, std::vector< std::vector< int >> &use_cuts, int rank=-1, bool use_softmax=false)
Matrix_float Umtx_float
Float32 copy of the unitary used when config["use_float"] is true.
virtual void add_finalyzing_layer()
Call to add further layer to the gate structure used in the subdecomposition.
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
void combine(Gates_block *op_block)
Call to append the gates of an gate block to the current block.
double randomization_rate
randomization rate
std::map< int, int > iteration_loops
A map of <int n: int num> indicating the number of iteration in each step of the decomposition.
double real_trace_conj_dot(Matrix &A, Matrix &B)
void randomize_parameters(Matrix_real &input, Matrix_real &output, const double f0)
Call to randomize the parameter.
virtual void apply_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel=0) override
Call to apply the gate on the input array/matrix Gates_block*input.
void solve_layer_optimization_problem_BFGS2(int num_of_parameters, Matrix_real solution_guess)
Call to solve layer by layer the optimization problem via BBFG algorithm.
Structure type representing complex numbers in the SQUANDER package.
double CPU_time
time spent on optimization
A class containing basic methods for the decomposition process.
double circuit_simulation_time
Time spent on circuit simulation/cost function evaluation.
decomposed_matrix
the unitary matrix from the result object
void copy_to(Matrix_real &target) const
Copy the matrix to a reusable double-precision target matrix.
int Power_of_2(int n)
Calculates the n-th power of 2.
void solve_layer_optimization_problem_BFGS(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via BBFG algorithm.
Double-precision complex matrix (float64).
Matrix get_trace_with_correction(Matrix &matrix, int qbit_num)
Call co calculate the Hilbert Schmidt testof the optimization process, and the first correction to th...
void copy_to(matrix_base< scalar > &target) const
Copy the current matrix storage into a reusable target matrix.
double get_previous_cost_function_value()
Call to retrieve the previous value of the cost funtion to be used to evaluate bitflip errors in the ...
void calc_decomposition_error(Matrix &decomposed_matrix)
Calculate the error of the decomposition according to the spectral norm of , where is the unitary pr...
int size() const
Call to get the number of the allocated elements.
double get_cost_function(const Matrix &matrix, int trace_offset=0)
Call co calculate the cost function during the final optimization process.
Gates_block()
Default constructor of the class.
cost_function_type
Type definition of the different types of the cost function.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
int get_initialize_id()
Call to get the identification number of the inititalization of the library.
Single-precision complex matrix (float32).
guess_type
Type definition of the types of the initial guess.
Fixed point data related to a gate operation.
static void optimization_problem_combined(Matrix_real parameters, void *void_instance, double *f0, Matrix_real &grad)
Call to calculate both the cost function and the its gradient components.
std::map< std::string, Config_Element > config
config metadata utilized during the optimization
void solve_layer_optimization_problem_ADAM(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via ADAM algorithm.
void unload_dfe_lib()
Call to unload the DFE libarary and release the allocated devices.
double get_cost_function_sum_of_squares(Matrix &matrix)
Optimization_Interface & operator=(const Optimization_Interface &other)
Copy assignment operator.
static void optimization_problem_grad(Matrix_real parameters, void *void_instance, Matrix_real &grad)
Calculate the derivative of the cost function with respect to the free parameters.
int parameter_num
the number of free parameters of the operation
void solve_layer_optimization_problem(int num_of_parameters, Matrix_real solution_guess)
Call to solve layer by layer the optimization problem via calling one of the implemented algorithms...
Header file for the paralleized calculation of the cost function of the final optimization problem (s...
void solve_layer_optimization_problem_GRAD_DESCEND_PARAMETER_SHIFT_RULE(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the GRAD_DESCEND_PARAMETER_SHIFT_RULE algor...
volatile double current_minimum
The current minimum of the optimization problem.
void solve_optimization_problem(double *solution_guess, int solution_guess_num)
This method can be used to solve the main optimization problem which is devidid into sub-layer optimi...
Matrix Umtx
The unitary to be decomposed.
virtual ~Optimization_Interface()
Destructor of the class.
double get_correction1_scale()
Call to get the prefactor of the single-bitflip errors in the cost function.
Header file for a class ???
int calcqgdKernelDFE(size_t rows, size_t cols, DFEgate_kernel_type *gates, int gatesNum, int gateSetNum, int traceOffset, double *trace)
Call to execute the calculation on the reserved DFE engines.
void solve_layer_optimization_problem_COSINE(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the COSINE algorithm.
static std::map< int, int > max_layer_num_def
A map of <int n: int num> indicating that how many layers should be used in the subdecomposition proc...
double real
the real part of a complex number
void final_optimization()
final optimization procedure improving the accuracy of the decompositin when all the qubits were alre...
Matrix_float get_Umtx_float()
Return the float32 unitary copy used by float execution.
int qbit_num
number of qubits spanning the matrix of the operation
bool optimize_layer_num
logical value. Set true to optimize the minimum number of gate layers required in the decomposition...
int get_qbit_num()
Call to get the number of qubits composing the unitary.
bool check_optimization_solution()
check_optimization_solution
double decomposition_error
error of the final decomposition
int max_inner_iterations
the maximal number of iterations for which an optimization engine tries to solve the optimization pro...
void solve_layer_optimization_problem_AGENTS_COMBINED(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the AGENT COMBINED algorithm.
int random_shift_count_max
the maximal number of parameter randomization tries to escape a local minimum.
virtual std::vector< Matrix > apply_to_combined(Matrix_real ¶meters_mtx, Matrix &input, int parallel) override
Combined forward + derivative application with shared precomputed trig cache.
Optimization_Interface()
Nullary constructor of the class.
void solve_layer_optimization_problem_ADAM_BATCHED(int num_of_parameters, Matrix_real &solution_guess_)
Call to solve layer by layer the optimization problem via batched ADAM algorithm. ...
Matrix_real optimized_parameters_mtx
The optimized parameters for the gates.
int get_parallel_configuration()
Get the parallel configuration from the config.
void set_cost_function_variant(cost_function_type variant)
Call to set the variant of the cost function used in the calculations.
Matrix get_trace_with_correction2(Matrix &matrix, int qbit_num)
Call co calculate the Hilbert Schmidt testof the optimization process, and the first correction to th...
int get_parameter_num() override
Call to get the number of free parameters.
double radius
parameter to contron the radius of parameter randomization around the curren tminimum ...
bool get_use_float() const
True when config["use_float"] requests float32 circuit execution.
Matrix_real optimization_problem_batched(std::vector< Matrix_real > ¶meters_vec)
The cost function of the optimization with batched input (implemented only for the Frobenius norm cos...
double global_target_minimum
The global target minimum of the optimization problem.
Class to store data of complex arrays and its properties.
double get_hilbert_schmidt_test(Matrix &matrix)
Call co calculate the cost function of the optimization process according to https://arxiv.org/pdf/2210.09191.pdf.
virtual void optimization_problem_combined_non_static(Matrix_real parameters, void *void_instance, double *f0, Matrix_real &grad)
Call to calculate both the cost function and the its gradient components.
void solve_layer_optimization_problem_BAYES_OPT(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via Bayes algorithm.
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()
double imag
the imaginary part of a complex number