15
15
*
16
16
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
17
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ *ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
20
+ *INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
+ *BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ *DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23
+ *OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ *NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25
+ *EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
26
*
27
27
* Contributors:
28
28
* Implementation - Thien Nguyen;
@@ -223,7 +223,8 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::initialize(
223
223
// Note: If xacc::verbose is not set, we always set ExaTN logging level to
224
224
// 0.
225
225
exatn::resetClientLoggingLevel (xacc::verbose ? xacc::getLoggingLevel () : 0 );
226
- exatn::resetRuntimeLoggingLevel (xacc::verbose ? xacc::getLoggingLevel () : 0 );
226
+ exatn::resetRuntimeLoggingLevel (xacc::verbose ? xacc::getLoggingLevel ()
227
+ : 0 );
227
228
228
229
xacc::subscribeLoggingLevel ([](int level) {
229
230
exatn::resetClientLoggingLevel (xacc::verbose ? level : 0 );
@@ -250,11 +251,21 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::initialize(
250
251
251
252
// Default number of layers
252
253
m_layersReconstruct = 4 ;
253
- if (options.keyExists <int >(" reconstruct-layers" )) {
254
- m_layersReconstruct = options.get <int >(" reconstruct-layers" );
254
+ m_countByGates = false ;
255
+ m_layerTracker.clear ();
256
+ if (options.keyExists <int >(" reconstruct-gates" )) {
257
+ m_layersReconstruct = options.get <int >(" reconstruct-gates" );
258
+ xacc::info (" Reconstruct tensor network every " +
259
+ std::to_string (m_layersReconstruct) + " 2-body gates." );
260
+ m_countByGates = true ;
261
+ } else {
262
+ if (options.keyExists <int >(" reconstruct-layers" )) {
263
+ m_layersReconstruct = options.get <int >(" reconstruct-layers" );
264
+ xacc::info (" Reconstruct tensor network every " +
265
+ std::to_string (m_layersReconstruct) + " layers." );
266
+ }
255
267
}
256
- xacc::info (" Reconstruct tensor network every " +
257
- std::to_string (m_layersReconstruct) + " layers." );
268
+
258
269
m_reconstructTol = 1e-3 ;
259
270
m_maxBondDim = 512 ;
260
271
m_reconstructionFidelity = 1.0 ;
@@ -276,7 +287,7 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::initialize(
276
287
}
277
288
if (options.stringExists (" reconstruct-builder" )) {
278
289
m_reconstructBuilder = options.getString (" reconstruct-builder" );
279
- xacc::info (" Reconstruct with: " + m_reconstructBuilder + " builder." );
290
+ xacc::info (" Reconstruct with: " + m_reconstructBuilder + " builder." );
280
291
}
281
292
}
282
293
@@ -589,7 +600,7 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::appendGateTensor(
589
600
const xacc::Instruction &in_gateInstruction, GateParams &&... in_params) {
590
601
// Count gate layer if this is a multi-qubit gate.
591
602
if (in_gateInstruction.nRequiredBits () > 1 ) {
592
- ++m_layerCounter ;
603
+ updateLayerCounter (in_gateInstruction) ;
593
604
}
594
605
const auto gateName = GetGateName (GateType);
595
606
const GateInstanceIdentifier gateInstanceId (gateName, in_params...);
@@ -674,7 +685,7 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::reconstructCircuitTensor() {
674
685
if (m_layersReconstruct <= 0 ) {
675
686
return ;
676
687
}
677
- if (m_layerCounter > m_layersReconstruct) {
688
+ if (m_layerCounter >= m_layersReconstruct) {
678
689
xacc::info (" Reconstruct Tensor Expansion" );
679
690
auto target = std::make_shared<exatn::TensorExpansion>(m_tensorExpansion);
680
691
// List of Approximate tensors to delete:
@@ -685,18 +696,20 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::reconstructCircuitTensor() {
685
696
const std::vector<int > qubitTensorDim (m_buffer->size (), 2 );
686
697
auto rootTensor = std::make_shared<exatn::Tensor>(" ROOT" , qubitTensorDim);
687
698
auto &networkBuildFactory = *(exatn::numerics::NetworkBuildFactory::get ());
688
- auto builder = networkBuildFactory.createNetworkBuilderShared (m_reconstructBuilder);
699
+ auto builder =
700
+ networkBuildFactory.createNetworkBuilderShared (m_reconstructBuilder);
689
701
builder->setParameter (" max_bond_dim" , m_maxBondDim);
690
702
auto approximant = [&]() {
691
703
if (m_initReconstructionRandom || !m_previousOptExpansion) {
692
- auto approximantTensorNetwork = exatn::makeSharedTensorNetwork (" Approx" , rootTensor, *builder);
704
+ auto approximantTensorNetwork =
705
+ exatn::makeSharedTensorNetwork (" Approx" , rootTensor, *builder);
693
706
for (auto iter = approximantTensorNetwork->cbegin ();
694
707
iter != approximantTensorNetwork->cend (); ++iter) {
695
708
const auto &tensorName = iter->second .getTensor ()->getName ();
696
709
if (tensorName != " ROOT" ) {
697
710
auto tensor = iter->second .getTensor ();
698
- const bool created = exatn::createTensorSync (
699
- tensor, getExatnElementType ());
711
+ const bool created =
712
+ exatn::createTensorSync ( tensor, getExatnElementType ());
700
713
assert (created);
701
714
const bool initialized = exatn::initTensorRnd (tensor->getName ());
702
715
assert (initialized);
@@ -706,8 +719,10 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::reconstructCircuitTensor() {
706
719
}
707
720
}
708
721
approximantTensorNetwork->markOptimizableAllTensors ();
709
- auto approximant_expansion = std::make_shared<exatn::TensorExpansion>(" Approx" );
710
- approximant_expansion->appendComponent (approximantTensorNetwork, TNQVM_COMPLEX_TYPE{1.0 , 0.0 });
722
+ auto approximant_expansion =
723
+ std::make_shared<exatn::TensorExpansion>(" Approx" );
724
+ approximant_expansion->appendComponent (approximantTensorNetwork,
725
+ TNQVM_COMPLEX_TYPE{1.0 , 0.0 });
711
726
approximant_expansion->conjugate ();
712
727
return approximant_expansion;
713
728
} else {
@@ -729,7 +744,7 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::reconstructCircuitTensor() {
729
744
// Run the reconstructor:
730
745
bool reconstructSuccess = exatn::sync ();
731
746
assert (reconstructSuccess);
732
- // exatn::TensorNetworkReconstructor::resetDebugLevel(2); //debug
747
+ // exatn::TensorNetworkReconstructor::resetDebugLevel(2); //debug
733
748
reconstructor.resetLearningRate (1.0 );
734
749
double residual_norm, fidelity;
735
750
const auto startOpt = std::chrono::system_clock::now ();
@@ -878,7 +893,7 @@ const double ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::getExpectationValueZ(
878
893
assert (success);
879
894
// std::cout << "After renormalize:\n";
880
895
// ketvector.printIt();
881
-
896
+
882
897
exatn::TensorExpansion ketWithObs (ketvector, *m_obsTensorOperator);
883
898
// std::cout << "Tensor Expansion:\n";
884
899
// ketWithObs.printIt();
@@ -919,7 +934,8 @@ const double ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::getExpectationValueZ(
919
934
// std::cout << "Component coeff: " << component.coefficient << "\n";
920
935
const std::complex<double > renormalizedComponentExpVal =
921
936
tensor_body_val * component.coefficient ;
922
- // std::cout << "renormalizedComponentExpVal: " << renormalizedComponentExpVal << "\n";
937
+ // std::cout << "renormalizedComponentExpVal: " <<
938
+ // renormalizedComponentExpVal << "\n";
923
939
return renormalizedComponentExpVal.real ();
924
940
}
925
941
xacc::error (" Unable to map execution data for sub-composite: " +
@@ -944,9 +960,9 @@ ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::computeWaveFuncSlice(
944
960
const auto bitVal = in_bitString[i];
945
961
const std::string braQubitName = " QB" + std::to_string (i);
946
962
if (bitVal == 0 ) {
947
- const bool created = exatn::createTensor (
948
- in_processGroup, braQubitName, getExatnElementType () ,
949
- exatn::TensorShape{2 });
963
+ const bool created =
964
+ exatn::createTensor ( in_processGroup, braQubitName,
965
+ getExatnElementType (), exatn::TensorShape{2 });
950
966
assert (created);
951
967
// Bit = 0
952
968
const bool initialized = exatn::initTensorData (
@@ -955,9 +971,9 @@ ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::computeWaveFuncSlice(
955
971
assert (initialized);
956
972
pairings.emplace_back (std::make_pair (i, i + nbOpenLegs));
957
973
} else if (bitVal == 1 ) {
958
- const bool created = exatn::createTensor (
959
- in_processGroup, braQubitName, getExatnElementType () ,
960
- exatn::TensorShape{2 });
974
+ const bool created =
975
+ exatn::createTensor ( in_processGroup, braQubitName,
976
+ getExatnElementType (), exatn::TensorShape{2 });
961
977
assert (created);
962
978
// Bit = 1
963
979
const bool initialized = exatn::initTensorData (
@@ -967,9 +983,9 @@ ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::computeWaveFuncSlice(
967
983
pairings.emplace_back (std::make_pair (i, i + nbOpenLegs));
968
984
} else if (bitVal == -1 ) {
969
985
// Add an Id tensor
970
- const bool created = exatn::createTensor (
971
- in_processGroup, braQubitName, getExatnElementType (),
972
- exatn::TensorShape{2 , 2 });
986
+ const bool created = exatn::createTensor (in_processGroup, braQubitName,
987
+ getExatnElementType (),
988
+ exatn::TensorShape{2 , 2 });
973
989
assert (created);
974
990
const bool initialized = exatn::initTensorData (
975
991
braQubitName, std::vector<TNQVM_COMPLEX_TYPE>{
@@ -1018,5 +1034,31 @@ ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::computeWaveFuncSlice(
1018
1034
}
1019
1035
return waveFnSlice;
1020
1036
}
1037
+ template <typename TNQVM_COMPLEX_TYPE>
1038
+ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::updateLayerCounter(
1039
+ const xacc::Instruction &in_gateInstruction) {
1040
+ auto &gate = const_cast <xacc::Instruction &>(in_gateInstruction);
1041
+ assert (gate.bits ().size () == 2 );
1042
+ if (m_countByGates) {
1043
+ ++m_layerCounter;
1044
+ } else {
1045
+ bool canCombine = true ;
1046
+ const auto q1 = gate.bits ()[0 ];
1047
+ const auto q2 = gate.bits ()[1 ];
1048
+
1049
+ for (const auto & [bit1, bit2]: m_layerTracker) {
1050
+ if ((q1 == bit1 || q1 == bit2) || (q2 == bit1 || q2 == bit2)) {
1051
+ canCombine = false ;
1052
+ break ;
1053
+ }
1054
+ }
1055
+ if (canCombine) {
1056
+ m_layerTracker.emplace (std::make_pair (q1, q2));
1057
+ } else {
1058
+ ++m_layerCounter;
1059
+ m_layerTracker.clear ();
1060
+ }
1061
+ }
1062
+ }
1021
1063
} // end namespace tnqvm
1022
1064
#endif // TNQVM_HAS_EXATN
0 commit comments