diff --git a/coreblas/compute/core_ipiv_to_perm.c b/coreblas/compute/core_ipiv_to_perm.c
index 6c19272b3eaec960eb457fc40e9ba77f06b24075..9b2b53ceedec775158a9e5ce192a7abdd7120896 100644
--- a/coreblas/compute/core_ipiv_to_perm.c
+++ b/coreblas/compute/core_ipiv_to_perm.c
@@ -11,7 +11,8 @@
  *
  * @version 1.3.0
  * @author Mathieu Faverge
- * @date 2024-02-18
+ * @author Matteo Marcos
+ * @date 2025-03-24
  */
 #include "coreblas.h"
 
@@ -44,6 +45,14 @@
  * @param[in] k
  *          The number of elements in ipiv. k >= 0.
  *
+ * @param[in] K1
+ *          The first element of IPIV for which an interchange will
+ *          be done.
+ *
+ * @param[in] K2
+ *          The last element of ipiv for which an interchange will
+ *          be done.
+ *
  * @param[in] ipiv
  *          The pivot array of size n. This is a (m0+1)-based indices array to follow
  *          the Fortran standard.
@@ -55,7 +64,7 @@
  *          The permutation array of the origin row indices (m0-based) of the [1,n] set of rows.
  *
  */
-void CORE_ipiv_to_perm( int m0, int m, int k, int *ipiv, int *perm, int *invp )
+void CORE_ipiv_to_perm( int m0, int m, int k, int K1, int K2, int *ipiv, int *perm, int *invp )
 {
     int i, j, ip;
     int i_1, ip_1;
@@ -66,6 +75,9 @@ void CORE_ipiv_to_perm( int m0, int m, int k, int *ipiv, int *perm, int *invp )
     }
 
     for(i = 0; i < k; i++) {
+        if ( ( i + m0 < K1 ) || ( i + m0 > K2 ) ) {
+            continue;
+        }
         ip = ipiv[i]-1;
         assert( ip - m0 >= i );
 
diff --git a/coreblas/include/coreblas.h b/coreblas/include/coreblas.h
index c72530c108bf89bae0a3456b7365d7e43605deec..623dcd541b974e25477560fa03dfbfb2dedfcb8e 100644
--- a/coreblas/include/coreblas.h
+++ b/coreblas/include/coreblas.h
@@ -18,7 +18,8 @@
  * @author Guillaume Sylvand
  * @author Mathieu Faverge
  * @author Raphael Boucherie
- * @date 2024-03-14
+ * @author Matteo Marcos
+ * @date 2025-03-24
  *
  */
 #ifndef _coreblas_h_
@@ -94,7 +95,7 @@ void __coreblas_kernel_trace( const char *func, ... );
 
 #endif
 
-void CORE_ipiv_to_perm( int m0, int m, int k, int *ipiv, int *perm, int *invp );
+void CORE_ipiv_to_perm( int m0, int m, int k, int K1, int K2, int *ipiv, int *perm, int *invp );
 
 END_C_DECLS
 
diff --git a/include/chameleon/tasks.h b/include/chameleon/tasks.h
index 1e5e242b274612406036f7f63cd73e82365be8a7..7ba9ee093056b21f3d3c8aa975dc304043a8d3a7 100644
--- a/include/chameleon/tasks.h
+++ b/include/chameleon/tasks.h
@@ -17,7 +17,8 @@
  * @author Florent Pruvost
  * @author Matthieu Kuhn
  * @author Alycia Lisito
- * @date 2024-09-06
+ * @author Matteo Marcos
+ * @date 2025-03-24
  *
  */
 #ifndef _chameleon_tasks_h_
@@ -172,7 +173,7 @@ void INSERT_TASK_ipiv_init   ( const RUNTIME_option_t *options,
 void INSERT_TASK_ipiv_reducek( const RUNTIME_option_t *options,
                                CHAM_ipiv_t *ws, int k, int h, int rank );
 void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
-                               int m0, int m, int k,
+                               int m0, int m, int k, int K1, int K2,
                                const CHAM_ipiv_t *ipivdesc, int ipivk );
 
 #include "chameleon/tasks_z.h"
diff --git a/runtime/openmp/codelets/codelet_ipiv.c b/runtime/openmp/codelets/codelet_ipiv.c
index c21d13280ea0d316f5cc5d1799345ae0e8a4bbb8..ccc7e8f46ea496f30d00d81dd0f418ba07fdd175 100644
--- a/runtime/openmp/codelets/codelet_ipiv.c
+++ b/runtime/openmp/codelets/codelet_ipiv.c
@@ -13,7 +13,8 @@
  * @author Mathieu Faverge
  * @author Matthieu Kuhn
  * @author Alycia Lisito
- * @date 2024-08-29
+ * @author Matteo Marcos
+ * @date 2025-03-24
  *
  */
 #include "chameleon_openmp.h"
@@ -28,6 +29,14 @@ void INSERT_TASK_ipiv_init( const RUNTIME_option_t *options,
     (void)ipiv;
 }
 
+void INSERT_TASK_ipiv_init_data( const RUNTIME_option_t *options,
+                                 CHAM_ipiv_t *ipiv )
+{
+    assert( 0 );
+    (void)options;
+    (void)ipiv;
+}
+
 void INSERT_TASK_ipiv_reducek( const RUNTIME_option_t *options,
                                CHAM_ipiv_t *ipiv, int k, int h, int rank )
 {
@@ -40,7 +49,7 @@ void INSERT_TASK_ipiv_reducek( const RUNTIME_option_t *options,
 }
 
 void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
-                               int m0, int m, int k,
+                               int m0, int m, int k, int K1, int K2,
                                const CHAM_ipiv_t *ipivdesc, int ipivk )
 {
     int *ipiv = NULL; // get pointer from ipivdesc
@@ -49,9 +58,11 @@ void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
 
 #pragma omp task firstprivate( m0, m, k ) depend( in:ipiv[0] ) depend( inout:perm[0] ) depend( inout:invp[0] )
     {
-        CORE_ipiv_to_perm( m0, m, k, ipiv, perm, invp );
+        CORE_ipiv_to_perm( m0, m, k, 1, m, ipiv, perm, invp );
     }
 
     (void)options;
+    (void)K1;
+    (void)K2;
     (void)ipivk;
 }
diff --git a/runtime/parsec/codelets/codelet_ipiv.c b/runtime/parsec/codelets/codelet_ipiv.c
index b6d582e5ac8514525665adebd27b9459a9076005..2145e00b3575d7de659f28422064616815acd22a 100644
--- a/runtime/parsec/codelets/codelet_ipiv.c
+++ b/runtime/parsec/codelets/codelet_ipiv.c
@@ -13,7 +13,8 @@
  * @author Mathieu Faverge
  * @author Matthieu Kuhn
  * @author Alycia Lisito
- * @date 2024-08-29
+ * @author Matteo Marcos
+ * @date 2025-03-24
  *
  */
 #include "chameleon_parsec.h"
@@ -28,6 +29,14 @@ void INSERT_TASK_ipiv_init( const RUNTIME_option_t *options,
     (void)ipiv;
 }
 
+void INSERT_TASK_ipiv_init_data( const RUNTIME_option_t *options,
+                                 CHAM_ipiv_t *ipiv )
+{
+    assert( 0 );
+    (void)options;
+    (void)ipiv;
+}
+
 void INSERT_TASK_ipiv_reducek( const RUNTIME_option_t *options,
                                CHAM_ipiv_t *ipiv, int k, int h, int rank )
 {
@@ -49,14 +58,14 @@ CORE_ipiv_to_perm_parsec( parsec_execution_stream_t *context,
     parsec_dtd_unpack_args(
         this_task, &m0, &m, &k, &ipiv, &perm, &invp );
 
-    CORE_ipiv_to_perm( m0, m, k, ipiv, perm, invp );
+    CORE_ipiv_to_perm( m0, m, k, 1, m, ipiv, perm, invp );
 
     (void)context;
     return PARSEC_HOOK_RETURN_DONE;
 }
 
 void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
-                               int m0, int m, int k,
+                               int m0, int m, int k, int K1, int K2,
                                const CHAM_ipiv_t *ipivdesc, int ipivk )
 {
     parsec_taskpool_t* PARSEC_dtd_taskpool = (parsec_taskpool_t *)(options->sequence->schedopt);
@@ -70,4 +79,7 @@ void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
         PASSED_BY_REF, RUNTIME_perm_getaddr( ipivdesc, ipivk ), chameleon_parsec_get_arena_index_perm( ipivdesc ) | OUTPUT,
         PASSED_BY_REF, RUNTIME_invp_getaddr( ipivdesc, ipivk ), chameleon_parsec_get_arena_index_invp( ipivdesc ) | OUTPUT,
         PARSEC_DTD_ARG_END );
+
+    (void)K1;
+    (void)K2;
 }
