diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index 54d82cc997e423cd27abd7be4334450d0e951ae1..ae8360dd7cc93d7ee9ba33e27ee897772e145e6c 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -7181,8 +7181,8 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx
     bool isIntra1 = candIdx1 >= GEO_MAX_NUM_UNI_CANDS;
     if (isIntra0)
     {
-      PU::getGeoIntraMPMs(pu, pu.intraMPM, splitDir, g_geoTmShape[0][g_geoParams[pu.geoSplitDir][0]]);
-      pu.intraDir[0] = pu.intraMPM[candIdx0 - GEO_MAX_NUM_UNI_CANDS];
+      PU::getGeoIntraMPMs(pu, pcIntraPred->m_intraMPM, splitDir, g_geoTmShape[0][g_geoParams[pu.geoSplitDir][0]]);
+      pu.intraDir[0] = pcIntraPred->m_intraMPM[candIdx0 - GEO_MAX_NUM_UNI_CANDS];
       pcIntraPred->initIntraPatternChType(cu, pu.Y());
       pcIntraPred->predIntraAng(COMPONENT_Y, tmpGeoBuf0.Y(), pu);
       if (isChromaEnabled(pu.chromaFormat))
@@ -7266,8 +7266,8 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx
 
     if (isIntra1)
     {
-      PU::getGeoIntraMPMs(pu, pu.intraMPM+GEO_MAX_NUM_INTRA_CANDS, splitDir, g_geoTmShape[1][g_geoParams[pu.geoSplitDir][0]]);
-      pu.intraDir[0] = pu.intraMPM[candIdx1 - GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS];
+      PU::getGeoIntraMPMs(pu, pcIntraPred->m_intraMPM+GEO_MAX_NUM_INTRA_CANDS, splitDir, g_geoTmShape[1][g_geoParams[pu.geoSplitDir][0]]);
+      pu.intraDir[0] = pcIntraPred->m_intraMPM[candIdx1 - GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS];
       pcIntraPred->initIntraPatternChType(cu, pu.Y());
       pcIntraPred->predIntraAng(COMPONENT_Y, tmpGeoBuf1.Y(), pu);
       if (isChromaEnabled(pu.chromaFormat))
@@ -7408,8 +7408,8 @@ void InterPrediction::motionCompensationIbcGpm( CodingUnit &cu, MergeCtx &ibcGpm
     bool isIntra1 = candIdx1 >= IBC_GPM_MAX_NUM_UNI_CANDS;
     if (isIntra0)
     {
-      PU::getGeoIntraMPMs(pu, pu.intraMPM, splitDir, g_geoTmShape[0][g_geoParams[pu.ibcGpmSplitDir][0]]);
-      pu.intraDir[0] = pu.intraMPM[candIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS];
+      PU::getGeoIntraMPMs(pu, pcIntraPred->m_intraMPM, splitDir, g_geoTmShape[0][g_geoParams[pu.ibcGpmSplitDir][0]]);
+      pu.intraDir[0] = pcIntraPred->m_intraMPM[candIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS];
       pcIntraPred->initIntraPatternChType(cu, pu.Y());
       pcIntraPred->predIntraAng(COMPONENT_Y, tmpGeoBuf0.Y(), pu);
 #if !JVET_AE0169_GPM_IBC_IBC
@@ -7418,7 +7418,7 @@ void InterPrediction::motionCompensationIbcGpm( CodingUnit &cu, MergeCtx &ibcGpm
 #endif
       if (chroma)
       {
-        pu.intraDir[1] = pu.intraMPM[candIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS];
+        pu.intraDir[1] = pcIntraPred->m_intraMPM[candIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS];
         pcIntraPred->initIntraPatternChType(cu, pu.Cb());
         pcIntraPred->predIntraAng(COMPONENT_Cb, tmpGeoBuf0.Cb(), pu);
         pcIntraPred->initIntraPatternChType(cu, pu.Cr());
@@ -7450,8 +7450,8 @@ void InterPrediction::motionCompensationIbcGpm( CodingUnit &cu, MergeCtx &ibcGpm
 
     if (isIntra1)
     {
-      PU::getGeoIntraMPMs(pu, pu.intraMPM+GEO_MAX_NUM_INTRA_CANDS, splitDir, g_geoTmShape[1][g_geoParams[pu.ibcGpmSplitDir][0]]);
-      pu.intraDir[0] = pu.intraMPM[candIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS];
+      PU::getGeoIntraMPMs(pu, pcIntraPred->m_intraMPM+GEO_MAX_NUM_INTRA_CANDS, splitDir, g_geoTmShape[1][g_geoParams[pu.ibcGpmSplitDir][0]]);
+      pu.intraDir[0] = pcIntraPred->m_intraMPM[candIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS];
       pcIntraPred->initIntraPatternChType(cu, pu.Y());
       pcIntraPred->predIntraAng(COMPONENT_Y, tmpGeoBuf1.Y(), pu);
 #if !JVET_AE0169_GPM_IBC_IBC
@@ -7460,7 +7460,7 @@ void InterPrediction::motionCompensationIbcGpm( CodingUnit &cu, MergeCtx &ibcGpm
 #endif
       if (chroma)
       {
-        pu.intraDir[1] = pu.intraMPM[candIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS];
+        pu.intraDir[1] = pcIntraPred->m_intraMPM[candIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS];
         pcIntraPred->initIntraPatternChType(cu, pu.Cb());
         pcIntraPred->predIntraAng(COMPONENT_Cb, tmpGeoBuf1.Cb(), pu);
         pcIntraPred->initIntraPatternChType(cu, pu.Cr());
diff --git a/source/Lib/CommonLib/IntraPrediction.h b/source/Lib/CommonLib/IntraPrediction.h
index e8c1f5b1b21c52b5ada437788db0619a7acd6d33..03f5a2dc1bff92b50df251a2fbd5e11212567ea1 100644
--- a/source/Lib/CommonLib/IntraPrediction.h
+++ b/source/Lib/CommonLib/IntraPrediction.h
@@ -238,6 +238,10 @@ public:
   Pel m_cr[CCCM_REF_SAMPLES_MAX];
 #endif
 
+#if SECONDARY_MPM
+  uint8_t m_intraMPM[NUM_MOST_PROBABLE_MODES];
+  uint8_t m_intraNonMPM[NUM_NON_MPM_MODES];
+#endif
 protected:
 #if JVET_AC0094_REF_SAMPLES_OPT
   Pel m_refBuffer[MAX_NUM_COMPONENT][NUM_PRED_BUF][((MAX_CU_SIZE << 3) + 1 + MAX_REF_LINE_IDX) * 2];
diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp
index 15abf62ce32131d4e9e8ac4e93feba2567b0a87f..b49b880a75e9ff92f0cafcf049cf09e7c88fad70 100644
--- a/source/Lib/CommonLib/Unit.cpp
+++ b/source/Lib/CommonLib/Unit.cpp
@@ -863,10 +863,6 @@ PredictionUnit::PredictionUnit(const ChromaFormat _chromaFormat, const Area &_ar
 void PredictionUnit::initData()
 {
   // intra data - need this default initialization for PCM
-#if SECONDARY_MPM
-  ::memset(intraMPM, 0, sizeof(intraMPM));
-  ::memset(intraNonMPM, 0, sizeof(intraNonMPM));
-#endif
 
   intraDir[0] = DC_IDX;
   intraDir[1] = PLANAR_IDX;
@@ -887,9 +883,10 @@ void PredictionUnit::initData()
   parseLumaMode = false;
   candId = -1;
   parseChromaMode = false;
+#endif
   mpmFlag = false;
   ipredIdx = -1;
-#endif
+  secondMpmFlag = false;
 #if JVET_Z0050_CCLM_SLOPE
   cclmOffsets = {};
 #endif
@@ -1053,10 +1050,6 @@ void PredictionUnit::initData()
 
 PredictionUnit& PredictionUnit::operator=(const IntraPredictionData& predData)
 {
-#if SECONDARY_MPM
-  ::memcpy(intraMPM, predData.intraMPM, sizeof(intraMPM));
-  ::memcpy(intraNonMPM, predData.intraNonMPM, sizeof(intraNonMPM));
-#endif
 
   for (uint32_t i = 0; i < MAX_NUM_CHANNEL_TYPE; i++)
   {
@@ -1074,9 +1067,10 @@ PredictionUnit& PredictionUnit::operator=(const IntraPredictionData& predData)
   parseLumaMode = predData.parseLumaMode;
   candId = predData.candId;
   parseChromaMode = predData.parseChromaMode;
+#endif
   mpmFlag = predData.mpmFlag;
   ipredIdx = predData.ipredIdx;
-#endif
+  secondMpmFlag = predData.secondMpmFlag;
 #if JVET_Z0050_CCLM_SLOPE
   cclmOffsets = predData.cclmOffsets;
 #endif
@@ -1248,10 +1242,6 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData)
 
 PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other )
 {
-#if SECONDARY_MPM
-  ::memcpy(intraMPM, other.intraMPM, sizeof(intraMPM));
-  ::memcpy(intraNonMPM, other.intraNonMPM, sizeof(intraNonMPM));
-#endif
 
   for( uint32_t i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
   {
@@ -1310,9 +1300,10 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other )
   parseLumaMode = other.parseLumaMode;
   candId = other.candId;
   parseChromaMode = other.parseChromaMode;
+#endif
   mpmFlag = other.mpmFlag;
   ipredIdx = other.ipredIdx;
-#endif
+  secondMpmFlag = other.secondMpmFlag;
   geoSplitDir  = other.geoSplitDir;
 #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING
   geoSyntaxMode = other.geoSyntaxMode;
diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h
index 376801a39aa0ebacc3e0b6b7d9958da764583b75..e0e1b8fc204320be440c4b0353efca0fb5329ba3 100644
--- a/source/Lib/CommonLib/Unit.h
+++ b/source/Lib/CommonLib/Unit.h
@@ -507,14 +507,10 @@ struct IntraPredictionData
   bool      parseLumaMode = false;
   int8_t    candId = -1;
   bool      parseChromaMode = false;
+#endif
   bool      mpmFlag = false;
   int8_t    ipredIdx = -1;
   bool      secondMpmFlag = false;
-#endif
-#if SECONDARY_MPM
-  uint8_t intraMPM[NUM_MOST_PROBABLE_MODES];
-  uint8_t intraNonMPM[NUM_NON_MPM_MODES];
-#endif
   uint8_t  intraDir[MAX_NUM_CHANNEL_TYPE];
 #if JVET_AB0155_SGPM
   uint8_t intraDir1[MAX_NUM_CHANNEL_TYPE];
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index fc19c7176a830a2ac17db32e11cc2c73f4c02cdc..35372eb75f5655b6391557379338165d633a09d2 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -21141,7 +21141,7 @@ void PU::getGeoMergeCandidates( const PredictionUnit &pu, MergeCtx& geoMrgCtx )
 #endif
 }
 
-void PU::spanGeoMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const uint8_t splitDir, const uint8_t candIdx0, const uint8_t candIdx1)
+void PU::spanGeoMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const uint8_t splitDir, const uint8_t candIdx0, const uint8_t candIdx1, const uint8_t *intraMPM)
 {
   pu.geoSplitDir  = splitDir;
   pu.geoMergeIdx0 = candIdx0;
@@ -21301,8 +21301,8 @@ void PU::spanGeoMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const uint8
     const unsigned mask = ~(scale - 1);
     uint8_t* ii = ib.buf;
     int geoIpm[3];
-    geoIpm[0] = isIntra0 ? pu.intraMPM[candIdx0 - GEO_MAX_NUM_UNI_CANDS] : -1;
-    geoIpm[1] = isIntra1 ? pu.intraMPM[candIdx1 - GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS] : -1;
+    geoIpm[0] = isIntra0 ? intraMPM[candIdx0 - GEO_MAX_NUM_UNI_CANDS] : -1;
+    geoIpm[1] = isIntra1 ? intraMPM[candIdx1 - GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS] : -1;
     geoIpm[2] = (isIntra0 && isIntra1) ? ((candIdx1 < candIdx0) ? geoIpm[1] : geoIpm[0]) : isIntra0 ? geoIpm[0] : geoIpm[1];
 
     for (int y = 0; y < mb.height; y++)
@@ -21593,10 +21593,10 @@ void PU::spanGeoIBCMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx)
 #if TM_MRG
 #if JVET_AA0058_GPM_ADAPTIVE_BLENDING
 #if JVET_AE0046_BI_GPM
-void PU::spanGeoMMVDMotionInfo(PredictionUnit& pu, MergeCtx& geoMrgCtx, MergeCtx& geoTmMrgCtx0, MergeCtx& geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx,
+void PU::spanGeoMMVDMotionInfo(PredictionUnit& pu, MergeCtx& geoMrgCtx, MergeCtx& geoTmMrgCtx0, MergeCtx& geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx, const uint8_t *intraMPM,
   const bool dmvrPart0, const bool dmvrPart1, Mv* bdofSubPuMvOffsetPart0, Mv* bdofSubPuMvOffsetPart1)
 #else
-void PU::spanGeoMMVDMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx, MergeCtx &geoTmMrgCtx0, MergeCtx &geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx)
+void PU::spanGeoMMVDMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx, MergeCtx &geoTmMrgCtx0, MergeCtx &geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx, const uint8_t *intraMPM)
 #endif
 #else
 void PU::spanGeoMMVDMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx, MergeCtx &geoTmMrgCtx0, MergeCtx &geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1)
@@ -22103,8 +22103,8 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u
     const unsigned mask = ~(scale - 1);
     uint8_t* ii = ib.buf;
     int geoIpm[3];
-    geoIpm[0] = isIntra0 ? pu.intraMPM[mergeIdx0 - GEO_MAX_NUM_UNI_CANDS] : -1;
-    geoIpm[1] = isIntra1 ? pu.intraMPM[mergeIdx1 - GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS] : -1;
+    geoIpm[0] = isIntra0 ? intraMPM[mergeIdx0 - GEO_MAX_NUM_UNI_CANDS] : -1;
+    geoIpm[1] = isIntra1 ? intraMPM[mergeIdx1 - GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS] : -1;
     geoIpm[2] = (isIntra0 && isIntra1) ? ((mergeIdx1 < mergeIdx0) ? geoIpm[1] : geoIpm[0]) : isIntra0 ? geoIpm[0] : geoIpm[1];
 
     for (int y = 0; y < mb.height; y++)
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index 570efa69459f8c1f3c598dfe51fc0f078ca15b19..d43dea94ba657785ede09ebaefa641ce5d92f674 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -657,15 +657,15 @@ namespace PU
 #else
   void getGeoMergeCandidates          (const PredictionUnit &pu, MergeCtx &GeoMrgCtx);
 #endif
-  void spanGeoMotionInfo              (      PredictionUnit &pu, MergeCtx &GeoMrgCtx, const uint8_t splitDir, const uint8_t candIdx0, const uint8_t candIdx1);
+  void spanGeoMotionInfo              (      PredictionUnit &pu, MergeCtx &geoMrgCtx, const uint8_t splitDir, const uint8_t candIdx0, const uint8_t candIdx1, const uint8_t *intraMPM);
 #if JVET_W0097_GPM_MMVD_TM
 #if TM_MRG
 #if JVET_AA0058_GPM_ADAPTIVE_BLENDING
 #if JVET_AE0046_BI_GPM
-  void spanGeoMMVDMotionInfo(PredictionUnit& pu, MergeCtx& geoMrgCtx, MergeCtx& geoTmMrgCtx0, MergeCtx& geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx,
+  void spanGeoMMVDMotionInfo(PredictionUnit& pu, MergeCtx& geoMrgCtx, MergeCtx& geoTmMrgCtx0, MergeCtx& geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx, const uint8_t *intraMPM,
     const bool dmvrPart0 = false, const bool dmvrPart1 = false, Mv* bdofSubPuMvOffsetPart0 = nullptr, Mv* bdofSubPuMvOffsetPart1 = nullptr);
 #else
-  void spanGeoMMVDMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx, MergeCtx &geoTmMrgCtx0, MergeCtx &geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx);
+  void spanGeoMMVDMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx, MergeCtx &geoTmMrgCtx0, MergeCtx &geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx, const uint8_t *intraMPM);
 #endif
 #else
   void spanGeoMMVDMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx, MergeCtx &geoTmMrgCtx0, MergeCtx &geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1);
diff --git a/source/Lib/CommonLib/dtrace_blockstatistics.cpp b/source/Lib/CommonLib/dtrace_blockstatistics.cpp
index bca6939fd1c12bc5f36208988d1a163fd5078cca..300680ffcecbc9df2cea21dc39911ec65707da60 100644
--- a/source/Lib/CommonLib/dtrace_blockstatistics.cpp
+++ b/source/Lib/CommonLib/dtrace_blockstatistics.cpp
@@ -822,9 +822,8 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
 #if JVET_Y0065_GPM_INTRA
                 if (candIdx0 >= GEO_MAX_NUM_UNI_CANDS)
                 {
-                  const int intraDir = tmpPu.intraMPM[candIdx0 - GEO_MAX_NUM_UNI_CANDS];
                   const int geoPartIdx = 0;
-                  DTRACE_POLYGON_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu.slice->getPOC(), geoPartitions[geoPartIdx], GetBlockStatisticName(BlockStatistic::GPMIntra), intraDir);
+                  DTRACE_POLYGON_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu.slice->getPOC(), geoPartitions[geoPartIdx], GetBlockStatisticName(BlockStatistic::GPMIntra), candIdx0);
                 }
                 else
                 {
@@ -859,9 +858,8 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
 #if JVET_Y0065_GPM_INTRA
                 if (candIdx1 >= GEO_MAX_NUM_UNI_CANDS)
                 {
-                  const int intraDir = tmpPu.intraMPM[candIdx1 - GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS];
                   const int geoPartIdx = 0;
-                  DTRACE_POLYGON_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu.slice->getPOC(), geoPartitions[geoPartIdx], GetBlockStatisticName(BlockStatistic::GPMIntra), intraDir);
+                  DTRACE_POLYGON_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, cu.slice->getPOC(), geoPartitions[geoPartIdx], GetBlockStatisticName(BlockStatistic::GPMIntra), candIdx1);
                 }
                 else
                 {
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 09c3b5540659e0549f27a7faa10a52685693860a..fdf9c1e7875842a1b7c454a90341aebba4381e53 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -1997,10 +1997,7 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
 
   PredictionUnit *pu = cu.firstPU;
 
-#if SECONDARY_MPM
-  uint8_t* mpmPred = pu->intraMPM;  // mpm_idx / rem_intra_luma_pred_mode
-  uint8_t* nonMpmPred = pu->intraNonMPM;
-#else
+#if !SECONDARY_MPM
   unsigned int mpmPred[NUM_MOST_PROBABLE_MODES];  // mpm_idx / rem_intra_luma_pred_mode
 #endif
 
@@ -2059,11 +2056,8 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
           ipredIdx += m_BinDecoder.decodeBinEP();
         }
       }
-#if ENABLE_DIMD || JVET_W0123_TIMD_FUSION
       pu->secondMpmFlag = false;
       pu->ipredIdx = ipredIdx;
-#endif
-      pu->intraDir[0] = mpmPred[ipredIdx];
     }
     else
     {
@@ -2100,21 +2094,17 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
 #else
         int idx = m_BinDecoder.decodeBinsEP( 4 ) + NUM_PRIMARY_MOST_PROBABLE_MODES;
 #endif
-        ipredMode = mpmPred[idx];
-        pu->secondMpmFlag = true;
         pu->ipredIdx = idx;
 #else
-        ipredMode = mpmPred[m_BinDecoder.decodeBinsEP( 4 ) + NUM_PRIMARY_MOST_PROBABLE_MODES];
+        pu->ipredIdx = m_BinDecoder.decodeBinsEP( 4 ) + NUM_PRIMARY_MOST_PROBABLE_MODES;
 #endif
+        pu->secondMpmFlag = true;
       }
       else
       {
         xReadTruncBinCode( ipredMode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES );
-#if ENABLE_DIMD || JVET_W0123_TIMD_FUSION
         pu->secondMpmFlag = false;
         pu->ipredIdx = ipredMode;
-#endif
-        ipredMode = nonMpmPred[ipredMode];
       }
 #else
       xReadTruncBinCode( ipredMode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES );
@@ -2156,7 +2146,7 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
 #if ENABLE_DIMD || JVET_W0123_TIMD_FUSION
     DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) predIdx=%d mpm=%d secondmpm=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pu->ipredIdx, pu->mpmFlag, pu->secondMpmFlag);
 #else
