#include "hip/hip_runtime.h"
/*
    -- MAGMA (version 2.6.2) --
       Univ. of Tennessee, Knoxville
       Univ. of California, Berkeley
       Univ. of Colorado, Denver
       @date March 2022

       @generated from magmablas_hip/ztrtri_lower_batched.hip.cpp, normal z -> c, Mon Mar 21 16:51:49 2022

       @author Peng Du
       @author Tingxing Dong
       @author Mark Gates
       @author Azzam Haidar
       
       This file implements lower case, and is called by ctrtri_kernel.cu.
       It's convenient to have separate files for lower & upper, to diff the sources.
*/

#include "magma_internal.h"

#define TRTRI_BATCHED
#include "ctrtri.hip.hpp"
#include "ctrtri_lower_device.hip.hpp"



/******************************************************************************/
__global__ void
ctrtri_diag_lower_kernel_batched(
    magma_diag_t diag, int n, magmaFloatComplex const * const * dA_array, int lda, magmaFloatComplex **dinvA_array)
{
    int batchid = blockIdx.z;
    ctrtri_diag_lower_device(diag, n, dA_array[batchid], lda, dinvA_array[batchid]);
}


/******************************************************************************/
__global__ void
triple_cgemm16_part1_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm16_part1_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm16_part2_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm16_part2_lower_device( n,  Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm32_part1_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm32_part1_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm32_part2_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm32_part2_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm64_part1_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm64_part1_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm64_part2_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm64_part2_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm_above64_part1_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm_above64_part1_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm_above64_part2_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm_above64_part2_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


/******************************************************************************/
__global__ void
triple_cgemm_above64_part3_lower_kernel_batched(
    int n, magmaFloatComplex const * const * Ain_array, int lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    int batchid = blockIdx.z;
    triple_cgemm_above64_part3_lower_device( n, Ain_array[batchid], lda, dinvA_array[batchid], jb, npages);
}


// =============================================================================
// vbatched kernels


/******************************************************************************/
__global__ void
ctrtri_diag_lower_kernel_vbatched(
    magma_diag_t diag, magma_int_t* n, magmaFloatComplex const * const * dA_array, magma_int_t* lda, magmaFloatComplex **dinvA_array)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return; 
    
    if(blockIdx.x >= magma_ceildiv(my_n, IB)) return;
    
    ctrtri_diag_lower_device(diag, my_n, dA_array[batchid], (int)lda[batchid], dinvA_array[batchid]);
}


// The kernels below have 3D grids
// grid.x and grid.y are independent from my_n
// only grid.y is dependent on my_n, so terminating thread blocks is based on blockIdx.y


/******************************************************************************/
__global__ void
triple_cgemm16_part1_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm16_part1_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm16_part2_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm16_part2_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm32_part1_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm32_part1_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm32_part2_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm32_part2_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm64_part1_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm64_part1_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm64_part2_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm64_part2_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm_above64_part1_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm_above64_part1_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm_above64_part2_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm_above64_part2_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}


/******************************************************************************/
__global__ void
triple_cgemm_above64_part3_lower_kernel_vbatched(
    magma_int_t* n, magmaFloatComplex const * const * Ain_array, magma_int_t* lda, magmaFloatComplex **dinvA_array, int jb, int npages)
{
    const int batchid = blockIdx.z;
    const int my_n = (int)n[batchid];
    if(my_n <= 0) return;
    
    const int my_npages = magma_ceildiv(my_n, jb*2);
    if(blockIdx.y >= my_npages*(jb/16) ) return;
    triple_cgemm_above64_part3_lower_device( my_n, Ain_array[batchid], (int)lda[batchid], dinvA_array[batchid], jb, my_npages);
}