diff --git a/runtime/quark/codelets/codelet_ipiv.c b/runtime/quark/codelets/codelet_ipiv.c
index 8075d0f8a43fc8fe2498cafdb39ae034483aa5d2..bf0846d3dfe9d6043162827a4d0a3eab9414caed 100644
--- a/runtime/quark/codelets/codelet_ipiv.c
+++ b/runtime/quark/codelets/codelet_ipiv.c
@@ -13,7 +13,8 @@
  * @author Mathieu Faverge
  * @author Matthieu Kuhn
  * @author Alycia Lisito
- * @date 2024-08-29
+ * @author Matteo Marcos
+ * @date 2025-03-24
  *
  */
 #include "chameleon_quark.h"
@@ -28,6 +29,14 @@ void INSERT_TASK_ipiv_init( const RUNTIME_option_t *options,
     (void)ipiv;
 }
 
+void INSERT_TASK_ipiv_init_data( const RUNTIME_option_t *options,
+                                 CHAM_ipiv_t            *ipiv )
+{
+    assert( 0 );
+    (void)options;
+    (void)ipiv;
+}
+
 void INSERT_TASK_ipiv_reducek( const RUNTIME_option_t *options,
                                CHAM_ipiv_t *ipiv, int k, int h, int rank )
 {
@@ -47,11 +56,11 @@ CORE_ipiv_to_perm_quark( Quark *quark )
 
     quark_unpack_args_6( quark, m0, m, k, ipiv, perm, invp );
 
-    CORE_ipiv_to_perm( m0, m, k, ipiv, perm, invp );
+    CORE_ipiv_to_perm( m0, m, k, 1, m, ipiv, perm, invp );
 }
 
 void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