-    DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pu->intraDir[0] );
+    DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) predIdx=%d mpm=%d secondmpm=%d \n", k, pu->lumaPos().x, pu->lumaPos().y, pu->ipredIdx, pu->mpmFlag, pu->secondMpmFlag);
 #endif
     pu = pu->next;
   }
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index 4dd461bc01f2b96f028a4c4225a14c5ae2b066ef..f8da73d99fc30175d15f536e9a89ea077172e1c1 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -381,8 +381,8 @@ void DecCu::decompressCtu( CodingStructure& cs, const UnitArea& ctuArea )
         if (currCU.firstPU->parseLumaMode)
         {
 #if SECONDARY_MPM
-          uint8_t* mpmPred = currCU.firstPU->intraMPM;  // mpm_idx / rem_intra_luma_pred_mode
-          uint8_t* nonMpmPred = currCU.firstPU->intraNonMPM;
+          uint8_t* mpmPred = m_pcIntraPred->m_intraMPM;  // mpm_idx / rem_intra_luma_pred_mode
+          uint8_t* nonMpmPred = m_pcIntraPred->m_intraNonMPM;
 #if JVET_AD0085_MPM_SORTING
           if (PU::allowMPMSorted(*currCU.firstPU) && !(currCU.firstPU->mpmFlag && currCU.firstPU->ipredIdx == 0))
           {
@@ -1517,6 +1517,7 @@ void DecCu::xReconInter(CodingUnit &cu)
 #if JVET_AA0058_GPM_ADAPTIVE_BLENDING
                               , cu.firstPU->geoBldIdx
 #endif
+                              , m_pcIntraPred->m_intraMPM
 #if JVET_AE0046_BI_GPM
                                , cu.firstPU->gpmDmvrRefinePart0
                                , cu.firstPU->gpmDmvrRefinePart1
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 2c41f84ac057e6c145149a8c425f0ddac8ba09f2..b7beadd2cb323d44137d55b490ba9db0a9dc189f 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -5336,9 +5336,9 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
     if (!lambdaCanBePredicted)
     {
 #if JVET_AB0082
-      READ_CODE(10, uiCode, "lambda");
+      READ_CODE(10, uiCode, "Lambda");
 #else
-      READ_CODE(9, uiCode, "lambda");
+      READ_CODE(9, uiCode, "Lambda");
 #endif
       pcSlice->setCostForARMC((uint32_t)uiCode);
     }
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index ea50513475b3c3cbad1e7cf1ed4e0c97a50d5f22..88a3a7aab911a312f5a80c26bac5a6cfc7653d6e 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -1517,52 +1517,24 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
   {
     return;
   }
-#endif
-#if SECONDARY_MPM
-  const int numMPMs = NUM_PRIMARY_MOST_PROBABLE_MODES;
-#else
-  const int numMPMs   = NUM_MOST_PROBABLE_MODES;
 #endif
   const int numBlocks = CU::getNumPUs( cu );
 #if !SECONDARY_MPM
   unsigned  mpmPreds   [4][numMPMs];
 #endif
-  unsigned  mpm_idxs    [4];
-  unsigned  ipredModes [4];
 
   const PredictionUnit* pu = cu.firstPU;
 
   // prev_intra_luma_pred_flag
   for( int k = 0; k < numBlocks; k++ )
   {
-#if !SECONDARY_MPM
-    unsigned*  mpmPred   = mpmPreds[k];
-#endif
-    unsigned&  mpm_idx    = mpm_idxs[k];
-    unsigned&  ipredMode = ipredModes[k];
-#if SECONDARY_MPM
-    const uint8_t* mpmPred = cu.firstPU->intraMPM;
-#else
-    PU::getIntraMPMs( *pu, mpmPred );
-#endif
-
-    ipredMode = pu->intraDir[0];
-    mpm_idx    = numMPMs;
-    for( unsigned idx = 0; idx < numMPMs; idx++ )
-    {
-      if( ipredMode == mpmPred[idx] )
-      {
-        mpm_idx = idx;
-        break;
-      }
-    }
     if ( pu->multiRefIdx )
     {
-      CHECK(mpm_idx >= numMPMs, "use of non-MPM");
+      CHECK(!pu->mpmFlag, "use of non-MPM");
     }
     else
     {
-      m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
+      m_BinEncoder.encodeBin(pu->mpmFlag, Ctx::IntraLumaMpmFlag());
     }
 
     pu = pu->next;
@@ -1573,13 +1545,9 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
   // mpm_idx / rem_intra_luma_pred_mode
   for( int k = 0; k < numBlocks; k++ )
   {
-    const unsigned& mpm_idx = mpm_idxs[k];
-#if ENABLE_TRACING && (ENABLE_DIMD || JVET_W0123_TIMD_FUSION)
-    int pred_idx = -1;
-    bool secondMpmFlag = false;
-#endif
-    if( mpm_idx < numMPMs )
+    if(pu->mpmFlag)
     {
+      const unsigned mpm_idx = pu->ipredIdx;
       {
         unsigned ctx = (pu->cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
 #if SECONDARY_MPM
@@ -1611,38 +1579,15 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
           m_BinEncoder.encodeBinEP(mpm_idx > 4);
         }
       }
-#if ENABLE_TRACING && (ENABLE_DIMD || JVET_W0123_TIMD_FUSION)
-      pred_idx = mpm_idx;
-#endif
     }
     else
     {
-#if !SECONDARY_MPM
-      unsigned* mpmPred   = mpmPreds[k];
-#endif
-      unsigned  ipredMode = ipredModes[k];
-
-      // sorting of MPMs
-#if !SECONDARY_MPM
-      std::sort( mpmPred, mpmPred + numMPMs );
-#endif
 
       {        
 #if SECONDARY_MPM
-        const uint8_t* secondaryMPMs = cu.firstPU->intraMPM + NUM_PRIMARY_MOST_PROBABLE_MODES;
-        uint8_t secondaryMPMIdx = NUM_SECONDARY_MOST_PROBABLE_MODES;
-
-        for (unsigned idx = 0; idx < NUM_SECONDARY_MOST_PROBABLE_MODES; idx++)
-        {
-          if (ipredMode == secondaryMPMs[idx])
-          {
-            secondaryMPMIdx = idx;
-            break;
-          }
-        }
-
-        if( secondaryMPMIdx < NUM_SECONDARY_MOST_PROBABLE_MODES )
+        if( pu->secondMpmFlag)
         {
+          uint8_t secondaryMPMIdx = pu->ipredIdx;
           m_BinEncoder.encodeBin(1, Ctx::IntraLumaSecondMpmFlag());
 #if JVET_AD0085_MPM_SORTING
           if (cu.cs->sps->getUseMpmSorting())
@@ -1668,31 +1613,15 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
           m_BinEncoder.encodeBinsEP( secondaryMPMIdx, 4);
 #if JVET_AD0085_MPM_SORTING
           }
-#endif
-#if ENABLE_TRACING && (ENABLE_DIMD || JVET_W0123_TIMD_FUSION)
-          pred_idx = secondaryMPMIdx + NUM_PRIMARY_MOST_PROBABLE_MODES;
-          secondMpmFlag = true;
 #endif
         }
         else
         {
           m_BinEncoder.encodeBin(0, Ctx::IntraLumaSecondMpmFlag());
                  
-          unsigned nonMPMIdx = NUM_NON_MPM_MODES;
-
-          for (unsigned idx = 0; idx < NUM_NON_MPM_MODES; idx++)
-          {
-            if (ipredMode == cu.firstPU->intraNonMPM[idx])
-            {
-              nonMPMIdx = idx;
-              break;
-            }
-          }
+          unsigned nonMPMIdx = pu->ipredIdx;
 
           xWriteTruncBinCode( nonMPMIdx, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
-#if ENABLE_TRACING && (ENABLE_DIMD || JVET_W0123_TIMD_FUSION)
-          pred_idx = nonMPMIdx;
-#endif
         }
 #else
         std::sort(mpmPred, mpmPred + numMPMs);
@@ -1712,7 +1641,7 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
     }
 
 #if JVET_AC0105_DIRECTIONAL_PLANAR
-    if (CU::isDirectionalPlanarAvailable(cu) && mpm_idx == 0)
+    if (CU::isDirectionalPlanarAvailable(cu) && pu->mpmFlag && pu->ipredIdx == 0)
     {
       m_BinEncoder.encodeBin(cu.plIdx > 0, Ctx::IntraLumaPlanarFlag(2));
       if (cu.plIdx)
@@ -1724,7 +1653,7 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
 #endif
 
 #if ENABLE_DIMD || JVET_W0123_TIMD_FUSION
-    DTRACE(g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) predIdx=%d mpm=%d secondmpm=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pred_idx, mpm_idx < numMPMs, secondMpmFlag);
+    DTRACE(g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) predIdx=%d mpm=%d secondmpm=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pu->ipredIdx + (!pu->mpmFlag && pu->secondMpmFlag ? NUM_PRIMARY_MOST_PROBABLE_MODES: 0), pu->mpmFlag, pu->secondMpmFlag);
 #else
     DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pu->intraDir[0] );
 #endif
@@ -1804,41 +1733,19 @@ void CABACWriter::intra_luma_pred_mode( const PredictionUnit& pu )
   }
 #endif
   // prev_intra_luma_pred_flag
-#if SECONDARY_MPM
-  const int numMPMs = NUM_PRIMARY_MOST_PROBABLE_MODES;
-  const uint8_t* mpmPred = pu.intraMPM;
-#else
-  const int numMPMs  = NUM_MOST_PROBABLE_MODES;
-  unsigned  mpmPred[numMPMs];
-#endif
-
-#if !SECONDARY_MPM
-  PU::getIntraMPMs( pu, mpmPred );
-#endif
-
-  unsigned ipredMode = pu.intraDir[0];
-  unsigned mpm_idx = numMPMs;
-
-  for( int idx = 0; idx < numMPMs; idx++ )
-  {
-    if( ipredMode == mpmPred[idx] )
-    {
-      mpm_idx = idx;
-      break;
-    }
-  }
   if ( pu.multiRefIdx )
   {
-    CHECK(mpm_idx >= numMPMs, "use of non-MPM");
+    CHECK(!pu.mpmFlag, "use of non-MPM");
   }
   else
   {
-    m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
+    m_BinEncoder.encodeBin(pu.mpmFlag, Ctx::IntraLumaMpmFlag());
   }
 
   // mpm_idx / rem_intra_luma_pred_mode
-  if( mpm_idx < numMPMs )
+  if (pu.mpmFlag)
   {
+    unsigned mpm_idx = pu.ipredIdx;
     {
       unsigned ctx = (pu.cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
 #if SECONDARY_MPM
@@ -1875,20 +1782,9 @@ void CABACWriter::intra_luma_pred_mode( const PredictionUnit& pu )
 #endif
     { 
 #if SECONDARY_MPM
-      auto secondMpmPred = mpmPred + NUM_PRIMARY_MOST_PROBABLE_MODES;
-      unsigned   secondMpmIdx = NUM_SECONDARY_MOST_PROBABLE_MODES;
-
-      for (unsigned idx = 0; idx < NUM_SECONDARY_MOST_PROBABLE_MODES; idx++)
-      {
-        if (ipredMode == secondMpmPred[idx])
-        {
-          secondMpmIdx = idx;
-          break;
-        }
-      }
-
-      if (secondMpmIdx < NUM_SECONDARY_MOST_PROBABLE_MODES)
+      if (pu.secondMpmFlag)
       {
+        unsigned secondMpmIdx = pu.ipredIdx;
         m_BinEncoder.encodeBin(1, Ctx::IntraLumaSecondMpmFlag());
 #if JVET_AD0085_MPM_SORTING
         if (pu.cs->sps->getUseMpmSorting())
@@ -1920,28 +1816,12 @@ void CABACWriter::intra_luma_pred_mode( const PredictionUnit& pu )
       {
         m_BinEncoder.encodeBin(0, Ctx::IntraLumaSecondMpmFlag());
                 
-        unsigned   non_mpm_idx = NUM_NON_MPM_MODES;
-        for (unsigned idx = 0; idx < NUM_NON_MPM_MODES; idx++)
-        {
-          if (ipredMode == pu.intraNonMPM[idx])
-          {
-            non_mpm_idx = idx;
-            break;
-          }
-        }
+        unsigned non_mpm_idx = pu.ipredIdx;
 
         xWriteTruncBinCode(non_mpm_idx, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
       }
 #else
-      std::sort(mpmPred, mpmPred + numMPMs);
-
-      for (int idx = numMPMs - 1; idx >= 0; idx--)
-      {
-        if (ipredMode > mpmPred[idx])
-        {
-          ipredMode--;
-        }
-      }
+      unsigned ipredMode = pu.intraDir[0];
 
       xWriteTruncBinCode(ipredMode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
 #endif
@@ -1949,7 +1829,7 @@ void CABACWriter::intra_luma_pred_mode( const PredictionUnit& pu )
   }
 
 #if JVET_AC0105_DIRECTIONAL_PLANAR
-  if (CU::isDirectionalPlanarAvailable(*pu.cu) && mpm_idx == 0)
+  if (CU::isDirectionalPlanarAvailable(*pu.cu) && pu.mpmFlag && pu.ipredIdx == 0)
   {
     m_BinEncoder.encodeBin(pu.cu->plIdx > 0, Ctx::IntraLumaPlanarFlag(2));
     if (pu.cu->plIdx)
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 999c0bf3a8fc9eb54f889eed59f78a3108005156..ea00ce1925704860cbb1d9c2ff906c8d7fdbae59 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -2528,7 +2528,7 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
 #if JVET_AD0085_MPM_SORTING
     if (PU::allowMPMSorted(pu))
     {
-      m_pcIntraSearch->getMpmListSize() = PU::getIntraMPMs(pu, m_pcIntraSearch->getMPMList(), m_pcIntraSearch->getNonMPMList()
+      m_pcIntraSearch->getMpmListSize() = PU::getIntraMPMs(pu, m_pcIntraSearch->m_intraMPM, m_pcIntraSearch->m_intraNonMPM
 #if JVET_AC0094_REF_SAMPLES_OPT
                                                          , true
 #endif
@@ -2538,7 +2538,7 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
     else
     {
 #endif
-    m_pcIntraSearch->getMpmListSize() = PU::getIntraMPMs(pu, m_pcIntraSearch->getMPMList(), m_pcIntraSearch->getNonMPMList()
+      m_pcIntraSearch->getMpmListSize() = PU::getIntraMPMs(pu, m_pcIntraSearch->m_intraMPM, m_pcIntraSearch->m_intraNonMPM
 #if JVET_AC0094_REF_SAMPLES_OPT
                                                          , false
 #endif
@@ -3000,6 +3000,10 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
             cu.colorTransform = false;
             foundZeroRootCbf = true;
           }
+          for (auto& pu : CU::traversePUs(cu))
+          {
+            m_pcIntraSearch->setLumaIntraPredIdx(pu);
+          }
 
           // Get total bits for current mode: encode CU
           m_CABACEstimator->resetBits();
@@ -7855,11 +7859,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct
       pu.gpmIntraFlag = pu.geoMergeIdx0 >= GEO_MAX_NUM_UNI_CANDS || pu.geoMergeIdx1 >= GEO_MAX_NUM_UNI_CANDS;
       if (pu.geoMergeIdx0 >= GEO_MAX_NUM_UNI_CANDS)
       {
-        memcpy(pu.intraMPM, geoIntraMPMList[pu.geoSplitDir][0], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
+        memcpy(m_pcIntraSearch->m_intraMPM, geoIntraMPMList[pu.geoSplitDir][0], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
       }
       if (pu.geoMergeIdx1 >= GEO_MAX_NUM_UNI_CANDS)
       {
-        memcpy(pu.intraMPM+GEO_MAX_NUM_INTRA_CANDS, geoIntraMPMList[pu.geoSplitDir][1], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
+        memcpy(m_pcIntraSearch->m_intraMPM +GEO_MAX_NUM_INTRA_CANDS, geoIntraMPMList[pu.geoSplitDir][1], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
       }
 #if ENABLE_DIMD
       cu.dimdMode = dimdMode;
@@ -7903,10 +7907,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct
       MergeCtx *mergeTmCtx1 = nullptr;
 #if JVET_AA0058_GPM_ADAPTIVE_BLENDING
 #if JVET_AE0046_BI_GPM
-      PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mergeTmCtx0, *mergeTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx, 
+      PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mergeTmCtx0, *mergeTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx, m_pcIntraSearch->m_intraMPM, 
         pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][pu.geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][pu.geoMergeIdx1] : nullptr);
 #else
-      PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mergeTmCtx0, *mergeTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx);
+      PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mergeTmCtx0, *mergeTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx, m_pcIntraSearch->m_intraMPM);
 #endif
 #else
       PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mergeTmCtx0, *mergeTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1);
@@ -9544,11 +9548,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct
         pu.gpmIntraFlag = pu.geoMergeIdx0 >= GEO_MAX_NUM_UNI_CANDS || pu.geoMergeIdx1 >= GEO_MAX_NUM_UNI_CANDS;
         if (pu.geoMergeIdx0 >= GEO_MAX_NUM_UNI_CANDS)
         {
-          memcpy(pu.intraMPM, geoIntraMPMList[pu.geoSplitDir][0], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
+          memcpy(m_pcIntraSearch->m_intraMPM, geoIntraMPMList[pu.geoSplitDir][0], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
         }
         if (pu.geoMergeIdx1 >= GEO_MAX_NUM_UNI_CANDS)
         {
-          memcpy(pu.intraMPM+GEO_MAX_NUM_INTRA_CANDS, geoIntraMPMList[pu.geoSplitDir][1], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
+          memcpy(m_pcIntraSearch->m_intraMPM +GEO_MAX_NUM_INTRA_CANDS, geoIntraMPMList[pu.geoSplitDir][1], sizeof(uint8_t)*GEO_MAX_NUM_INTRA_CANDS);
         }
 #if ENABLE_DIMD
         cu.dimdMode = dimdMode;
@@ -9657,10 +9661,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct
         Mv* bdofSubPuMvOffsetPart0 = pu.gpmDmvrRefinePart0 ? (pu.geoTmFlag0 ? m_mvBufEncBDOF4GPM[g_geoTmShape[0][g_geoParams[pu.geoSplitDir][0]]][pu.geoMergeIdx0] : m_mvBufEncBDOF4GPM[GEO_TM_OFF][pu.geoMergeIdx0]) : nullptr;
         Mv* bdofSubPuMvOffsetPart1 = pu.gpmDmvrRefinePart1 ? (pu.geoTmFlag1 ? m_mvBufEncBDOF4GPM[g_geoTmShape[1][g_geoParams[pu.geoSplitDir][0]]][pu.geoMergeIdx1] : m_mvBufEncBDOF4GPM[GEO_TM_OFF][pu.geoMergeIdx1]) : nullptr;
 
-        PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mrgTmCtx0, *mrgTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx,
+        PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mrgTmCtx0, *mrgTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx, m_pcIntraSearch->m_intraMPM,
           pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, bdofSubPuMvOffsetPart0, bdofSubPuMvOffsetPart1);
 #else
-        PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mrgTmCtx0, *mrgTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx);
+        PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mrgTmCtx0, *mrgTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx, m_pcIntraSearch->m_intraMPM);
 #endif
 #else
         PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], *mrgTmCtx0, *mrgTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1);
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index fa023dc880d7c402375ec99568fbd3d9ce792171..bdc601e79348983bb34e9499e6bffdf5ae9dc57e 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -714,10 +714,6 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
 
     CHECK(pu.cu != &cu, "PU is not contained in the CU");
 
-#if SECONDARY_MPM
-    std::memcpy( pu.intraMPM, m_mpmList, sizeof( pu.intraMPM ) );
-    std::memcpy( pu.intraNonMPM, m_nonMPMList, sizeof( pu.intraNonMPM ) );
-#endif
 
     //===== determine set of modes to be tested (using prediction signal only) =====
     int numModesAvailable = NUM_LUMA_MODE; // total number of Intra modes
@@ -1201,11 +1197,10 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
             pu.multiRefIdx    = 1;
 #if SECONDARY_MPM
             const int numMPMs = NUM_PRIMARY_MOST_PROBABLE_MODES;
-            uint8_t* multiRefMPM = m_mpmList;
 #else
             const int numMPMs = NUM_MOST_PROBABLE_MODES;
-            unsigned  multiRefMPM[numMPMs];
 #endif
+            uint8_t* multiRefMPM = m_intraMPM;
 #if !SECONDARY_MPM
             PU::getIntraMPMs(pu, multiRefMPM);
 #endif
@@ -1893,7 +1888,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
           {
 
 #if SECONDARY_MPM
-            auto uiPreds = m_mpmList;
+            auto uiPreds = m_intraMPM;
 #else
             const int numMPMs = NUM_MOST_PROBABLE_MODES;
             unsigned  uiPreds[numMPMs];
@@ -6988,6 +6983,7 @@ void IntraSearch::xEncIntraHeader( CodingStructure &cs, Partitioner &partitioner
         m_CABACEstimator->pred_mode( cu );
       }
       m_CABACEstimator->bdpcm_mode( cu, COMPONENT_Y );
+      setLumaIntraPredIdx(pu);
       m_CABACEstimator->intra_luma_pred_mode( pu );
     }
   }
@@ -10682,6 +10678,7 @@ uint64_t IntraSearch::xFracModeBitsIntra(PredictionUnit &pu, const uint32_t &uiM
     if (!pu.ciipFlag)
 #endif
     {
+      setLumaIntraPredIdx(pu);
       m_CABACEstimator->intra_luma_pred_mode(pu);
     }
   }
@@ -11547,4 +11544,68 @@ void IntraSearch::xFinishISPModes()
     }
   }
 }
+void IntraSearch::setLumaIntraPredIdx(PredictionUnit& pu)
+{
+#if SECONDARY_MPM
+  const int numMPMs = NUM_PRIMARY_MOST_PROBABLE_MODES + NUM_SECONDARY_MOST_PROBABLE_MODES;
+#else
+  const int numMPMs = NUM_MOST_PROBABLE_MODES;
+#endif
+  int pred_idx = numMPMs;
+  for (int idx = 0; idx < numMPMs; idx++)
+  {
+    if (pu.intraDir[0] == m_intraMPM[idx])
+    {
+      pred_idx = idx;
+      break;
+    }
+  }
+#if SECONDARY_MPM
+  if (pred_idx < NUM_PRIMARY_MOST_PROBABLE_MODES)
+  {
+    pu.mpmFlag = true;
+    pu.secondMpmFlag = false;
+  }
+  else if (pred_idx < numMPMs)
+  {
+    pu.mpmFlag = false;
+    pu.secondMpmFlag = true;
+    pred_idx -= NUM_PRIMARY_MOST_PROBABLE_MODES;
+  }
+  else
+  {
+    pu.mpmFlag = false;
+    pu.secondMpmFlag = false;
+    pred_idx = NUM_NON_MPM_MODES;
+    for (int idx = 0; idx < NUM_NON_MPM_MODES; idx++)
+    {
+      if (pu.intraDir[0] == m_intraNonMPM[idx])
+      {
+        pred_idx = idx;
+        break;
+      }
+    }
+
+  }
+#else
+  if (mpm_idx < NUM_MOST_PROBABLE_MODES)
+  {
+    pu.mpmFlag = true;
+  }
+  else
+  {
+    std::sort(mpmPred, mpmPred + numMPMs);
+    int pred_idx = pu.intraDir[0];
+    for (int idx = numMPMs - 1; idx >= 0; idx--)
+    {
+      if (pred_idx > mpmPred[idx])
+      {
+        pred_idx--;
+      }
+    }
+    CHECK(pred_idx >= 64, "Incorrect mode");
+  }
+#endif
+  pu.ipredIdx = pred_idx;
+}
 
diff --git a/source/Lib/EncoderLib/IntraSearch.h b/source/Lib/EncoderLib/IntraSearch.h
index 3a0071622abff84e0f5f9d0fb09eb7a280b148de..863920d8eab361660c1c510b420c34f2887fc245 100644
--- a/source/Lib/EncoderLib/IntraSearch.h
+++ b/source/Lib/EncoderLib/IntraSearch.h
@@ -520,8 +520,6 @@ private:
   int                                                m_savedRdModeIdx;
 
 #if SECONDARY_MPM
-  uint8_t m_mpmList[NUM_MOST_PROBABLE_MODES];
-  uint8_t m_nonMPMList[NUM_NON_MPM_MODES];
   int m_mpmListSize;
 #endif
 
@@ -679,8 +677,6 @@ public:
 #endif
 
 #if SECONDARY_MPM
-  uint8_t* getMPMList()           { return m_mpmList; }
-  uint8_t* getNonMPMList()        { return m_nonMPMList; }
   int& getMpmListSize()           { return m_mpmListSize; }
 #endif
 #if JVET_AE0169_BIPREDICTIVE_IBC
@@ -689,6 +685,7 @@ public:
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
   double getBestIntraSADCost()    { return m_bestIntraSADCost; }
 #endif
+  void setLumaIntraPredIdx(PredictionUnit& pu);
 protected:
 
   // -------------------------------------------------------------------------------------------------------------------