/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/*** DO NOT EDIT THIS FILE DIRECTLY (use 'headers' to generate) ***/

#ifndef hypre_SEQ_BLOCK_MV_HEADER
#define hypre_SEQ_BLOCK_MV_HEADER

#include <HYPRE_config.h>
#include "_hypre_seq_mv.h"

#ifdef HYPRE_MIXED_PRECISION
#include "_hypre_seq_block_mv_mup_def.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

#ifndef hypre_DENSE_BLOCK_MATRIX_HEADER
#define hypre_DENSE_BLOCK_MATRIX_HEADER

/*--------------------------------------------------------------------------
 * Uniformly blocked dense matrix data structure
 *--------------------------------------------------------------------------*/

typedef struct hypre_DenseBlockMatrix_struct
{
   HYPRE_Int             row_major;          /* Flag indicating storage format (false: col major)*/
   HYPRE_Int             num_rows;           /* Number of rows of entire matrix */
   HYPRE_Int             num_cols;           /* Number of columns of entire matrix */
   HYPRE_Int             num_nonzeros;       /* Number of nonzero coefficients of entire matrix */
   HYPRE_Int             num_blocks;         /* Number of sub-matrices (blocks) */

   /* Local info for a individual block (sub-matrix) */
   HYPRE_Int             row_stride;         /* Stride for accessing row values */
   HYPRE_Int             col_stride;         /* Stride for accessing column values */
   HYPRE_Int             num_rows_block;     /* Number of rows per block */
   HYPRE_Int             num_cols_block;     /* Number of columns per block */
   HYPRE_Int             num_nonzeros_block; /* Number of nonzero coefficients per block */

   /* Matrix coefficients array */
   HYPRE_Int             owns_data;          /* Flag indicating ownership of the data array */
   HYPRE_Complex        *data;               /* Matrix coefficients */
   HYPRE_Complex       **data_aop;           /* Array of pointers to data */
   HYPRE_MemoryLocation  memory_location;    /* Memory location of data array */

#if defined(HYPRE_MIXED_PRECISION)
   HYPRE_Precision matrix_precision;
#endif
} hypre_DenseBlockMatrix;

/*--------------------------------------------------------------------------
 * Accessor functions for the uniform batched matrix structure
 *--------------------------------------------------------------------------*/

#define hypre_DenseBlockMatrixRowMajor(matrix)         ((matrix) -> row_major)
#define hypre_DenseBlockMatrixNumRows(matrix)          ((matrix) -> num_rows)
#define hypre_DenseBlockMatrixNumCols(matrix)          ((matrix) -> num_cols)
#define hypre_DenseBlockMatrixNumNonzeros(matrix)      ((matrix) -> num_nonzeros)
#define hypre_DenseBlockMatrixNumBlocks(matrix)        ((matrix) -> num_blocks)

#define hypre_DenseBlockMatrixRowStride(matrix)        ((matrix) -> row_stride)
#define hypre_DenseBlockMatrixColStride(matrix)        ((matrix) -> col_stride)
#define hypre_DenseBlockMatrixNumRowsBlock(matrix)     ((matrix) -> num_rows_block)
#define hypre_DenseBlockMatrixNumColsBlock(matrix)     ((matrix) -> num_cols_block)
#define hypre_DenseBlockMatrixNumNonzerosBlock(matrix) ((matrix) -> num_nonzeros_block)

#define hypre_DenseBlockMatrixOwnsData(matrix)         ((matrix) -> owns_data)
#define hypre_DenseBlockMatrixData(matrix)             ((matrix) -> data)
#define hypre_DenseBlockMatrixDataAOP(matrix)          ((matrix) -> data_aop)
#define hypre_DenseBlockMatrixMemoryLocation(matrix)   ((matrix) -> memory_location)
#define hypre_DenseBlockMatrixDataIJ(matrix, d, i, j) \
   (d[(matrix) -> row_stride * i + \
      (matrix) -> col_stride * j])
#define hypre_DenseBlockMatrixDataBIJ(matrix, b, i, j) \
   ((matrix) -> data[(matrix) -> num_nonzeros_block * b + \
                     (matrix) -> row_stride * i + \
                     (matrix) -> col_stride * j])

#ifdef HYPRE_MIXED_PRECISION
#define hypre_DenseBlockMatrixPrecision(matrix)          ((matrix) -> matrix_precision)
#endif

#endif
/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/* dense_block_matrix.c */
hypre_DenseBlockMatrix *
hypre_DenseBlockMatrixCreate( HYPRE_Int  row_major,
                              HYPRE_Int  num_rows,
                              HYPRE_Int  num_cols,
                              HYPRE_Int  num_rows_block,
                              HYPRE_Int  num_cols_block );
hypre_DenseBlockMatrix *
hypre_DenseBlockMatrixCreateByBlock( HYPRE_Int  row_major,
                                     HYPRE_Int  num_blocks,
                                     HYPRE_Int  num_rows_block,
                                     HYPRE_Int  num_cols_block );
hypre_DenseBlockMatrix*
hypre_DenseBlockMatrixClone( hypre_DenseBlockMatrix *A,
                             HYPRE_Int               copy_data );
HYPRE_Int
hypre_DenseBlockMatrixDestroy( hypre_DenseBlockMatrix *A );
HYPRE_Int
hypre_DenseBlockMatrixInitializeOn( hypre_DenseBlockMatrix  *A,
                                    HYPRE_MemoryLocation     memory_location );
HYPRE_Int
hypre_DenseBlockMatrixInitialize( hypre_DenseBlockMatrix *A );
HYPRE_Int
hypre_DenseBlockMatrixBuildAOP( hypre_DenseBlockMatrix *A );
HYPRE_Int
hypre_DenseBlockMatrixCopy( hypre_DenseBlockMatrix *A,
                            hypre_DenseBlockMatrix *B );
HYPRE_Int
hypre_DenseBlockMatrixMigrate( hypre_DenseBlockMatrix *A,
                               HYPRE_MemoryLocation    memory_location );
HYPRE_Int
hypre_DenseBlockMatrixPrint( MPI_Comm                comm,
                             hypre_DenseBlockMatrix *A,
                             const char*             filename );

/* dense_block_matmult.c */
HYPRE_Int
hypre_DenseBlockMatrixMultiplyHost( hypre_DenseBlockMatrix  *A,
                                    hypre_DenseBlockMatrix  *B,
                                    hypre_DenseBlockMatrix  *C);
HYPRE_Int
hypre_DenseBlockMatrixMultiply( hypre_DenseBlockMatrix   *A,
                                hypre_DenseBlockMatrix   *B,
                                hypre_DenseBlockMatrix  **C_ptr);

#ifdef __cplusplus
}
#endif

#ifdef HYPRE_MIXED_PRECISION
/* The following is for user compiles and the order is important.  The first
 * header ensures that we do not change prototype names in user files or in the
 * second header file.  The second header contains all the prototypes needed by
 * users for mixed precision. */
#ifndef hypre_MP_BUILD
#include "_hypre_seq_block_mv_mup_undef.h"
#include "_hypre_seq_block_mv_mup.h"
#endif
#endif

#endif