-                               int m0, int m, int k,
+                               int m0, int m, int k, int K1, int K2,
                                const CHAM_ipiv_t *ipivdesc, int ipivk )
 {
     quark_option_t *opt = (quark_option_t*)(options->schedopt);
@@ -65,4 +74,7 @@ void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
         sizeof(int*), RUNTIME_perm_getaddr( ipivdesc, ipivk ), OUTPUT,
         sizeof(int*), RUNTIME_invp_getaddr( ipivdesc, ipivk ), OUTPUT,
         0 );
+
+    (void)K1;
+    (void)K2;
 }
diff --git a/runtime/starpu/codelets/codelet_ipiv.c b/runtime/starpu/codelets/codelet_ipiv.c
index 4498c63f3cbaba8655c740f98f7bdc4cc5fea974..7d7045edc9d70710f74deee861b436b745b974a4 100644
--- a/runtime/starpu/codelets/codelet_ipiv.c
+++ b/runtime/starpu/codelets/codelet_ipiv.c
@@ -13,7 +13,8 @@
  * @author Mathieu Faverge
  * @author Matthieu Kuhn
  * @author Alycia Lisito
- * @date 2024-09-17
+ * @author Matteo Marcos
+ * @date 2025-03-24
  *
  */
 #include "chameleon_starpu_internal.h"
@@ -86,16 +87,16 @@ void INSERT_TASK_ipiv_reducek( const RUNTIME_option_t *options,
 #if !defined(CHAMELEON_SIMULATION)
 static void cl_ipiv_to_perm_cpu_func( void *descr[], void *cl_arg )
 {
-    int m0, m, k;
+    int  m0, m, k, K1, K2;
     int *ipiv, *perm, *invp;
 
-    starpu_codelet_unpack_args( cl_arg, &m0, &m, &k );
+    starpu_codelet_unpack_args( cl_arg, &m0, &m, &k, &K1, &K2 );
 
     ipiv = (int*)STARPU_VECTOR_GET_PTR(descr[0]);
     perm = (int*)STARPU_VECTOR_GET_PTR(descr[1]);
     invp = (int*)STARPU_VECTOR_GET_PTR(descr[2]);
 
-    CORE_ipiv_to_perm( m0, m, k, ipiv, perm, invp );
+    CORE_ipiv_to_perm( m0, m, k, K1, K2, ipiv, perm, invp );
 }
 #endif /* !defined(CHAMELEON_SIMULATION) */
 
@@ -115,7 +116,7 @@ static struct starpu_codelet cl_ipiv_to_perm = {
 };
 
 void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
-                               int m0, int m, int k,
+                               int m0, int m, int k, int K1, int K2,
                                const CHAM_ipiv_t *ipivdesc, int ipivk )
 {
     struct starpu_codelet *codelet = &cl_ipiv_to_perm;
@@ -125,6 +126,8 @@ void INSERT_TASK_ipiv_to_perm( const RUNTIME_option_t *options,
         STARPU_VALUE,             &m0,  sizeof(int),
         STARPU_VALUE,             &m,   sizeof(int),
         STARPU_VALUE,             &k,   sizeof(int),
+        STARPU_VALUE,             &K1,  sizeof(int),
+        STARPU_VALUE,             &K2,  sizeof(int),
         STARPU_R,                 RUNTIME_ipiv_getaddr( ipivdesc, ipivk ),
         STARPU_W,                 RUNTIME_perm_getaddr( ipivdesc, ipivk ),
         STARPU_W,                 RUNTIME_invp_getaddr( ipivdesc, ipivk ),