libflame  12600
Functions
FLASH_main_prototypes.h File Reference

(r12600)

Go to the source code of this file.

Functions

FLA_Error FLASH_Obj_blocksizes_check (FLA_Obj H, dim_t *b_m, dim_t *b_n)
FLA_Error FLASH_Obj_create_helper_check (FLA_Bool without_buffer, FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_hierarchy_check (FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *elem_sizes_m, dim_t *elem_sizes_n, FLA_Obj flat_matrix, FLA_Obj *H, unsigned long id, dim_t depth_overall, dim_t *depth_sizes_m, dim_t *depth_sizes_n, dim_t *m_offsets, dim_t *n_offsets)
FLA_Error FLASH_Obj_create_conf_to_check (FLA_Trans trans, FLA_Obj H_cur, FLA_Obj *H_new)
FLA_Error FLASH_Obj_create_hier_conf_to_flat_check (FLA_Trans trans, FLA_Obj F, dim_t depth, dim_t *b_mn, FLA_Obj *H)
FLA_Error FLASH_Obj_create_hier_conf_to_flat_ext_check (FLA_Trans trans, FLA_Obj F, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_flat_conf_to_hier_check (FLA_Trans trans, FLA_Obj H, FLA_Obj *F)
FLA_Error FLASH_Obj_create_hier_copy_of_flat_check (FLA_Obj F, dim_t depth, dim_t *b_mn, FLA_Obj *H)
FLA_Error FLASH_Obj_create_hier_copy_of_flat_ext_check (FLA_Obj F, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_flat_copy_of_hier_check (FLA_Obj H, FLA_Obj *F)
FLA_Error FLASH_Obj_free_check (FLA_Obj *H)
FLA_Error FLASH_Obj_free_without_buffer_check (FLA_Obj *H)
FLA_Error FLASH_Obj_free_hierarchy_check (FLA_Obj *H)
FLA_Error FLASH_Obj_attach_buffer_check (void *buffer, dim_t rs, dim_t cs, FLA_Obj *H)
FLA_Error FLASH_Obj_attach_buffer_hierarchy_check (FLA_Obj F, FLA_Obj *H)
FLA_Error FLASH_Part_create_2x1 (FLA_Obj A, FLA_Obj *AT, FLA_Obj *AB, dim_t n_rows, FLA_Side side)
FLA_Error FLASH_Part_create_1x2 (FLA_Obj A, FLA_Obj *AL, FLA_Obj *AR, dim_t n_cols, FLA_Side side)
FLA_Error FLASH_Part_create_2x2 (FLA_Obj A, FLA_Obj *ATL, FLA_Obj *ATR, FLA_Obj *ABL, FLA_Obj *ABR, dim_t n_rows, dim_t n_cols, FLA_Side side)
FLA_Error FLASH_Part_free_2x1 (FLA_Obj *AT, FLA_Obj *AB)
FLA_Error FLASH_Part_free_1x2 (FLA_Obj *AL, FLA_Obj *AR)
FLA_Error FLASH_Part_free_2x2 (FLA_Obj *ATL, FLA_Obj *ATR, FLA_Obj *ABL, FLA_Obj *ABR)
FLA_Error FLASH_Obj_adjust_views (FLA_Bool attach_buffer, dim_t offm, dim_t offn, dim_t m, dim_t n, FLA_Obj A, FLA_Obj *S)
FLA_Error FLASH_Obj_adjust_views_hierarchy (FLA_Bool attach_buffer, dim_t offm, dim_t offn, dim_t m, dim_t n, FLA_Obj A, FLA_Obj *S)
dim_t FLASH_Obj_scalar_length (FLA_Obj H)
dim_t FLASH_Obj_scalar_width (FLA_Obj H)
dim_t FLASH_Obj_scalar_min_dim (FLA_Obj H)
dim_t FLASH_Obj_scalar_max_dim (FLA_Obj H)
dim_t FLASH_Obj_scalar_vector_dim (FLA_Obj H)
dim_t FLASH_Obj_scalar_row_offset (FLA_Obj H)
dim_t FLASH_Obj_scalar_col_offset (FLA_Obj H)
dim_t FLASH_Obj_scalar_length_tl (FLA_Obj H)
dim_t FLASH_Obj_scalar_width_tl (FLA_Obj H)
dim_t FLASH_Obj_base_scalar_length (FLA_Obj H)
dim_t FLASH_Obj_base_scalar_width (FLA_Obj H)
FLA_Error FLASH_Obj_show (char *header, FLA_Obj H, char *elem_format, char *footer)
FLA_Error FLASH_Obj_show_hierarchy (FLA_Obj H, dim_t i, char *elem_format)
FLA_Error FLASH_Axpy_buffer_to_hier (FLA_Obj alpha, dim_t m, dim_t n, void *buffer, dim_t rs, dim_t cs, dim_t i, dim_t j, FLA_Obj H)
FLA_Error FLASH_Axpy_hier_to_buffer (FLA_Obj alpha, dim_t i, dim_t j, FLA_Obj H, dim_t m, dim_t n, void *buffer, dim_t rs, dim_t cs)
FLA_Error FLASH_Axpy_flat_to_hier (FLA_Obj alpha, FLA_Obj F, dim_t i, dim_t j, FLA_Obj H)
FLA_Error FLASH_Axpy_hier_to_flat (FLA_Obj alpha, dim_t i, dim_t j, FLA_Obj H, FLA_Obj F)
FLA_Error FLASH_Axpy_hierarchy (int direction, FLA_Obj alpha, FLA_Obj F, FLA_Obj *H)
FLA_Error FLASH_Copy_buffer_to_hier (dim_t m, dim_t n, void *buffer, dim_t rs, dim_t cs, dim_t i, dim_t j, FLA_Obj H)
FLA_Error FLASH_Copy_hier_to_buffer (dim_t i, dim_t j, FLA_Obj H, dim_t m, dim_t n, void *buffer, dim_t rs, dim_t cs)
FLA_Error FLASH_Copy_flat_to_hier (FLA_Obj F, dim_t i, dim_t j, FLA_Obj H)
FLA_Error FLASH_Copy_hier_to_flat (dim_t i, dim_t j, FLA_Obj H, FLA_Obj F)
FLA_Error FLASH_Copy_hierarchy (int direction, FLA_Obj F, FLA_Obj *H)
FLA_Datatype FLASH_Obj_datatype (FLA_Obj H)
dim_t FLASH_Obj_depth (FLA_Obj H)
dim_t FLASH_Obj_blocksizes (FLA_Obj H, dim_t *b_m, dim_t *b_n)
FLA_Error FLASH_Obj_create (FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *b_mn, FLA_Obj *H)
FLA_Error FLASH_Obj_create_ext (FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_without_buffer (FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *b_mn, FLA_Obj *H)
FLA_Error FLASH_Obj_create_without_buffer_ext (FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_helper (FLA_Bool without_buffer, FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_hierarchy (FLA_Datatype datatype, dim_t m, dim_t n, dim_t depth, dim_t *elem_sizes_m, dim_t *elem_sizes_n, FLA_Obj flat_matrix, FLA_Obj *H, unsigned long id, dim_t depth_overall, dim_t *depth_sizes_m, dim_t *depth_sizes_n, dim_t *m_offsets, dim_t *n_offsets)
FLA_Error FLASH_Obj_create_conf_to (FLA_Trans trans, FLA_Obj H_cur, FLA_Obj *H_new)
FLA_Error FLASH_Obj_create_hier_conf_to_flat (FLA_Trans trans, FLA_Obj F, dim_t depth, dim_t *b_mn, FLA_Obj *H)
FLA_Error FLASH_Obj_create_hier_conf_to_flat_ext (FLA_Trans trans, FLA_Obj F, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_flat_conf_to_hier (FLA_Trans trans, FLA_Obj H, FLA_Obj *F)
FLA_Error FLASH_Obj_create_copy_of (FLA_Trans trans, FLA_Obj H_cur, FLA_Obj *H_new)
FLA_Error FLASH_Obj_create_hier_copy_of_flat (FLA_Obj F, dim_t depth, dim_t *b_mn, FLA_Obj *H)
FLA_Error FLASH_Obj_create_hier_copy_of_flat_ext (FLA_Obj F, dim_t depth, dim_t *b_m, dim_t *b_n, FLA_Obj *H)
FLA_Error FLASH_Obj_create_flat_copy_of_hier (FLA_Obj H, FLA_Obj *F)
void FLASH_Obj_free (FLA_Obj *H)
void FLASH_Obj_free_hierarchy (FLA_Obj *H)
void FLASH_Obj_free_without_buffer (FLA_Obj *H)
FLA_Error FLASH_Obj_attach_buffer (void *buffer, dim_t rs, dim_t cs, FLA_Obj *H)
FLA_Error FLASH_Obj_attach_buffer_hierarchy (FLA_Obj F, FLA_Obj *H)
FLA_Error FLASH_Obj_flatten (FLA_Obj H, FLA_Obj F)
FLA_Error FLASH_Obj_hierarchify (FLA_Obj F, FLA_Obj H)
void * FLASH_Obj_extract_buffer (FLA_Obj H)
void FLASH_print_struct (FLA_Obj H)
void FLASH_print_struct_helper (FLA_Obj H, int indent)

Function Documentation

FLA_Error FLASH_Axpy_buffer_to_hier ( FLA_Obj  alpha,
dim_t  m,
dim_t  n,
void *  buffer,
dim_t  rs,
dim_t  cs,
dim_t  i,
dim_t  j,
FLA_Obj  H 
)

References FLA_Check_consistent_object_datatype(), FLA_Check_error_level(), FLA_Check_if_scalar(), FLA_Check_matrix_strides(), FLA_Check_submatrix_dims_and_offset(), FLA_Obj_attach_buffer(), FLA_Obj_create_without_buffer(), FLA_Obj_free_without_buffer(), FLASH_Axpy_flat_to_hier(), and FLASH_Obj_datatype().

{
    FLA_Obj      flat_matrix;
    FLA_Datatype datatype;
    FLA_Error    e_val;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
    {
        e_val = FLA_Check_if_scalar( alpha );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_consistent_object_datatype( alpha, H );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_matrix_strides( m, n, rs, cs );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_submatrix_dims_and_offset( m, n, i, j, H );
        FLA_Check_error_code( e_val );
    }

    // Acquire the datatype from the hierarchical matrix object.
    datatype = FLASH_Obj_datatype( H );

    // Create a temporary conventional matrix object of the requested datatype
    // and dimensions and attach the given buffer containing the incoming data.
    FLA_Obj_create_without_buffer( datatype, m, n, &flat_matrix );
    FLA_Obj_attach_buffer( buffer, rs, cs, &flat_matrix );

    // Recurse through H, adding in the corresponding elements of flat_matrix,
    // starting at the (i,j) element offset.
    FLASH_Axpy_flat_to_hier( alpha, flat_matrix, i, j, H );

    // Free the object (but don't free the buffer!).
    FLA_Obj_free_without_buffer( &flat_matrix );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Axpy_flat_to_hier ( FLA_Obj  alpha,
FLA_Obj  F,
dim_t  i,
dim_t  j,
FLA_Obj  H 
)

References FLA_Obj_length(), FLA_Obj_width(), FLASH_Axpy_hierarchy(), FLASH_Part_create_2x2(), and FLASH_Part_free_2x2().

Referenced by FLASH_Axpy_buffer_to_hier().

{
    FLA_Obj HTL, HTR,
            HBL, HBR;
    FLA_Obj HBR_tl, HBR_tr,
            HBR_bl, HBR_br;
    dim_t   m, n;

    m = FLA_Obj_length( F );
    n = FLA_Obj_width( F );

    FLASH_Part_create_2x2( H,   &HTL, &HTR,
                                &HBL, &HBR,    i, j, FLA_TL );

    FLASH_Part_create_2x2( HBR,   &HBR_tl, &HBR_tr,
                                  &HBR_bl, &HBR_br,    m, n, FLA_TL );

    FLASH_Axpy_hierarchy( FLA_FLAT_TO_HIER, alpha, F, &HBR_tl );

    FLASH_Part_free_2x2( &HBR_tl, &HBR_tr,
                         &HBR_bl, &HBR_br );

    FLASH_Part_free_2x2( &HTL, &HTR,
                         &HBL, &HBR );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Axpy_hier_to_buffer ( FLA_Obj  alpha,
dim_t  i,
dim_t  j,
FLA_Obj  H,
dim_t  m,
dim_t  n,
void *  buffer,
dim_t  rs,
dim_t  cs 
)

References FLA_Check_consistent_object_datatype(), FLA_Check_error_level(), FLA_Check_if_scalar(), FLA_Check_matrix_strides(), FLA_Check_submatrix_dims_and_offset(), FLA_Obj_attach_buffer(), FLA_Obj_create_without_buffer(), FLA_Obj_free_without_buffer(), FLASH_Axpy_hier_to_flat(), and FLASH_Obj_datatype().

{
    FLA_Obj      flat_matrix;
    FLA_Datatype datatype;
    FLA_Error    e_val;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
    {
        e_val = FLA_Check_if_scalar( alpha );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_consistent_object_datatype( alpha, H );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_matrix_strides( m, n, rs, cs );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_submatrix_dims_and_offset( m, n, i, j, H );
        FLA_Check_error_code( e_val );
    }

    // Acquire the datatype from the hierarchical matrix object.
    datatype = FLASH_Obj_datatype( H );

    // Create a temporary conventional matrix object of the requested datatype
    // and dimensions and attach the given buffer containing the incoming data.
    FLA_Obj_create_without_buffer( datatype, m, n, &flat_matrix );
    FLA_Obj_attach_buffer( buffer, rs, cs, &flat_matrix );

    // Recurse through H, adding in the corresponding elements of flat_matrix,
    // starting at the (i,j) element offset.
    FLASH_Axpy_hier_to_flat( alpha, i, j, H, flat_matrix );

    // Free the object (but don't free the buffer!).
    FLA_Obj_free_without_buffer( &flat_matrix );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Axpy_hier_to_flat ( FLA_Obj  alpha,
dim_t  i,
dim_t  j,
FLA_Obj  H,
FLA_Obj  F 
)

References FLA_Obj_length(), FLA_Obj_width(), FLASH_Axpy_hierarchy(), FLASH_Part_create_2x2(), and FLASH_Part_free_2x2().

Referenced by FLASH_Axpy_hier_to_buffer().

{
    FLA_Obj HTL, HTR,
            HBL, HBR;
    FLA_Obj HBR_tl, HBR_tr,
            HBR_bl, HBR_br;
    dim_t   m, n;

    m = FLA_Obj_length( F );
    n = FLA_Obj_width( F );

    FLASH_Part_create_2x2( H,   &HTL, &HTR,
                                &HBL, &HBR,    i, j, FLA_TL );

    FLASH_Part_create_2x2( HBR,   &HBR_tl, &HBR_tr,
                                  &HBR_bl, &HBR_br,    m, n, FLA_TL );

    FLASH_Axpy_hierarchy( FLA_HIER_TO_FLAT, alpha, F, &HBR_tl );

    FLASH_Part_free_2x2( &HBR_tl, &HBR_tr,
                         &HBR_bl, &HBR_br );

    FLASH_Part_free_2x2( &HTL, &HTR,
                         &HBL, &HBR );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Axpy_hierarchy ( int  direction,
FLA_Obj  alpha,
FLA_Obj  F,
FLA_Obj H 
)

References FLA_Axpy_external(), FLA_Cont_with_1x3_to_1x2(), FLA_Cont_with_3x1_to_2x1(), FLA_is_owner(), FLA_Obj_elemtype(), FLA_Obj_length(), FLA_Obj_width(), FLA_Part_1x2(), FLA_Part_2x1(), FLA_Repart_1x2_to_1x3(), FLA_Repart_2x1_to_3x1(), FLASH_Axpy_hierarchy(), FLASH_Obj_scalar_length(), and FLASH_Obj_scalar_width().

Referenced by FLASH_Axpy_flat_to_hier(), FLASH_Axpy_hier_to_flat(), and FLASH_Axpy_hierarchy().

{
    // Once we get down to a submatrix whose elements are scalars, we are down
    // to our base case.
    if ( FLA_Obj_elemtype( *H ) == FLA_SCALAR )
    {
        // Depending on which top-level function invoked us, we either axpy
        // the source data in the flat matrix to the leaf-level submatrix of
        // the hierarchical matrix, or axpy the data in the hierarchical
        // submatrix to the flat matrix.
        if      ( direction == FLA_FLAT_TO_HIER )
        {
#ifdef FLA_ENABLE_SCC
            if ( FLA_is_owner() )
#endif
            FLA_Axpy_external( alpha, F, *H );
        }
        else if ( direction == FLA_HIER_TO_FLAT )
        {
#ifdef FLA_ENABLE_SCC
            if ( FLA_is_owner() )
#endif
            FLA_Axpy_external( alpha, *H, F );
        }
    }
    else
    {
        FLA_Obj HL,  HR,       H0,  H1,  H2;
        FLA_Obj FL,  FR,       F0,  F1,  F2;

        FLA_Obj H1T,           H01,
                H1B,           H11,
                               H21;
        FLA_Obj F1T,           F01,
                F1B,           F11,
                               F21;

        dim_t b_m;
        dim_t b_n;

        FLA_Part_1x2( *H,    &HL,  &HR,      0, FLA_LEFT );
        FLA_Part_1x2(  F,    &FL,  &FR,      0, FLA_LEFT );

        while ( FLA_Obj_width( HL ) < FLA_Obj_width( *H ) )
        {
            FLA_Repart_1x2_to_1x3( HL,  /**/ HR,        &H0, /**/ &H1, &H2,
                                   1, FLA_RIGHT );

            // Get the scalar width of H1 and use that to determine the
            // width of F1.
            b_n = FLASH_Obj_scalar_width( H1 );

            FLA_Repart_1x2_to_1x3( FL,  /**/ FR,        &F0, /**/ &F1, &F2,
                                   b_n, FLA_RIGHT );

            // -------------------------------------------------------------

            FLA_Part_2x1( H1,    &H1T,
                                 &H1B,       0, FLA_TOP );
            FLA_Part_2x1( F1,    &F1T,
                                 &F1B,       0, FLA_TOP );

            while ( FLA_Obj_length( H1T ) < FLA_Obj_length( H1 ) )
            {
                FLA_Repart_2x1_to_3x1( H1T,               &H01,
                                    /* ** */            /* *** */
                                                          &H11,
                                       H1B,               &H21,        1, FLA_BOTTOM );

                // Get the scalar length of H11 and use that to determine the
                // length of F11.
                b_m = FLASH_Obj_scalar_length( H11 );

                FLA_Repart_2x1_to_3x1( F1T,               &F01,
                                    /* ** */            /* *** */
                                                          &F11,
                                       F1B,               &F21,        b_m, FLA_BOTTOM );
                // -------------------------------------------------------------

                // Recursively axpy between F11 and H11.
                FLASH_Axpy_hierarchy( direction, alpha, F11,
                                      FLASH_OBJ_PTR_AT( H11 ) );

                // -------------------------------------------------------------

                FLA_Cont_with_3x1_to_2x1( &H1T,               H01,
                                                              H11,
                                        /* ** */           /* *** */
                                          &H1B,               H21,     FLA_TOP );
                FLA_Cont_with_3x1_to_2x1( &F1T,               F01,
                                                              F11,
                                        /* ** */           /* *** */
                                          &F1B,               F21,     FLA_TOP );
            }

            // -------------------------------------------------------------

            FLA_Cont_with_1x3_to_1x2( &HL,  /**/ &HR,        H0, H1, /**/ H2,
                                      FLA_LEFT );
            FLA_Cont_with_1x3_to_1x2( &FL,  /**/ &FR,        F0, F1, /**/ F2,
                                      FLA_LEFT );
        }
    }

    return FLA_SUCCESS;
}
FLA_Error FLASH_Copy_buffer_to_hier ( dim_t  m,
dim_t  n,
void *  buffer,
dim_t  rs,
dim_t  cs,
dim_t  i,
dim_t  j,
FLA_Obj  H 
)

References FLA_Check_error_level(), FLA_Check_matrix_strides(), FLA_Check_submatrix_dims_and_offset(), FLA_Obj_attach_buffer(), FLA_Obj_create_without_buffer(), FLA_Obj_free_without_buffer(), FLASH_Copy_flat_to_hier(), and FLASH_Obj_datatype().

{
    FLA_Obj      flat_matrix;
    FLA_Datatype datatype;
    FLA_Error    e_val;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
    {
        e_val = FLA_Check_matrix_strides( m, n, rs, cs );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_submatrix_dims_and_offset( m, n, i, j, H );
        FLA_Check_error_code( e_val );
    }

    // Acquire the datatype from the hierarchical matrix object.
    datatype = FLASH_Obj_datatype( H );

    // Create a temporary conventional matrix object of the requested datatype
    // and dimensions and attach the given buffer containing the incoming data.
    FLA_Obj_create_without_buffer( datatype, m, n, &flat_matrix );
    FLA_Obj_attach_buffer( buffer, rs, cs, &flat_matrix );

    // Recurse through H, adding in the corresponding elements of flat_matrix,
    // starting at the (i,j) element offset.
    FLASH_Copy_flat_to_hier( flat_matrix, i, j, H );

    // Free the object (but don't free the buffer!).
    FLA_Obj_free_without_buffer( &flat_matrix );

    return FLA_SUCCESS;
}

References FLA_Obj_length(), FLA_Obj_width(), FLASH_Copy_hierarchy(), FLASH_Part_create_2x2(), and FLASH_Part_free_2x2().

Referenced by FLA_LQ_UT_macro_task(), FLA_LU_piv_macro_task(), FLA_QR_UT_macro_task(), FLASH_Copy_buffer_to_hier(), FLASH_Obj_create_hier_copy_of_flat(), FLASH_Obj_create_hier_copy_of_flat_ext(), and FLASH_Obj_hierarchify().

{
    FLA_Obj HTL, HTR,
            HBL, HBR;
    FLA_Obj HBR_tl, HBR_tr,
            HBR_bl, HBR_br;
    dim_t   m, n;

    m = FLA_Obj_length( F );
    n = FLA_Obj_width( F );

    FLASH_Part_create_2x2( H,   &HTL, &HTR,
                                &HBL, &HBR,    i, j, FLA_TL );

    FLASH_Part_create_2x2( HBR,   &HBR_tl, &HBR_tr,
                                  &HBR_bl, &HBR_br,    m, n, FLA_TL );

    FLASH_Copy_hierarchy( FLA_FLAT_TO_HIER, F, &HBR_tl );

    FLASH_Part_free_2x2( &HBR_tl, &HBR_tr,
                         &HBR_bl, &HBR_br );

    FLASH_Part_free_2x2( &HTL, &HTR,
                         &HBL, &HBR );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Copy_hier_to_buffer ( dim_t  i,
dim_t  j,
FLA_Obj  H,
dim_t  m,
dim_t  n,
void *  buffer,
dim_t  rs,
dim_t  cs 
)

References FLA_Check_error_level(), FLA_Check_matrix_strides(), FLA_Check_submatrix_dims_and_offset(), FLA_Obj_attach_buffer(), FLA_Obj_create_without_buffer(), FLA_Obj_free_without_buffer(), FLASH_Copy_hier_to_flat(), and FLASH_Obj_datatype().

{
    FLA_Obj      flat_matrix;
    FLA_Datatype datatype;
    FLA_Error    e_val;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
    {
        e_val = FLA_Check_matrix_strides( m, n, rs, cs );
        FLA_Check_error_code( e_val );

        e_val = FLA_Check_submatrix_dims_and_offset( m, n, i, j, H );
        FLA_Check_error_code( e_val );
    }

    // Acquire the datatype from the hierarchical matrix object.
    datatype = FLASH_Obj_datatype( H );

    // Create a temporary conventional matrix object of the requested datatype
    // and dimensions and attach the given buffer containing the incoming data.
    FLA_Obj_create_without_buffer( datatype, m, n, &flat_matrix );
    FLA_Obj_attach_buffer( buffer, rs, cs, &flat_matrix );

    // Recurse through H, adding in the corresponding elements of flat_matrix,
    // starting at the (i,j) element offset.
    FLASH_Copy_hier_to_flat( i, j, H, flat_matrix );

    // Free the object (but don't free the buffer!).
    FLA_Obj_free_without_buffer( &flat_matrix );

    return FLA_SUCCESS;
}

References FLA_Obj_length(), FLA_Obj_width(), FLASH_Copy_hierarchy(), FLASH_Part_create_2x2(), and FLASH_Part_free_2x2().

Referenced by FLASH_Copy_hier_to_buffer(), FLASH_Obj_create_flat_copy_of_hier(), and FLASH_Obj_flatten().

{
    FLA_Obj HTL, HTR,
            HBL, HBR;
    FLA_Obj HBR_tl, HBR_tr,
            HBR_bl, HBR_br;
    dim_t   m, n;

    m = FLA_Obj_length( F );
    n = FLA_Obj_width( F );

    FLASH_Part_create_2x2( H,   &HTL, &HTR,
                                &HBL, &HBR,    i, j, FLA_TL );

    FLASH_Part_create_2x2( HBR,   &HBR_tl, &HBR_tr,
                                  &HBR_bl, &HBR_br,    m, n, FLA_TL );

    FLASH_Copy_hierarchy( FLA_HIER_TO_FLAT, F, &HBR_tl );

    FLASH_Part_free_2x2( &HBR_tl, &HBR_tr,
                         &HBR_bl, &HBR_br );

    FLASH_Part_free_2x2( &HTL, &HTR,
                         &HBL, &HBR );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Copy_hierarchy ( int  direction,
FLA_Obj  F,
FLA_Obj H 
)

References FLA_Cont_with_1x3_to_1x2(), FLA_Cont_with_3x1_to_2x1(), FLA_Copy_external(), FLA_is_owner(), FLA_Obj_elemtype(), FLA_Obj_length(), FLA_Obj_width(), FLA_Part_1x2(), FLA_Part_2x1(), FLA_Repart_1x2_to_1x3(), FLA_Repart_2x1_to_3x1(), FLASH_Copy_hierarchy(), FLASH_Obj_scalar_length(), and FLASH_Obj_scalar_width().

Referenced by FLASH_Copy_flat_to_hier(), FLASH_Copy_hier_to_flat(), and FLASH_Copy_hierarchy().

{
    // Once we get down to a submatrix whose elements are scalars, we are down
    // to our base case.
    if ( FLA_Obj_elemtype( *H ) == FLA_SCALAR )
    {
        // Depending on which top-level function invoked us, we either copy
        // the source data in the flat matrix to the leaf-level submatrix of
        // the hierarchical matrix, or copy the data in the hierarchical
        // submatrix to the flat matrix.
        if      ( direction == FLA_FLAT_TO_HIER )
        {
#ifdef FLA_ENABLE_SCC
            if ( FLA_is_owner() )
#endif
            FLA_Copy_external( F, *H );
        }
        else if ( direction == FLA_HIER_TO_FLAT )
        {
#ifdef FLA_ENABLE_SCC
            if ( FLA_is_owner() )
#endif
            FLA_Copy_external( *H, F );
        }
    }
    else
    {
        FLA_Obj HL,  HR,       H0,  H1,  H2;
        FLA_Obj FL,  FR,       F0,  F1,  F2;

        FLA_Obj H1T,           H01,
                H1B,           H11,
                               H21;
        FLA_Obj F1T,           F01,
                F1B,           F11,
                               F21;

        dim_t b_m;
        dim_t b_n;

        FLA_Part_1x2( *H,    &HL,  &HR,      0, FLA_LEFT );
        FLA_Part_1x2(  F,    &FL,  &FR,      0, FLA_LEFT );

        while ( FLA_Obj_width( HL ) < FLA_Obj_width( *H ) )
        {
            FLA_Repart_1x2_to_1x3( HL,  /**/ HR,        &H0, /**/ &H1, &H2,
                                   1, FLA_RIGHT );

            // Get the scalar width of H1 and use that to determine the
            // width of F1.
            b_n = FLASH_Obj_scalar_width( H1 );

            FLA_Repart_1x2_to_1x3( FL,  /**/ FR,        &F0, /**/ &F1, &F2,
                                   b_n, FLA_RIGHT );

            // -------------------------------------------------------------

            FLA_Part_2x1( H1,    &H1T,
                                 &H1B,       0, FLA_TOP );
            FLA_Part_2x1( F1,    &F1T,
                                 &F1B,       0, FLA_TOP );

            while ( FLA_Obj_length( H1T ) < FLA_Obj_length( H1 ) )
            {
                FLA_Repart_2x1_to_3x1( H1T,               &H01,
                                    /* ** */            /* *** */
                                                          &H11,
                                       H1B,               &H21,        1, FLA_BOTTOM );

                // Get the scalar length of H11 and use that to determine the
                // length of F11.
                b_m = FLASH_Obj_scalar_length( H11 );

                FLA_Repart_2x1_to_3x1( F1T,               &F01,
                                    /* ** */            /* *** */
                                                          &F11,
                                       F1B,               &F21,        b_m, FLA_BOTTOM );
                // -------------------------------------------------------------

                // Recursively copy between F11 and H11.
                FLASH_Copy_hierarchy( direction, F11,
                                      FLASH_OBJ_PTR_AT( H11 ) );

                // -------------------------------------------------------------

                FLA_Cont_with_3x1_to_2x1( &H1T,               H01,
                                                              H11,
                                        /* ** */           /* *** */
                                          &H1B,               H21,     FLA_TOP );
                FLA_Cont_with_3x1_to_2x1( &F1T,               F01,
                                                              F11,
                                        /* ** */           /* *** */
                                          &F1B,               F21,     FLA_TOP );
            }

            // -------------------------------------------------------------

            FLA_Cont_with_1x3_to_1x2( &HL,  /**/ &HR,        H0, H1, /**/ H2,
                                      FLA_LEFT );
            FLA_Cont_with_1x3_to_1x2( &FL,  /**/ &FR,        F0, F1, /**/ F2,
                                      FLA_LEFT );
        }
    }

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_adjust_views ( FLA_Bool  attach_buffer,
dim_t  offm,
dim_t  offn,
dim_t  m,
dim_t  n,
FLA_Obj  A,
FLA_Obj S 
)
FLA_Error FLASH_Obj_adjust_views_hierarchy ( FLA_Bool  attach_buffer,
dim_t  offm,
dim_t  offn,
dim_t  m,
dim_t  n,
FLA_Obj  A,
FLA_Obj S 
)

References FLA_Obj_view::base, FLA_Obj_struct::buffer, FLA_Obj_struct::cs, FLA_Cont_with_1x3_to_1x2(), FLA_Cont_with_3x1_to_2x1(), FLA_Obj_col_offset(), FLA_Obj_elemtype(), FLA_Obj_length(), FLA_Obj_row_offset(), FLA_Obj_width(), FLA_Part_1x2(), FLA_Part_2x1(), FLA_Part_2x2(), FLA_Repart_1x2_to_1x3(), FLA_Repart_2x1_to_3x1(), FLASH_Obj_adjust_views_hierarchy(), FLASH_Obj_scalar_length_tl(), FLASH_Obj_scalar_width_tl(), FLA_Obj_struct::id, FLA_Obj_view::m_inner, FLA_Obj_view::n_inner, and FLA_Obj_struct::rs.

Referenced by FLASH_Obj_adjust_views(), and FLASH_Obj_adjust_views_hierarchy().

{
    FLA_Obj ATL, ATR,
            ABL, ABR;

    FLA_Obj STL, STR,
            SBL, SBR;

    // Base case.
    if ( FLA_Obj_elemtype( A ) == FLA_SCALAR )
    {
        // Repartition to exclude elements above and to the left of our
        // submatrix of interest.
        FLA_Part_2x2( A,    &ATL, &ATR,
                            &ABL, &ABR,    offm, offn, FLA_TL );
        FLA_Part_2x2( *S,   &STL, &STR,
                            &SBL, &SBR,    offm, offn, FLA_TL );

        // Overwrite the existing views with ones that have updated offsets.
        A  = ABR;
        *S = SBR;

        // Repartition to exclude elements below and to the right of our
        // submatrix of interest.
        FLA_Part_2x2( A,    &ATL, &ATR,
                            &ABL, &ABR,    m, n, FLA_TL );
        FLA_Part_2x2( *S,   &STL, &STR,
                            &SBL, &SBR,    m, n, FLA_TL );

        // Overwrite the existing view of S with the view of A so that S
        // Refers to the correct base object.
        A  = ATL;
        *S = STL;

        // Adjust the _inner fields in the view to reflect the number of
        // elements we have in each dimension.
        S->m_inner = m;
        S->n_inner = n;

        // Copy over buffer, stride, and object ID information if requested.
        if ( attach_buffer )
        {
            // Copy over the address of the numerical data buffer and its
            // corresponding row and column strides. This is obviously
            // necessary since we are creating a hierarchial view into an
            // existing hierarhical matrix, not a separate/new matrix
            // altogether.
            S->base->buffer = A.base->buffer;
            S->base->rs     = A.base->rs;
            S->base->cs     = A.base->cs;

            // Copy over the id field of the original matrix. This is used
            // by SuperMatrix to distinguish between distinct hierarchical
            // matrices. Since again, we are not creating a new matrix, we
            // will use the original object's id value.
            S->base->id = A.base->id;
        }
    }
    else // if ( FLA_Obj_elemtype( A ) == FLA_MATRIX )
    {
        FLA_Obj AL,  AR,       A0,  A1,  A2;

        FLA_Obj SL,  SR,       S0,  S1,  S2;

        FLA_Obj A1T,           A01,
                A1B,           A11,
                               A21;

        FLA_Obj S1T,           S01,
                S1B,           S11,
                               S21;
        dim_t b_m_full;
        dim_t b_n_full;
        dim_t offm_relA;
        dim_t offn_relA;
        dim_t offm_abs;
        dim_t offn_abs;
        dim_t offm_cur;
        dim_t offn_cur;
        dim_t offm_rem;
        dim_t offn_rem;
        dim_t offm_next;
        dim_t offn_next;
        dim_t m_next;
        dim_t n_next;
        dim_t m_ahead;
        dim_t n_ahead;
        dim_t m_behind;
        dim_t n_behind;

        // Acquire the scalar length and width of the top-left (full) block
        // at the current hierarchical level.
        b_m_full = FLASH_Obj_scalar_length_tl( A );
        b_n_full = FLASH_Obj_scalar_width_tl( A );
/*
printf( "-----------------\n" );
printf( "b_m/n_full:    %d %d\n", b_m_full, b_n_full );
printf( "offm/n:        %d %d\n", offm, offn );
printf( "r/c offsets:   %d %d\n", FLA_Obj_row_offset( A ), FLA_Obj_col_offset( A ) );
*/      
        // Compute the offsets for the top-left corner of the submatrix of
        // interest relative to the view at the current level of the
        // hierarchy of A.
        offm_relA = offm / b_m_full - FLA_Obj_row_offset( A );
        offn_relA = offn / b_n_full - FLA_Obj_col_offset( A );

        // Compute the offsets for the top-left corner of the submatrix of
        // interest in absolute units, from the top-left edge of the 
        // overall allocated matrix. This will be used to partition into S
        // Since its view has (presumably) not yet been changed since it
        // was created.
        offm_abs  = offm / b_m_full;
        offn_abs  = offn / b_n_full;
/*
printf( "offm/n_relA:   %d %d\n", offm_relA, offn_relA );
printf( "offm/n_abs:    %d %d\n", offm_abs, offn_abs );
*/
        // Repartition to exclude blocks above and to the left of our
        // submatrix of interest.
        FLA_Part_2x2( A,    &ATL, &ATR,
                            &ABL, &ABR,    offm_relA, offn_relA, FLA_TL );
        FLA_Part_2x2( *S,   &STL, &STR,
                            &SBL, &SBR,    offm_abs, offn_abs, FLA_TL );
/*
printf( "ABR.offm/n     %d %d\n", FLA_Obj_row_offset( ABR ), FLA_Obj_col_offset( ABR ) );
printf( "ABR is         %d %d\n", FLA_Obj_length( ABR ), FLA_Obj_width( ABR ) );
printf( "SBR.offm/n     %d %d\n", FLA_Obj_row_offset( SBR ), FLA_Obj_col_offset( SBR ) );
printf( "SBR is         %d %d\n", FLA_Obj_length( SBR ), FLA_Obj_width( SBR ) );
*/
        // Overwrite the existing views with ones that have updated offsets
        // (for this level in the hierarchy).
        A = ABR;
        *S = SBR;

        // Compute the new offsets within SBR, which is the remaining
        // distance after you subtract out the distance spanned by the
        // partitioning we just did.
        offm_rem = offm - offm_abs * b_m_full;
        offn_rem = offn - offn_abs * b_n_full;

//printf( "offm/n_rem:    %d %d\n", offm_rem, offn_rem );

        // Compute a new set of offsets corresponding to the bottom-right
        // edge of the desired submatrix. We'll use this to partition away
        // the remaining (bottom and right) parts of the FLASH matrix at
        // this level.
        offm_cur = ( offm_rem + m ) / b_m_full;
        offn_cur = ( offn_rem + n ) / b_n_full;
        offm_cur += ( (offm_rem + m) % b_m_full ? 1 : 0 );
        offn_cur += ( (offn_rem + n) % b_n_full ? 1 : 0 );

//printf( "offm/n_cur:    %d %d\n", offm_cur, offn_cur );

        // Repartition to exclude blocks below and to the right of our
        // submatrix of interest.
        FLA_Part_2x2( A,    &ATL, &ATR,
                            &ABL, &ABR,    offm_cur, offn_cur, FLA_TL );
        FLA_Part_2x2( *S,   &STL, &STR,
                            &SBL, &SBR,    offm_cur, offn_cur, FLA_TL );
/*
printf( "ATL.offm/n     %d %d\n", FLA_Obj_row_offset( ATL ), FLA_Obj_col_offset( ATL ) );
printf( "ATL is         %d %d\n", FLA_Obj_length( ATL ), FLA_Obj_width( ATL ) );
printf( "STL.offm/n     %d %d\n", FLA_Obj_row_offset( STL ), FLA_Obj_col_offset( STL ) );
printf( "STL is         %d %d\n", FLA_Obj_length( STL ), FLA_Obj_width( STL ) );
*/

        // Overwrite the existing views with ones that have updated offsets
        // (for this level in the hierarchy).
        A = ATL;
        *S = STL;

        // Adjust the _inner fields in the view to reflect the number of
        // elements we will eventually have in each dimension.
        S->m_inner = m;
        S->n_inner = n;

        // Initialize a counter that keeps track of the n offset relative to
        // the top-left most edge of the submatrix of interest.
        n_behind = 0;

        FLA_Part_1x2(  A,    &AL,  &AR,      0, FLA_LEFT );
        FLA_Part_1x2( *S,    &SL,  &SR,      0, FLA_LEFT );

        while ( FLA_Obj_width( AL ) < FLA_Obj_width( A ) )
        {
            FLA_Repart_1x2_to_1x3( AL,  /**/ AR,        &A0, /**/ &A1, &A2,
                                   1, FLA_RIGHT );
            FLA_Repart_1x2_to_1x3( SL,  /**/ SR,        &S0, /**/ &S1, &S2,
                                   1, FLA_RIGHT );

            // -------------------------------------------------------------

            // Set the n offset for the next levels of recursion based
            // on which panel of A we are in.
            if ( FLA_Obj_width( AL ) == 0 ) offn_next = offn_rem;
            else                            offn_next = 0;

            // Compute the number of columns left to be visited in the
            // submatrix of interset.
            n_ahead = n - n_behind;

            // Set the n dimensions for the next level of recursion
            // depending on whether the submatrix continues beyond the
            // current block.
            if ( offn_next + n_ahead > b_n_full ) n_next = b_n_full - offn_next;
            else                                  n_next = n_ahead;

            // Initialize a counter that keeps track of the m offset relative
            // to the top-left most edge of the submatrix of interest.
            m_behind = 0;

            FLA_Part_2x1( A1,    &A1T,
                                 &A1B,       0, FLA_TOP );
            FLA_Part_2x1( S1,    &S1T,
                                 &S1B,       0, FLA_TOP );

            while ( FLA_Obj_length( A1T ) < FLA_Obj_length( A1 ) )
            {
                FLA_Repart_2x1_to_3x1( A1T,               &A01,
                                    /* ** */            /* ** */
                                                          &A11,
                                       A1B,               &A21,        1, FLA_BOTTOM );
                FLA_Repart_2x1_to_3x1( S1T,               &S01,
                                    /* ** */            /* ** */
                                                          &S11,
                                       S1B,               &S21,        1, FLA_BOTTOM );

                // -------------------------------------------------------------

                // Set the m offset for the next levels of recursion based
                // on which block of A1 we are in.
                if ( FLA_Obj_length( A1T ) == 0 ) offm_next = offm_rem;
                else                              offm_next = 0;

                // Compute the number of rows left to be visited in the
                // submatrix of interset.
                m_ahead = m - m_behind;

                // Set the m dimensions for the next level of recursion
                // depending on whether the submatrix continues beyond the
                // current block.
                if ( offm_next + m_ahead > b_m_full ) m_next = b_m_full - offm_next;
                else                                  m_next = m_ahead;

//printf( "offm/n_next m/n_next:    %d %d %d %d\n", offm_next, offn_next, m_next, n_next );
                // Recursively call ourselves with new, smaller offsets
                // and the submatrix corresponding to FLASH blocks captured by ABR.
                FLASH_Obj_adjust_views_hierarchy( attach_buffer,
                                                  offm_next,
                                                  offn_next,
                                                  m_next,
                                                  n_next,
                                                  *FLASH_OBJ_PTR_AT( A11 ),
                                                  FLASH_OBJ_PTR_AT( S11 ) );

                // Increment m_behind to keep track of our absolute m offset.
                m_behind += m_next;

                // -------------------------------------------------------------

                FLA_Cont_with_3x1_to_2x1( &A1T,               A01,
                                                              A11,
                                        /* ** */           /* ** */
                                          &A1B,               A21,     FLA_TOP );
                FLA_Cont_with_3x1_to_2x1( &S1T,               S01,
                                                              S11,
                                        /* ** */           /* ** */
                                          &S1B,               S21,     FLA_TOP );
            }

            // Increment n_behind to keep track of our absolute n offset.
            n_behind += n_next;

            // -------------------------------------------------------------

            FLA_Cont_with_1x3_to_1x2( &AL,  /**/ &AR,        A0, A1, /**/ A2,
                                      FLA_LEFT );
            FLA_Cont_with_1x3_to_1x2( &SL,  /**/ &SR,        S0, S1, /**/ S2,
                                      FLA_LEFT );
        }
    }

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_attach_buffer ( void *  buffer,
dim_t  rs,
dim_t  cs,
FLA_Obj H 
)

References FLA_Check_error_level(), FLA_Obj_attach_buffer(), FLA_Obj_create_without_buffer(), FLA_Obj_free_without_buffer(), FLASH_Obj_attach_buffer_check(), FLASH_Obj_attach_buffer_hierarchy(), FLASH_Obj_base_scalar_length(), FLASH_Obj_base_scalar_width(), and FLASH_Obj_datatype().

{
    FLA_Obj      flat_matrix;
    dim_t        m_base, n_base;
    FLA_Datatype datatype;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_attach_buffer_check( buffer, rs, cs, H );

    // Extract the scalar dimensions of the base object(s) and get its
    // numerical datatype. (These fields will be set even if it has a NULL
    // buffer, which it probably does since this function was just invoked.)
    m_base   = FLASH_Obj_base_scalar_length( *H );
    n_base   = FLASH_Obj_base_scalar_width( *H );
    datatype = FLASH_Obj_datatype( *H );

    // Create a temporary conventional object and attach the given buffer.
    // Segments of this buffer will be partitioned out to the various
    // leaf-level matrices of the hierarchical matrix H.
    FLA_Obj_create_without_buffer( datatype, m_base, n_base, &flat_matrix );
    FLA_Obj_attach_buffer( buffer, rs, cs, &flat_matrix );

    // Recurse through the hierarchical matrix, assigning segments of
    // flat_matrix to the various leaf-level matrices, similar to what
    // we would do if we were creating the object outright.
    FLASH_Obj_attach_buffer_hierarchy( flat_matrix, H );

    // Free the object (but don't free the buffer!).
    FLA_Obj_free_without_buffer( &flat_matrix );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_attach_buffer_check ( void *  buffer,
dim_t  rs,
dim_t  cs,
FLA_Obj H 
)

References FLA_Check_matrix_strides(), FLA_Check_null_pointer(), FLASH_Obj_base_scalar_length(), and FLASH_Obj_base_scalar_width().

Referenced by FLASH_Obj_attach_buffer().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_matrix_strides( FLASH_Obj_base_scalar_length( *H ), FLASH_Obj_base_scalar_width( *H ), rs, cs );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}

References FLA_Check_error_level(), FLA_Cont_with_1x3_to_1x2(), FLA_Cont_with_3x1_to_2x1(), FLA_Obj_attach_buffer(), FLA_Obj_buffer_at_view(), FLA_Obj_col_stride(), FLA_Obj_elemtype(), FLA_Obj_length(), FLA_Obj_row_stride(), FLA_Obj_width(), FLA_Part_1x2(), FLA_Part_2x1(), FLA_Repart_1x2_to_1x3(), FLA_Repart_2x1_to_3x1(), FLASH_Obj_attach_buffer_hierarchy(), FLASH_Obj_attach_buffer_hierarchy_check(), FLASH_Obj_base_scalar_length(), and FLASH_Obj_base_scalar_width().

Referenced by FLASH_Obj_attach_buffer(), and FLASH_Obj_attach_buffer_hierarchy().

{
    FLA_Obj FL,    FR,       F0,  F1,  F2;

    FLA_Obj HL,    HR,       H0,  H1,  H2;

    FLA_Obj F1T,              F01,
            F1B,              F11,
                              F21;

    FLA_Obj H1T,              H01,
            H1B,              H11,
                              H21;

    dim_t b_m, b_n;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_attach_buffer_hierarchy_check( F, H );

    if ( FLA_Obj_elemtype( *H ) == FLA_SCALAR )
    {
        // If we've recursed down to a leaf node, then we can simply attach
        // the matrix buffer to the current leaf-level submatrix.
        // Notice we use FLA_Obj_buffer_at_view() because we want to attach
        // the buffer address referenced by the view of F.
        FLA_Obj_attach_buffer( FLA_Obj_buffer_at_view( F ), 
                               FLA_Obj_row_stride( F ),
                               FLA_Obj_col_stride( F ), H );
    }
    else
    {
        FLA_Part_1x2( *H,    &HL,  &HR,      0, FLA_LEFT );

        FLA_Part_1x2(  F,    &FL,  &FR,      0, FLA_LEFT );

        while ( FLA_Obj_width( HL ) < FLA_Obj_width( *H ) )
        {

            FLA_Repart_1x2_to_1x3( HL,  /**/ HR,        &H0, /**/ &H1, &H2,
                                   1, FLA_RIGHT );

            b_n = FLASH_Obj_base_scalar_width( H1 );

            FLA_Repart_1x2_to_1x3( FL,  /**/ FR,        &F0, /**/ &F1, &F2,
                                   b_n, FLA_RIGHT );

            /*------------------------------------------------------------*/

            FLA_Part_2x1( H1,    &H1T,
                                 &H1B,            0, FLA_TOP );

            FLA_Part_2x1( F1,    &F1T,
                                 &F1B,            0, FLA_TOP );

            while ( FLA_Obj_length( H1T ) < FLA_Obj_length( H1 ) )
            {

                FLA_Repart_2x1_to_3x1( H1T,               &H01,
                                    /* ** */            /* ** */
                                                          &H11,
                                       H1B,               &H21,        1, FLA_BOTTOM );

                b_m = FLASH_Obj_base_scalar_length( H11 );

                FLA_Repart_2x1_to_3x1( F1T,               &F01,
                                    /* ** */            /* ** */
                                                          &F11,
                                       F1B,               &F21,      b_m, FLA_BOTTOM );

                /*------------------------------------------------------------*/

                FLASH_Obj_attach_buffer_hierarchy( F11,
                                                   FLASH_OBJ_PTR_AT( H11 ) );

                /*------------------------------------------------------------*/

                FLA_Cont_with_3x1_to_2x1( &H1T,               H01,
                                                              H11,
                                        /* ** */           /* ** */
                                          &H1B,               H21,     FLA_TOP );

                FLA_Cont_with_3x1_to_2x1( &F1T,               F01,
                                                              F11,
                                        /* ** */           /* ** */
                                          &F1B,               F21,     FLA_TOP );
            }

            /*------------------------------------------------------------*/

            FLA_Cont_with_1x3_to_1x2( &HL,  /**/ &HR,        H0, H1, /**/ H2,
                                      FLA_LEFT );

            FLA_Cont_with_1x3_to_1x2( &FL,  /**/ &FR,        F0, F1, /**/ F2,
                                      FLA_LEFT );

        }
    }

    return FLA_SUCCESS;
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_attach_buffer_hierarchy().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}

References FLA_Obj_view::base, FLA_Obj_base_buffer(), FLA_Obj_base_length(), FLA_Obj_col_stride(), FLA_Obj_elemtype(), and FLA_Obj_row_stride().

Referenced by FLASH_Obj_attach_buffer(), FLASH_Obj_attach_buffer_check(), FLASH_Obj_attach_buffer_hierarchy(), FLASH_Obj_create_conf_to(), FLASH_Obj_scalar_length_tl(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), and FLASH_Part_create_2x2().

{
    FLA_Obj* buffer;
    dim_t    m;
    dim_t    rs, cs;
    dim_t    i;
    dim_t    m_base = 0;

    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
        return FLA_Obj_base_length( H );

    // Notice we use the base buffer since we are interested in the
    // whole object, not just the part referened by the view.
    buffer = FLA_Obj_base_buffer( H );
    m      = FLA_Obj_base_length( H );
    rs     = FLA_Obj_row_stride( H );
    cs     = FLA_Obj_col_stride( H );

    // Add up the row dimensions of all the base objects in the 0th
    // column of objects.
    for ( i = 0; i < m; ++i )
    {
        FLA_Obj hij = buffer[ i*rs + 0*cs ];

        m_base += (hij.base)->m_inner;
    }

    return m_base;
}

References FLA_Obj_view::base, FLA_Obj_base_buffer(), FLA_Obj_base_width(), FLA_Obj_col_stride(), FLA_Obj_elemtype(), and FLA_Obj_row_stride().

Referenced by FLASH_Obj_attach_buffer(), FLASH_Obj_attach_buffer_check(), FLASH_Obj_attach_buffer_hierarchy(), FLASH_Obj_create_conf_to(), FLASH_Obj_scalar_width_tl(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), and FLASH_Part_create_2x2().

{
    FLA_Obj* buffer;
    dim_t    n;
    dim_t    rs, cs;
    dim_t    j;
    dim_t    n_base = 0;

    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
        return FLA_Obj_base_width( H );

    // Notice we use the base buffer since we are interested in the
    // whole object, not just the part referened by the view.
    buffer = FLA_Obj_base_buffer( H );
    n      = FLA_Obj_base_width( H );
    rs     = FLA_Obj_row_stride( H );
    cs     = FLA_Obj_col_stride( H );

    // Add up the column dimensions of all the base objects in the 0th
    // row of objects.
    for ( j = 0; j < n; ++j )
    {
        FLA_Obj hij = buffer[ 0*rs + j*cs ];

        n_base += (hij.base)->n_inner;
    }

    return n_base;
}
dim_t FLASH_Obj_blocksizes ( FLA_Obj  H,
dim_t b_m,
dim_t b_n 
)

References FLA_Check_error_level(), FLA_Obj_base_buffer(), FLA_Obj_base_length(), FLA_Obj_base_width(), FLA_Obj_elemtype(), and FLASH_Obj_blocksizes_check().

Referenced by FLASH_Obj_create_conf_to(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), and FLASH_Part_create_2x2().

{
    FLA_Elemtype elemtype;
    FLA_Obj*     buffer_H;
    dim_t        depth = 0;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_blocksizes_check( H, b_m, b_n );

    // Recurse through the hierarchy to the first leaf node. We initialize
    // the recursion here:
    elemtype = FLA_Obj_elemtype( H );
    buffer_H = ( FLA_Obj* ) FLA_Obj_base_buffer( H );

    while ( elemtype == FLA_MATRIX )
    {
        b_m[depth] = FLA_Obj_base_length( buffer_H[0] );
        b_n[depth] = FLA_Obj_base_width( buffer_H[0] );
        ++depth;

        // Get the element type of the top-leftmost underlying object. Also,
        // get a pointer to the first element of the top-leftmost object and
        // assume that it is of type FLA_Obj* in case elemtype is once again
        // FLA_MATRIX.
        elemtype = FLA_Obj_elemtype( buffer_H[0] );
        buffer_H = ( FLA_Obj * ) FLA_Obj_base_buffer( buffer_H[0] );
    }

    // At this point, the first depth elements of blocksizes have been filled
    // with the blocksizes of H's various hierarchical levels. Return the
    // matrix depth as a confirmation of how many blocksizes were found.
    return depth;
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_blocksizes().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( b_m );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( b_n );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create ( FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t b_mn,
FLA_Obj H 
)

References FLASH_Obj_create_helper().

Referenced by FLASH_Obj_create_diag_panel(), and FLASH_Obj_create_hier_conf_to_flat().

{
    FLASH_Obj_create_helper( FALSE, datatype, m, n, depth, b_mn, b_mn, H );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_conf_to ( FLA_Trans  trans,
FLA_Obj  H_cur,
FLA_Obj H_new 
)

References FLA_Check_error_level(), FLA_free(), FLA_malloc(), FLASH_Obj_adjust_views(), FLASH_Obj_base_scalar_length(), FLASH_Obj_base_scalar_width(), FLASH_Obj_blocksizes(), FLASH_Obj_create_conf_to_check(), FLASH_Obj_create_ext(), FLASH_Obj_datatype(), FLASH_Obj_depth(), FLASH_Obj_scalar_col_offset(), FLASH_Obj_scalar_length(), FLASH_Obj_scalar_row_offset(), and FLASH_Obj_scalar_width().

Referenced by FLASH_CAQR_UT_inc_create_hier_matrices(), FLASH_Eig_gest(), and FLASH_Obj_create_copy_of().

{
    FLA_Datatype datatype;
    dim_t        m_base, n_base;
    dim_t        m_view, n_view;
    dim_t        offm_scalar, offn_scalar;
    dim_t        depth;
    dim_t*       b_m;
    dim_t*       b_n;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_conf_to_check( trans, H, H_new );

    // Acquire some properties of the hierarchical matrix object.
    datatype    = FLASH_Obj_datatype( H );
    m_base      = FLASH_Obj_base_scalar_length( H );
    n_base      = FLASH_Obj_base_scalar_width( H );
    m_view      = FLASH_Obj_scalar_length( H );
    n_view      = FLASH_Obj_scalar_width( H );
    offm_scalar = FLASH_Obj_scalar_row_offset( H );
    offn_scalar = FLASH_Obj_scalar_col_offset( H );
    depth       = FLASH_Obj_depth( H );

    // Allocate a pair of temporary arrays for the blocksizes, whose lengths
    // are equal to the object's hierarchical depth.
    b_m = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );
    b_n = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );

    // Accumulate the blocksizes into the blocksize buffer.
    FLASH_Obj_blocksizes( H, b_m, b_n );

    // Handle the transposition, if requested.
    if ( trans == FLA_TRANSPOSE )
    {
        FLA_Check_error_code( FLA_NOT_YET_IMPLEMENTED );
    }

    // Create the new hierarchical matrix object with the same base dimensions
    // as the original object..
    FLASH_Obj_create_ext( datatype, m_base, n_base, depth, b_m, b_n, H_new ); 

    // Adjust the hierarchical view of the new object to match that of the
    // original object.
    FLASH_Obj_adjust_views( FALSE, offm_scalar, offn_scalar, m_view, n_view, H, H_new );

    // Free the temporary blocksize buffers.
    FLA_free( b_m );
    FLA_free( b_n );

    return FLA_SUCCESS;
}

References FLA_Check_null_pointer(), and FLA_Check_valid_real_trans().

Referenced by FLASH_Obj_create_conf_to().

{
  FLA_Error e_val;

  e_val = FLA_Check_valid_real_trans( trans );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( H_new );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_copy_of ( FLA_Trans  trans,
FLA_Obj  H_cur,
FLA_Obj H_new 
)

References FLA_Obj_create_copy_of(), FLA_Obj_free(), FLASH_Copy(), FLASH_Obj_create_conf_to(), FLASH_Obj_create_flat_copy_of_hier(), and FLASH_Obj_hierarchify().

Referenced by FLASH_CAQR_UT_inc_solve(), FLASH_QR_UT_inc_solve(), FLASH_QR_UT_solve(), and FLASH_UDdate_UT_inc_update_rhs().

{
    // Create a new object conformal to the current object.
    FLASH_Obj_create_conf_to( trans, H_cur, H_new );

    // This is a workaround until we implement a FLASH_Copyt().
    if ( trans == FLA_NO_TRANSPOSE || trans == FLA_CONJ_NO_TRANSPOSE )
    {
        // Copy the contents of the current object to the new object.
        FLASH_Copy( H_cur, *H_new );

        // NOTE: we don't currently honor requests to conjugate!
        // We could, if we had FLASH_Conj() implemented, but we don't
        // currently.
    }
    else // if ( trans == FLA_TRANSPOSE || trans == FLA_CONJ_TRANSPOSE )
    {
        FLA_Obj F, F_trans;

        FLASH_Obj_create_flat_copy_of_hier( H_cur, &F );
        FLA_Obj_create_copy_of( trans, F, &F_trans );
        FLASH_Obj_hierarchify( F_trans, *H_new );
        FLA_Obj_free( &F );
        FLA_Obj_free( &F_trans );
    }

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_ext ( FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t b_m,
dim_t b_n,
FLA_Obj H 
)

References FLA_Check_error_level(), FLA_Obj_create(), FLASH_Obj_create_flat_conf_to_hier_check(), FLASH_Obj_datatype(), FLASH_Obj_scalar_length(), and FLASH_Obj_scalar_width().

Referenced by FLASH_Obj_create_flat_copy_of_hier().

{
    FLA_Datatype datatype;
    dim_t        m_H, n_H;
    dim_t        m_F, n_F;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_flat_conf_to_hier_check( trans, H, F );

    // Acquire the numerical datatype, length, and width of the
    // hierarchical matrix object.
    datatype = FLASH_Obj_datatype( H );
    m_H      = FLASH_Obj_scalar_length( H );
    n_H      = FLASH_Obj_scalar_width( H );

    // Factor in the transposition, if requested.
    if ( trans == FLA_NO_TRANSPOSE )
    {
        m_F = m_H;
        n_F = n_H;
    }
    else
    {
        m_F = n_H;
        n_F = m_H;
    }

    // Create the flat matrix object. Default to column-major storage.
    FLA_Obj_create( datatype, m_F, n_F, 0, 0, F );

    return FLA_SUCCESS;
}

References FLA_Check_null_pointer(), and FLA_Check_valid_real_trans().

Referenced by FLASH_Obj_create_flat_conf_to_hier().

{
  FLA_Error e_val;

  e_val = FLA_Check_valid_real_trans( trans );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( F );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_create_flat_copy_of_hier().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( F );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_helper ( FLA_Bool  without_buffer,
FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t b_m,
dim_t b_n,
FLA_Obj H 
)

References FLA_Check_error_level(), FLA_free(), FLA_malloc(), FLA_Obj_create(), FLA_Obj_create_without_buffer(), FLA_Obj_free_without_buffer(), FLASH_Obj_create_helper_check(), and FLASH_Obj_create_hierarchy().

Referenced by FLASH_Obj_create(), FLASH_Obj_create_ext(), FLASH_Obj_create_without_buffer(), and FLASH_Obj_create_without_buffer_ext().

{
    dim_t     i;
    FLA_Obj   flat_matrix;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_helper_check( without_buffer, datatype, m, n, depth, b_m, b_n, H );

    if ( depth == 0 )
    {
        // Base case: create a single contiguous matrix block. If we are
        // creating an object with a buffer, then we use column-major order.
        if ( without_buffer == FALSE )
            FLA_Obj_create( datatype, m, n, 0, 0, H );
        else
            FLA_Obj_create_without_buffer( datatype, m, n, H );
    }
    else
    {
        // We need temporary arrays the same length as the blocksizes arrays.
        dim_t* elem_sizes_m  = ( dim_t * ) FLA_malloc( depth * sizeof( dim_t ) );
        dim_t* elem_sizes_n  = ( dim_t * ) FLA_malloc( depth * sizeof( dim_t ) );
        dim_t* depth_sizes_m = ( dim_t * ) FLA_malloc( depth * sizeof( dim_t ) );
        dim_t* depth_sizes_n = ( dim_t * ) FLA_malloc( depth * sizeof( dim_t ) );
        dim_t* m_offsets     = ( dim_t * ) FLA_malloc( depth * sizeof( dim_t ) );
        dim_t* n_offsets     = ( dim_t * ) FLA_malloc( depth * sizeof( dim_t ) );
        
        // Fill two sets of arrays: elem_sizes_m/elem_sizes_n and depth_sizes_m/
        // depth_sizes_n.
        //  - elem_sizes_m[i] will contain the number of numerical elements that span
        //    the row dimension of a block at the ith level of the hierarchy. This is
        //    just the product of all row blocksizes "internal" to and including the
        //    current blocking level. (The elem_sizes_n array tracks similar values
        //    in the column dimension.)
        //  - depth_sizes_m[i] is similar to elem_sizes_m[i]. The only difference is
        //    that instead of tracking the number of numerical elements in the row
        //    dimension, it tracks the number of "storage" blocks that span the m
        //    dimension of a block at the ith level, where the m dimension of a
        //    storage block is the block size given in b_m[depth-1], ie:
        //    the inner-most row dimension block size. (The depth_sizes_n array
        //    tracks similar values in the column dimension.)
        elem_sizes_m[depth-1]  = b_m[depth-1];
        elem_sizes_n[depth-1]  = b_n[depth-1];
        depth_sizes_m[depth-1] = 1;
        depth_sizes_n[depth-1] = 1;
        for ( i = depth - 1; i > 0; --i )
        {
            elem_sizes_m[i-1]  = elem_sizes_m[i]  * b_m[i-1];
            elem_sizes_n[i-1]  = elem_sizes_n[i]  * b_n[i-1];
            depth_sizes_m[i-1] = depth_sizes_m[i] * b_m[i-1];
            depth_sizes_n[i-1] = depth_sizes_n[i] * b_n[i-1];
        }
    
        // Initialize the m_offsets and n_offsets arrays to zero.
        for ( i = 0; i < depth; i++ )
        {
            m_offsets[i] = 0;
            n_offsets[i] = 0;
        }

        // Create a "flat" matrix object. All leaf-level child objects will refer
        // to various offsets within this object's buffer. Whether we create the
        // object with row- or column-major storage is moot, since either way it
        // will be a 1-by-mn length matrix which we will partition through later
        // on in FLASH_Obj_create_hierarchy(). Note that it is IMPORTANT that the
        // matrix be 1-by-mn, and NOT m-by-n, since we want to use the 1x2
        // partitioning routines to walk through it as we attach various parts of
        // the buffer to the matrix hierarchy.
        if ( without_buffer == FALSE )
            FLA_Obj_create( datatype, 1, m*n, 0, 0, &flat_matrix );
        else
            FLA_Obj_create_without_buffer( datatype, m, n, &flat_matrix );
        
        // Recursively create the matrix hierarchy.
        FLASH_Obj_create_hierarchy( datatype, m, n, depth, elem_sizes_m, elem_sizes_n, flat_matrix, H, 0, depth, depth_sizes_m, depth_sizes_n, m_offsets, n_offsets );
        
        // Free the flat_matrix object, but not its buffer. If we created a
        // normal object with a buffer, we don't want to free the buffer because
        // it is being used by the hierarchical objected we just created. If we
        // created a bufferless object, we don't want to free the buffer because
        // there was no buffer allocated in the first place.
        FLA_Obj_free_without_buffer( &flat_matrix );
        
        // Free the local arrays.
        FLA_free( elem_sizes_m );
        FLA_free( elem_sizes_n );
        FLA_free( depth_sizes_m );
        FLA_free( depth_sizes_n );
        FLA_free( m_offsets );
        FLA_free( n_offsets );
    }

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_helper_check ( FLA_Bool  without_buffer,
FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t b_m,
dim_t b_n,
FLA_Obj H 
)

References FLA_Check_null_pointer(), and FLA_Check_valid_datatype().

Referenced by FLASH_Obj_create_helper().

{
  FLA_Error e_val;

  e_val = FLA_Check_valid_datatype( datatype );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( b_m );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( b_n );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  // A value of depth < 0 should cause an error.

  // Values of m < 1, n < 1 should cause an error. (or < 0?)

  // First depth entries in blocksize_m, _n should be checked; values < 1 should cause error.

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_hier_conf_to_flat ( FLA_Trans  trans,
FLA_Obj  F,
dim_t  depth,
dim_t b_mn,
FLA_Obj H 
)

References FLA_Check_error_level(), FLA_Obj_datatype(), FLA_Obj_length(), FLA_Obj_width(), FLASH_Obj_create(), and FLASH_Obj_create_hier_conf_to_flat_check().

Referenced by FLASH_Obj_create_hier_copy_of_flat().

{
    FLA_Datatype datatype;
    dim_t        m_H, n_H;
    dim_t        m_F, n_F;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_hier_conf_to_flat_check( trans, F, depth, b_mn, H );

    // Acquire the numerical datatype, length, and width of the flat matrix
    // object.
    datatype = FLA_Obj_datatype( F );
    m_F      = FLA_Obj_length( F );
    n_F      = FLA_Obj_width( F );

    // Factor in the transposition, if requested.
    if ( trans == FLA_NO_TRANSPOSE )
    {
        m_H = m_F;
        n_H = n_F;
    }
    else
    {
        m_H = n_F;
        n_H = m_F;
    }

    // Create the hierarchical matrix object.
    FLASH_Obj_create( datatype, m_H, n_H, depth, b_mn, H );

    return FLA_SUCCESS;
}

References FLA_Check_null_pointer(), and FLA_Check_valid_real_trans().

Referenced by FLASH_Obj_create_hier_conf_to_flat().

{
  FLA_Error e_val;

  e_val = FLA_Check_valid_real_trans( trans );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( blocksizes );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  // A value of depth < 0 should cause an error.

  // First depth entries in blocksize should be checked; values < 1 should cause error.

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_hier_conf_to_flat_ext ( FLA_Trans  trans,
FLA_Obj  F,
dim_t  depth,
dim_t b_m,
dim_t b_n,
FLA_Obj H 
)

References FLA_Check_error_level(), FLA_Obj_datatype(), FLA_Obj_length(), FLA_Obj_width(), FLASH_Obj_create_ext(), and FLASH_Obj_create_hier_conf_to_flat_ext_check().

Referenced by FLASH_Obj_create_hier_copy_of_flat_ext().

{
    FLA_Datatype datatype;
    dim_t        m_H, n_H;
    dim_t        m_F, n_F;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_hier_conf_to_flat_ext_check( trans, F, depth, b_m, b_n, H );

    // Acquire the numerical datatype, length, and width of the flat matrix
    // object.
    datatype = FLA_Obj_datatype( F );
    m_F      = FLA_Obj_length( F );
    n_F      = FLA_Obj_width( F );

    // Factor in the transposition, if requested.
    if ( trans == FLA_NO_TRANSPOSE )
    {
        m_H = m_F;
        n_H = n_F;
    }
    else
    {
        m_H = n_F;
        n_H = m_F;
    }

    // Create the hierarchical matrix object.
    FLASH_Obj_create_ext( datatype, m_H, n_H, depth, b_m, b_n, H );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_hier_conf_to_flat_ext_check ( FLA_Trans  trans,
FLA_Obj  F,
dim_t  depth,
dim_t b_m,
dim_t b_n,
FLA_Obj H 
)

References FLA_Check_null_pointer(), and FLA_Check_valid_real_trans().

Referenced by FLASH_Obj_create_hier_conf_to_flat_ext().

{
  FLA_Error e_val;

  e_val = FLA_Check_valid_real_trans( trans );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( b_m );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( b_n );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  // A value of depth < 0 should cause an error.

  // First depth entries in blocksize should be checked; values < 1 should cause error.

  return FLA_SUCCESS;
}

References FLA_Check_error_level(), FLASH_Copy_flat_to_hier(), FLASH_Obj_create_hier_conf_to_flat(), and FLASH_Obj_create_hier_copy_of_flat_check().

Referenced by FLASH_CAQR_UT_inc_create_hier_matrices(), FLASH_LQ_UT_create_hier_matrices(), FLASH_LU_incpiv_create_hier_matrices(), FLASH_QR_UT_create_hier_matrices(), FLASH_QR_UT_inc_create_hier_matrices(), and FLASH_UDdate_UT_inc_create_hier_matrices().

{
    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_hier_copy_of_flat_check( F, depth, b_mn, H );

    // Create a hierarchical object conformal to the flat object.
    FLASH_Obj_create_hier_conf_to_flat( FLA_NO_TRANSPOSE, F, depth, b_mn, H );

    // Initialize the contents of the hierarchical matrix object with the
    // contents of the flat matrix object.
    FLASH_Copy_flat_to_hier( F, 0, 0, *H );
    
    return FLA_SUCCESS;
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_create_hier_copy_of_flat().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( blocksizes );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  // A value of depth < 0 should cause an error.

  // First depth entries in blocksize should be checked; values < 1 should cause error.

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_hier_copy_of_flat_ext ( FLA_Obj  F,
dim_t  depth,
dim_t b_m,
dim_t b_n,
FLA_Obj H 
)

References FLA_Check_error_level(), FLASH_Copy_flat_to_hier(), FLASH_Obj_create_hier_conf_to_flat_ext(), and FLASH_Obj_create_hier_copy_of_flat_ext_check().

{
    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_hier_copy_of_flat_ext_check( F, depth, b_m, b_n, H );

    // Create a hierarchical object conformal to the flat object.
    FLASH_Obj_create_hier_conf_to_flat_ext( FLA_NO_TRANSPOSE, F, depth, b_m, b_n, H );

    // Initialize the contents of the hierarchical matrix object with the
    // contents of the flat matrix object.
    FLASH_Copy_flat_to_hier( F, 0, 0, *H );
    
    return FLA_SUCCESS;
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_create_hier_copy_of_flat_ext().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( b_m );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( b_n );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  // A value of depth < 0 should cause an error.

  // First depth entries in blocksize should be checked; values < 1 should cause error.

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_hierarchy ( FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t elem_sizes_m,
dim_t elem_sizes_n,
FLA_Obj  flat_matrix,
FLA_Obj H,
unsigned long  id,
dim_t  depth_overall,
dim_t depth_sizes_m,
dim_t depth_sizes_n,
dim_t m_offsets,
dim_t n_offsets 
)

References FLA_Obj_view::base, FLA_Check_error_level(), FLA_Cont_with_1x3_to_1x2(), FLA_Obj_attach_buffer(), FLA_Obj_buffer_at_view(), FLA_Obj_create_ext(), FLA_Obj_create_without_buffer(), FLA_Obj_datatype_size(), FLA_Obj_free_without_buffer(), FLA_Obj_width(), FLA_Part_1x2(), FLA_Repart_1x2_to_1x3(), FLASH_Obj_create_hierarchy(), FLASH_Obj_create_hierarchy_check(), FLASH_Queue_set_block_size(), FLA_Obj_struct::id, FLA_Obj_struct::m_index, and FLA_Obj_struct::n_index.

Referenced by FLASH_Obj_create_helper(), and FLASH_Obj_create_hierarchy().

{
    dim_t    i, j, b;
    dim_t    next_m, next_n;
    dim_t    num_m, num_n;
    dim_t    m_inner, n_inner;
    dim_t    elem_size_m_cur;
    dim_t    elem_size_n_cur;
    FLA_Obj  FL, FR, F0, F1, F2;
    FLA_Obj* buffer_H;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_create_hierarchy_check( datatype, m, n, depth, elem_sizes_m, elem_sizes_n, flat_matrix, H, id, depth_overall, depth_sizes_m, depth_sizes_n, m_offsets, n_offsets );

    if ( depth == 0 )
    {
        // If we're asked to create a zero-depth matrix, we interpret that as
        // a request to create leaf-level objects using the remaining portion
        // of the segment of the flat_matrix buffer that was passed in.
        FLA_Obj_create_without_buffer( datatype, m, n, H );
        FLA_Obj_attach_buffer( FLA_Obj_buffer_at_view( flat_matrix ), 1, m, H );
#ifdef FLA_ENABLE_SUPERMATRIX
        FLASH_Queue_set_block_size( m * n * FLA_Obj_datatype_size( datatype ) );
#endif
        H->base->id = id;

        // Fill in the m_index and n_index variables, which identify the
        // location of the current leaf node, in units of storage blocks,
        // within the overall matrix.
        for ( i = 0; i < depth_overall; i++ )
        {
            H->base->m_index += m_offsets[i] * depth_sizes_m[i];
            H->base->n_index += n_offsets[i] * depth_sizes_n[i];
        }
    }
    else
    {
        // The "current" level's elem_size value. That is, the number of numerical
        // scalar elements along one side of a full block on the current level,
        // for the row and column dimensions.
        elem_size_m_cur = elem_sizes_m[0];
        elem_size_n_cur = elem_sizes_n[0];

        // Compute the number of rows and columns in the current hierarchical
        // level of blocking.
        num_m = m / elem_size_m_cur + ( (m % elem_size_m_cur) ? 1 : 0 );
        num_n = n / elem_size_n_cur + ( (n % elem_size_n_cur) ? 1 : 0 );

        // The total number of scalar elements contained within/below this level
        // of the hierarchy. (The edge cases are handled by the computation of
        // next_m and next_n below, since they are passed in as the new m and n
        // for the next recursive call.)
        m_inner = m;
        n_inner = n;
        
        // Create a matrix whose elements are FLA_Objs for the current level of
        // blocking.
        FLA_Obj_create_ext( datatype, FLA_MATRIX, num_m, num_n, m_inner, n_inner, 0, 0, H );

        if ( depth == depth_overall )
            id = H->base->id;
        else
            H->base->id = id;

        // Grab the buffer from the new hierarchical object. This is an array of
        // FLA_Objs.
        buffer_H = ( FLA_Obj* ) FLA_Obj_buffer_at_view( *H );
        
        // Prepare to partition through the flat matrix so we can further allocate
        // segments of it to the various hierarchical sub-matrices. (The second
        // case occurs when the current function is called with a flat_matrix
        // argument that was created without a buffer.)
        if ( FLA_Obj_buffer_at_view( flat_matrix ) != NULL )
            FLA_Part_1x2( flat_matrix, &FL, &FR, 0, FLA_LEFT );
        else
            FLA_Obj_create_without_buffer( datatype, 0, 0, &F1 );
        
        for ( j = 0; j < num_n; ++j )
        {
            // Determine the number of elements along the column dimension
            // that will be contained within the submatrix referenced by
            // the (i,j)th FLA_MATRIX element in the current matrix.
            if ( j != num_n-1 || (n % elem_size_n_cur) == 0 )
                next_n = elem_size_n_cur;
            else
                next_n = n % elem_size_n_cur;
            
            n_offsets[depth_overall-depth] = j;
                        
            for ( i = 0; i < num_m; ++i )
            {           
                // Determine the number of elements along the row dimension
                // that will be contained within the submatrix referenced by
                // the (i,j)th FLA_MATRIX element in the current matrix.
                if ( i != num_m-1 || (m % elem_size_m_cur) == 0 )
                    next_m = elem_size_m_cur;
                else
                    next_m = m % elem_size_m_cur;

                m_offsets[depth_overall-depth] = i;
                
                // Partition the next m*n elements from the flat matrix so we can
                // "attach" them to the hierarchical matrices contained within the
                // (i,j)th FLA_MATRIX object.
                if ( FLA_Obj_buffer_at_view( flat_matrix ) != NULL )
                {
                    b = min( FLA_Obj_width( FR ), next_m * next_n );
                    FLA_Repart_1x2_to_1x3( FL,  /**/ FR,        &F0, /**/ &F1, &F2,
                                           b, FLA_RIGHT );
                }
                
                // Recursively call ourselves, with the appropriate parameters for
                // the next deeper level in the matrix hierarchy.
                FLASH_Obj_create_hierarchy( datatype, next_m, next_n, depth-1, &elem_sizes_m[1], &elem_sizes_n[1], F1, &buffer_H[j*num_m + i], id, depth_overall, depth_sizes_m, depth_sizes_n, m_offsets, n_offsets );

                // Continue with the repartitioning.
                if ( FLA_Obj_buffer_at_view( flat_matrix ) != NULL )
                {
                    FLA_Cont_with_1x3_to_1x2( &FL,  /**/ &FR,        F0, F1, /**/ F2,
                                              FLA_LEFT );
                }
            }
        }

        // Free the temporary flat matrix subpartition object, but only if it was
        // created to begin with. Since it would have been created without a
        // buffer, we must free it in a similar manner.
        if ( FLA_Obj_buffer_at_view( flat_matrix ) == NULL )
            FLA_Obj_free_without_buffer( &F1 );
    }
    
    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_hierarchy_check ( FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t elem_sizes_m,
dim_t elem_sizes_n,
FLA_Obj  flat_matrix,
FLA_Obj H,
unsigned long  id,
dim_t  depth_overall,
dim_t depth_sizes_m,
dim_t depth_sizes_n,
dim_t m_offsets,
dim_t n_offsets 
)

References FLA_Check_null_pointer(), and FLA_Check_valid_datatype().

Referenced by FLASH_Obj_create_hierarchy().

{
  FLA_Error e_val;

  e_val = FLA_Check_valid_datatype( datatype );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( elem_sizes_m );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( elem_sizes_n );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( depth_sizes_m );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( depth_sizes_n );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( m_offsets );
  FLA_Check_error_code( e_val );

  e_val = FLA_Check_null_pointer( n_offsets );
  FLA_Check_error_code( e_val );

  // A value of depth < 0 should cause an error.

  // Values of m < 1, n < 1 should cause an error. (or < 0?)

  // First depth entries in depth_sizes_m,_n elem_sizes_m,_n m_,n_offsets should be checked; values < 1 should cause error.

  return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_without_buffer ( FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t b_mn,
FLA_Obj H 
)

References FLASH_Obj_create_helper().

{
    FLASH_Obj_create_helper( TRUE, datatype, m, n, depth, b_mn, b_mn, H );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_create_without_buffer_ext ( FLA_Datatype  datatype,
dim_t  m,
dim_t  n,
dim_t  depth,
dim_t b_m,
dim_t b_n,
FLA_Obj H 
)

References FLASH_Obj_create_helper().

Referenced by FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), and FLASH_Part_create_2x2().

{
    FLASH_Obj_create_helper( TRUE, datatype, m, n, depth, b_m, b_n, H );

    return FLA_SUCCESS;
}

References FLA_Obj_base_buffer(), and FLA_Obj_elemtype().

Referenced by FLASH_Apply_CAQ_UT_inc_create_workspace(), FLASH_Apply_pivots(), FLASH_Apply_Q_UT_create_workspace(), FLASH_Apply_Q_UT_inc_create_workspace(), FLASH_Apply_QUD_UT_inc_create_workspace(), FLASH_FS_incpiv(), FLASH_LQ_UT(), FLASH_LU_incpiv(), FLASH_LU_piv(), FLASH_Obj_create_conf_to(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), FLASH_Part_create_2x2(), and FLASH_QR_UT().

{
    FLA_Elemtype elemtype;
    FLA_Obj*     buffer_H;
    dim_t        depth = 0;

    // Recurse through the hierarchy to the first leaf node. We initialize
    // the recursion here:
    elemtype = FLA_Obj_elemtype( H );
    buffer_H = ( FLA_Obj* ) FLA_Obj_base_buffer( H );

    while ( elemtype == FLA_MATRIX )
    {
        ++depth;

        // Get the element type of the top-leftmost underlying object. Also,
        // get a pointer to the first element of the top-leftmost object and
        // assume that it is of type FLA_Obj* in case elemtype is once again
        // FLA_MATRIX.
        elemtype = FLA_Obj_elemtype( buffer_H[0] );
        buffer_H = ( FLA_Obj * ) FLA_Obj_base_buffer( buffer_H[0] );
    }

    // At this point, the value of depth represents the depth of the matrix
    // hierarchy.
    return depth;
}

References FLA_Obj_base_buffer(), and FLA_Obj_elemtype().

Referenced by FLASH_Obj_free().

{
    FLA_Elemtype elemtype;
    FLA_Obj*     buffer_H;

    // Recurse through the hierarchy to the first leaf node to gain access
    // to the address of the actual numerical data buffer (ie: the "flat"
    // matrix object used in FLASH_Obj_create()). We initialize the search
    // here:
    elemtype = FLA_Obj_elemtype( H );
    buffer_H  = ( FLA_Obj* ) FLA_Obj_base_buffer( H );

    while ( elemtype == FLA_MATRIX )
    {
        elemtype = FLA_Obj_elemtype( buffer_H[0] );
        buffer_H = ( FLA_Obj* ) FLA_Obj_base_buffer( buffer_H[0] );
    }

    // At this point, the value in buffer_H is a pointer to the array that
    // holds the numerical data.
    return ( void* ) buffer_H;
}

References FLASH_Copy_hier_to_flat().

{
    FLASH_Copy_hier_to_flat( 0, 0, H, F );

    return FLA_SUCCESS;
}
void FLASH_Obj_free ( FLA_Obj H)

References FLA_Check_error_level(), FLA_free(), FLA_Obj_elemtype(), FLA_Obj_free(), FLA_shfree(), FLASH_Obj_extract_buffer(), FLASH_Obj_free_check(), and FLASH_Obj_free_hierarchy().

Referenced by FLASH_CAQR_UT_inc_solve(), FLASH_Eig_gest(), FLASH_LQ_UT_solve(), FLASH_LU_incpiv_opt1(), FLASH_QR_UT_inc_opt1(), FLASH_QR_UT_inc_solve(), FLASH_QR_UT_solve(), FLASH_Random_spd_matrix(), and FLASH_UDdate_UT_inc_update_rhs().

{
    FLA_Obj* buffer_H;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_free_check( H );

    // Free the object according to whether it contains a hierarchy.
    if ( FLA_Obj_elemtype( *H ) == FLA_MATRIX )
    {
        // Extract a pointer to the data buffer that was parititioned across all
        // leaf-level submatrices.
        buffer_H = ( FLA_Obj * ) FLASH_Obj_extract_buffer( *H );
    
        // Free the data buffer. This works because FLASH_Obj_extract_buffer()
        // returns the starting address of the first element's buffer, which is
        // also the starting address of the entire buffer.
#ifdef FLA_ENABLE_SCC
        FLA_shfree( buffer_H );
#else
        FLA_free( buffer_H );
#endif

        // All that remains now is to free the interior of the matrix hierarchy.
        // This includes non-leaf buffers and their corresponding base objects
        // as well as leaf-level base objects.
        FLASH_Obj_free_hierarchy( H );
    }
    else
    {
        // If the matrix has no hierarchy, treat it like a flat object.
        FLA_Obj_free( H );
    }
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_free().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}

References FLA_Check_error_level(), FLA_Obj_base_buffer(), FLA_Obj_elemtype(), FLA_Obj_free(), FLA_Obj_free_without_buffer(), FLA_Obj_num_elem_alloc(), FLASH_Obj_free_hierarchy(), and FLASH_Obj_free_hierarchy_check().

Referenced by FLASH_Obj_free(), FLASH_Obj_free_hierarchy(), and FLASH_Obj_free_without_buffer().

{
    //dim_t    m_H, n_H, rs, cs, i, j;
    dim_t    i;
    dim_t    n_elem_alloc;
    FLA_Obj* buffer_H;

    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_free_hierarchy_check( H );

    // If the element type of H is FLA_SCALAR, then it has no children to
    // free, so free the base object. In order to avoid freeing the object's
    // data buffer, which would have already been freed en masse by now if
    // the calling function is FLASH_Obj_free(), we will call
    // FLA_Obj_free_without_buffer().
    if ( FLA_Obj_elemtype( *H ) == FLA_SCALAR )
    {
        FLA_Obj_free_without_buffer( H );
        return;
    }
    else
    {
        // Acquire the number of elements allocated when this node was
        // created.
        n_elem_alloc = FLA_Obj_num_elem_alloc( *H );

        // Acquire the array of objects contained inside of H.
        buffer_H = ( FLA_Obj* ) FLA_Obj_base_buffer( *H );

        // For each allocated submatrix in H...
        for ( i = 0; i < n_elem_alloc; ++i )
        {
            // Recurse with the ith element of the allocated buffer.
            FLASH_Obj_free_hierarchy( &buffer_H[i] );
        }

        // Finally, free the internal array of objects.
        FLA_Obj_free( H );
    }
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_free_hierarchy().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}

References FLA_Check_error_level(), FLA_Obj_elemtype(), FLA_Obj_free_without_buffer(), FLASH_Obj_free_hierarchy(), and FLASH_Obj_free_without_buffer_check().

Referenced by FLASH_Part_free_1x2(), FLASH_Part_free_2x1(), and FLASH_Part_free_2x2().

{
    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLASH_Obj_free_without_buffer_check( H );

    // Free the object according to whether it contains a hierarchy.
    if ( FLA_Obj_elemtype( *H ) == FLA_MATRIX )
    {
        // Skip freeing the numerical data buffer, since the object was
        // presumably created with FLASH_Obj_create_without_buffer().

        // Free the interior of the matrix hierarchy. This includes non-leaf
        // buffers and their corresponding base objects as well as leaf-level
        // base objects.
        FLASH_Obj_free_hierarchy( H );
    }
    else
    {
        // If the matrix has no hierarchy, treat it like a flat object with
        // no internal data buffer.
        FLA_Obj_free_without_buffer( H );
    }
}

References FLA_Check_null_pointer().

Referenced by FLASH_Obj_free_without_buffer().

{
  FLA_Error e_val;

  e_val = FLA_Check_null_pointer( H );
  FLA_Check_error_code( e_val );

  return FLA_SUCCESS;
}

References FLA_Cont_with_3x1_to_2x1(), FLA_Obj_elemtype(), FLA_Obj_length(), FLA_Part_2x1(), FLA_Repart_2x1_to_3x1(), and FLA_Obj_view::m_inner.

Referenced by FLA_Check_submatrix_dims_and_offset(), FLA_Obj_copy_view(), FLASH_Axpy_hierarchy(), FLASH_Copy_hierarchy(), FLASH_LU_find_zero_on_diagonal(), FLASH_Obj_create_conf_to(), FLASH_Obj_create_flat_conf_to_hier(), FLASH_Obj_scalar_max_dim(), FLASH_Obj_scalar_min_dim(), FLASH_Obj_scalar_vector_dim(), FLASH_Obj_show(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), and FLASH_Part_create_2x2().

{
    FLA_Obj  HT,              H0,
             HB,              H1,
                              H2;
    FLA_Obj* H1p;

    dim_t b = 0;

    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
        return FLA_Obj_length( H );

    if ( FLA_Obj_length( H ) == 0 )
        return 0;

    FLA_Part_2x1( H,    &HT,
                        &HB,            0, FLA_TOP );

    while ( FLA_Obj_length( HT ) < FLA_Obj_length( H ) )
    {
        FLA_Repart_2x1_to_3x1( HT,                &H0,
                            /* ** */            /* ** */
                                                  &H1,
                               HB,                &H2,        1, FLA_BOTTOM );

        /*------------------------------------------------------------*/

        H1p = FLASH_OBJ_PTR_AT( H1 );
        b += H1p->m_inner;

        /*------------------------------------------------------------*/

        FLA_Cont_with_3x1_to_2x1( &HT,                H0,
                                                      H1,
                                /* ** */           /* ** */   
                                  &HB,                H2,     FLA_TOP );
    }
  
    return b;
}

References FLA_Cont_with_1x3_to_1x2(), FLA_Obj_elemtype(), FLA_Obj_width(), FLA_Part_1x2(), FLA_Repart_1x2_to_1x3(), and FLA_Obj_view::n_inner.

Referenced by FLA_Check_submatrix_dims_and_offset(), FLA_Obj_copy_view(), FLASH_Apply_Q_UT_create_workspace(), FLASH_Axpy_hierarchy(), FLASH_CAQR_UT_inc_adjust_views(), FLASH_CAQR_UT_inc_solve(), FLASH_Copy_hierarchy(), FLASH_Obj_create_conf_to(), FLASH_Obj_create_flat_conf_to_hier(), FLASH_Obj_scalar_max_dim(), FLASH_Obj_scalar_min_dim(), FLASH_Obj_scalar_vector_dim(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), FLASH_Part_create_2x2(), FLASH_QR_UT_inc_create_hier_matrices(), and FLASH_QR_UT_inc_solve().

{
    FLA_Obj  HL,    HR,       H0,  H1,  H2;
    FLA_Obj* H1p;

    dim_t b = 0;

    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
        return FLA_Obj_width( H );

    if ( FLA_Obj_width( H ) == 0 )
        return 0;

    FLA_Part_1x2( H,    &HL,  &HR,      0, FLA_LEFT );

    while ( FLA_Obj_width( HL ) < FLA_Obj_width( H ) )
    {
        FLA_Repart_1x2_to_1x3( HL,  /**/ HR,        &H0, /**/ &H1, &H2,
                               1, FLA_RIGHT );

        /*------------------------------------------------------------*/

        H1p = FLASH_OBJ_PTR_AT( H1 );
        b += H1p->n_inner;

        /*------------------------------------------------------------*/

        FLA_Cont_with_1x3_to_1x2( &HL,  /**/ &HR,        H0, H1, /**/ H2,
                                  FLA_LEFT );
    }

    return b;
}
FLA_Error FLASH_Obj_show ( char *  header,
FLA_Obj  H,
char *  elem_format,
char *  footer 
)

References FLA_Obj_elemtype(), FLA_Obj_show(), FLASH_Obj_scalar_length(), FLASH_Obj_scalar_row_offset(), and FLASH_Obj_show_hierarchy().

{
    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
    {
        // Display the flat object.
        FLA_Obj_show( header, H, elem_format, footer );
    }
    else
    {
        dim_t m_scalar;
        dim_t i_view;
        dim_t i_abs;
        dim_t offm_scalar;

        // We want to print all m rows in the FLASH view.
        m_scalar = FLASH_Obj_scalar_length( H );

        // Get the scalar offset of the overall FLASH view relative to the
        // top-left corner of the overall object to which the view belongs.
        offm_scalar = FLASH_Obj_scalar_row_offset( H );

//printf( "flash_view_show: %d\n", m_scalar );
//printf( "flash_view_show: %d\n", offm_scalar );
    
        printf( "%s\n", header );

        for ( i_view = 0; i_view < m_scalar; ++i_view )
        {
            // Convert the relative view index to an absolute index.
            i_abs = offm_scalar + i_view; 
        
            // Print the ith row of the FLASH object H.
            FLASH_Obj_show_hierarchy( H, i_abs, elem_format );
            printf( "\n" );
        }

        printf( "%s\n", footer );
    }

    return FLA_SUCCESS;
}
FLA_Error FLASH_Obj_show_hierarchy ( FLA_Obj  H,
dim_t  i,
char *  elem_format 
)

References FLA_Cont_with_1x3_to_1x2(), FLA_Obj_buffer_at_view(), FLA_Obj_col_stride(), FLA_Obj_datatype(), FLA_Obj_elemtype(), FLA_Obj_row_offset(), FLA_Obj_row_stride(), FLA_Obj_width(), FLA_Part_1x2(), FLA_Part_2x1(), FLA_Repart_1x2_to_1x3(), FLASH_Obj_scalar_length_tl(), and FLASH_Obj_show_hierarchy().

Referenced by FLASH_Obj_show(), and FLASH_Obj_show_hierarchy().

{
    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
    {
        FLA_Datatype datatype = FLA_Obj_datatype( H );
        dim_t        m        = FLA_Obj_width( H );
        dim_t        rs       = FLA_Obj_row_stride( H );
        dim_t        cs       = FLA_Obj_col_stride( H );
        dim_t        j;

        // At this point, i is an absolute row index. We subtract out the
        // row offset of the view so that the index is relative to the view.
        i = i - FLA_Obj_row_offset( H );

        if ( datatype == FLA_INT )
        {
            int* buffer = FLA_Obj_buffer_at_view( H );

            for ( j = 0; j < m; ++j )
            {
                printf( elem_format, buffer[ j*cs + i*rs ] );
                printf( " " );
            }
        }
        else if ( datatype == FLA_FLOAT )
        {
            float* buffer = FLA_Obj_buffer_at_view( H );

            for ( j = 0; j < m; ++j )
            {
                printf( elem_format, buffer[ j*cs + i*rs ] );
                printf( " " );
            }
        }
        else if ( datatype == FLA_DOUBLE )
        {
            double* buffer = FLA_Obj_buffer_at_view( H );

            for ( j = 0; j < m; ++j )
            {
                printf( elem_format, buffer[ j*cs + i*rs ] );
                printf( " " );
            }
        }
        else if ( datatype == FLA_COMPLEX )
        {
            scomplex* buffer = FLA_Obj_buffer_at_view( H );

            for ( j = 0; j < m; ++j )
            {
                printf( elem_format, buffer[ j*cs + i*rs ].real,
                                     buffer[ j*cs + i*rs ].imag );
                printf( " " );
            }
        }
        else if ( datatype == FLA_DOUBLE_COMPLEX )
        {
            dcomplex* buffer = FLA_Obj_buffer_at_view( H );

            for ( j = 0; j < m; ++j )
            {
                printf( elem_format, buffer[ j*cs + i*rs ].real,
                                     buffer[ j*cs + i*rs ].imag );
                printf( " " );
            }
        }
        else
        {
            FLA_Check_error_code( FLA_NOT_YET_IMPLEMENTED );
        }
    }
    else
    {
        FLA_Obj  HT,
                 HB;
        FLA_Obj  HBL,  HBR,     H10, H11, H12;
        dim_t b_m_scalar;
        dim_t offm_local;
        dim_t i_next;

        // Get the scalar length of the top-left block.
        b_m_scalar = FLASH_Obj_scalar_length_tl( H );

#if 0
printf( "\n------------------------\n" );
printf( "b_m_scalar      %d\n", b_m_scalar );
printf( "i               %d\n", i );
#endif

        // Compute the offset of the matrix block, relative to the current
        // view, that contains the ith row of the matrix.
        offm_local      = ( i ) / b_m_scalar - FLA_Obj_row_offset( H );
        i_next          = ( i ) % b_m_scalar;

#if 0
printf( "row offset        %d\n", FLA_Obj_row_offset( H ) );
printf( "offm_local        %d\n", offm_local );
printf( "i_next            %d\n", i_next );
#endif

        FLA_Part_2x1( H,    &HT,
                            &HB,       offm_local, FLA_TOP );

        FLA_Part_1x2(  HB,    &HBL,  &HBR,      0, FLA_LEFT );

        while ( FLA_Obj_width( HBL ) < FLA_Obj_width( HB ) )
        {
            FLA_Repart_1x2_to_1x3( HBL,  /**/ HBR,        &H10, /**/ &H11, &H12,
                                   1, FLA_RIGHT );

            // ------------------------------------------------------

            FLASH_Obj_show_hierarchy( *FLASH_OBJ_PTR_AT( H11 ),
                                      i_next, elem_format );

            // ------------------------------------------------------

            FLA_Cont_with_1x3_to_1x2( &HBL,  /**/ &HBR,        H10, H11, /**/ H12,
                                      FLA_LEFT );
        }
    }

    return FLA_SUCCESS;
}
FLA_Error FLASH_Part_create_1x2 ( FLA_Obj  A,
FLA_Obj AL,
FLA_Obj AR,
dim_t  n_cols,
FLA_Side  side 
)

References FLA_Check_error_level(), FLA_free(), FLA_malloc(), FLA_Part_1x2_check(), FLASH_Obj_adjust_views(), FLASH_Obj_base_scalar_length(), FLASH_Obj_base_scalar_width(), FLASH_Obj_blocksizes(), FLASH_Obj_create_without_buffer_ext(), FLASH_Obj_datatype(), FLASH_Obj_depth(), FLASH_Obj_scalar_col_offset(), FLASH_Obj_scalar_length(), FLASH_Obj_scalar_row_offset(), and FLASH_Obj_scalar_width().

{
    FLA_Datatype dt_A;
    dim_t        m_A,  n_A;
    dim_t        m_A_base, n_A_base;
    dim_t        m_AL, n_AL;
    dim_t        m_AR, n_AR;
    dim_t        depth;
    dim_t*       b_m;
    dim_t*       b_n;
    dim_t        offm_A,  offn_A;
    dim_t        offm_AL, offn_AL;
    dim_t        offm_AR, offn_AR;

    if ( FLA_Check_error_level() == FLA_FULL_ERROR_CHECKING )
        FLA_Part_1x2_check( A,    AL, AR,     n_cols, side );

    // Safeguard: if n_cols > n, reduce n_cols to n.
    if ( n_cols > FLASH_Obj_scalar_width( A ) )
        n_cols = FLASH_Obj_scalar_width( A );

    // Acquire various properties of the hierarchical matrix object.
    dt_A     = FLASH_Obj_datatype( A );
    m_A      = FLASH_Obj_scalar_length( A );
    n_A      = FLASH_Obj_scalar_width( A );
    offm_A   = FLASH_Obj_scalar_row_offset( A );
    offn_A   = FLASH_Obj_scalar_col_offset( A );
    m_A_base = FLASH_Obj_base_scalar_length( A );
    n_A_base = FLASH_Obj_base_scalar_width( A );
    depth    = FLASH_Obj_depth( A );

    // Allocate a pair of temporary arrays for the blocksizes, whose lengths
    // are equal to the object's hierarchical depth.
    b_m = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );
    b_n = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );

    // Accumulate the blocksizes into the blocksize buffers.
    FLASH_Obj_blocksizes( A, b_m, b_n );

    // Adjust n_cols to be (n - n_cols) if the side specified is on the
    // right so that the right values get assigned below.
    if ( side == FLA_RIGHT ) n_cols = n_A - n_cols;

    // Set the dimensions of the partitions.
    m_AL = m_A;
    n_AL = n_cols;
    m_AR = m_A;
    n_AR = n_A - n_cols;

    // Set the offsets.
    offm_AL = offm_A + 0;
    offn_AL = offn_A + 0;
    offm_AR = offm_A + 0;
    offn_AR = offn_A + n_AL;
    
    // Create bufferless hierarhical objects that have the desired dimensions
    // for the views.
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, AL );
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, AR );

    // Recursively walk the hierarchy and adjust the views so that they
    // collectively refer to the absolute offsets given, and attach the
    // leaf-level numerical buffers of A to the new views.
    FLASH_Obj_adjust_views( TRUE, offm_AL, offn_AL, m_AL, n_AL, A, AL );
    FLASH_Obj_adjust_views( TRUE, offm_AR, offn_AR, m_AR, n_AR, A, AR );

    // Free the temporary blocksize buffers.
    FLA_free( b_m );
    FLA_free( b_n );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Part_create_2x1 ( FLA_Obj  A,
FLA_Obj AT,
FLA_Obj AB,
dim_t  n_rows,
FLA_Side  side 
)

References FLA_Check_error_level(), FLA_free(), FLA_malloc(), FLA_Part_2x1_check(), FLASH_Obj_adjust_views(), FLASH_Obj_base_scalar_length(), FLASH_Obj_base_scalar_width(), FLASH_Obj_blocksizes(), FLASH_Obj_create_without_buffer_ext(), FLASH_Obj_datatype(), FLASH_Obj_depth(), FLASH_Obj_scalar_col_offset(), FLASH_Obj_scalar_length(), FLASH_Obj_scalar_row_offset(), and FLASH_Obj_scalar_width().

Referenced by FLASH_CAQR_UT_inc_solve(), and FLASH_QR_UT_inc_solve().

{
    FLA_Datatype dt_A;
    dim_t        m_A,  n_A;
    dim_t        m_A_base, n_A_base;
    dim_t        m_AT, n_AT;
    dim_t        m_AB, n_AB;
    dim_t        depth;
    dim_t*       b_m;
    dim_t*       b_n;
    dim_t        offm_A,  offn_A;
    dim_t        offm_AT, offn_AT;
    dim_t        offm_AB, offn_AB;

    if ( FLA_Check_error_level() == FLA_FULL_ERROR_CHECKING )
        FLA_Part_2x1_check( A,    AT,
                                  AB,     n_rows, side );

    // Safeguard: if n_rows > m, reduce n_rows to m.
    if ( n_rows > FLASH_Obj_scalar_length( A ) )
        n_rows = FLASH_Obj_scalar_length( A );

    // Acquire various properties of the hierarchical matrix view.
    dt_A     = FLASH_Obj_datatype( A );
    m_A      = FLASH_Obj_scalar_length( A );
    n_A      = FLASH_Obj_scalar_width( A );
    offm_A   = FLASH_Obj_scalar_row_offset( A );
    offn_A   = FLASH_Obj_scalar_col_offset( A );
    m_A_base = FLASH_Obj_base_scalar_length( A );
    n_A_base = FLASH_Obj_base_scalar_width( A );
    depth    = FLASH_Obj_depth( A );

    // Allocate a pair of temporary arrays for the blocksizes, whose lengths
    // are equal to the object's hierarchical depth.
    b_m = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );
    b_n = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );

    // Accumulate the blocksizes into the blocksize buffers.
    FLASH_Obj_blocksizes( A, b_m, b_n );

    // Adjust n_rows to be (m - n_rows) if the side specified is on the
    // bottom so that the right values get assigned below.
    if ( side == FLA_BOTTOM ) n_rows = m_A - n_rows;

    // Set the dimensions of the partitions.
    m_AT = n_rows;
    n_AT = n_A;
    m_AB = m_A - n_rows;
    n_AB = n_A;

    // Set the offsets.
    offm_AT = offm_A + 0;
    offn_AT = offn_A + 0;
    offm_AB = offm_A + m_AT;
    offn_AB = offn_A + 0;
    
    // Create bufferless hierarhical objects that have the desired dimensions
    // for the views.
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, AT );
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, AB );

/*
printf( "depth      %d\n", depth );
printf( "b_m/n[0]   %d %d\n", b_m[0], b_n[0] );
printf( "b_m/n_tl   %d %d\n", FLASH_Obj_scalar_length_tl( A ), FLASH_Obj_scalar_width_tl( A ) );
printf( "m/n_A_base %d %d\n", m_A_base, n_A_base );
printf( "offm/n_AT: %d %d\n", offm_AT, offn_AT );
printf( "m/n_AT:    %d %d\n", m_AT, n_AT );
printf( "offm/n_AB: %d %d\n", offm_AB, offn_AB );
printf( "m/n_AB:    %d %d\n", m_AB, n_AB );
printf( "A is       %d %d\n", FLA_Obj_length( A ), FLA_Obj_width( A ) );
printf( "AT is      %d %d\n", FLA_Obj_length( *AT ), FLA_Obj_width( *AT ) );
printf( "AB is      %d %d\n", FLA_Obj_length( *AB ), FLA_Obj_width( *AB ) );
*/

    // Recursively walk the hierarchy and adjust the views so that they
    // collectively refer to the absolute offsets given, and attach the
    // leaf-level numerical buffers of A to the new views.
    FLASH_Obj_adjust_views( TRUE, offm_AT, offn_AT, m_AT, n_AT, A, AT );
    FLASH_Obj_adjust_views( TRUE, offm_AB, offn_AB, m_AB, n_AB, A, AB );

    // Free the temporary blocksize buffers.
    FLA_free( b_m );
    FLA_free( b_n );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Part_create_2x2 ( FLA_Obj  A,
FLA_Obj ATL,
FLA_Obj ATR,
FLA_Obj ABL,
FLA_Obj ABR,
dim_t  n_rows,
dim_t  n_cols,
FLA_Side  side 
)

References FLA_Check_error_level(), FLA_free(), FLA_malloc(), FLA_Part_2x2_check(), FLASH_Obj_adjust_views(), FLASH_Obj_base_scalar_length(), FLASH_Obj_base_scalar_width(), FLASH_Obj_blocksizes(), FLASH_Obj_create_without_buffer_ext(), FLASH_Obj_datatype(), FLASH_Obj_depth(), FLASH_Obj_scalar_col_offset(), FLASH_Obj_scalar_length(), FLASH_Obj_scalar_row_offset(), and FLASH_Obj_scalar_width().

Referenced by FLASH_Axpy_flat_to_hier(), FLASH_Axpy_hier_to_flat(), FLASH_Copy_flat_to_hier(), and FLASH_Copy_hier_to_flat().

{
    FLA_Datatype dt_A;
    dim_t        m_A_base, n_A_base;
    dim_t        m_A,  n_A;
    dim_t        m_ATL, n_ATL;
    dim_t        m_ABL, n_ABL;
    dim_t        m_ATR, n_ATR;
    dim_t        m_ABR, n_ABR;
    dim_t        depth;
    dim_t*       b_m;
    dim_t*       b_n;
    dim_t        offm_A,  offn_A;
    dim_t        offm_ATL, offn_ATL;
    dim_t        offm_ABL, offn_ABL;
    dim_t        offm_ATR, offn_ATR;
    dim_t        offm_ABR, offn_ABR;

    if ( FLA_Check_error_level() == FLA_FULL_ERROR_CHECKING )
        FLA_Part_2x2_check( A,   ATL, ATR,
                                 ABL, ABR,   n_rows, n_cols, side );

    // Safeguard: if n_rows > m, reduce n_rows to m.
    if ( n_rows > FLASH_Obj_scalar_length( A ) )
        n_rows = FLASH_Obj_scalar_length( A );

    // Safeguard: if n_cols > n, reduce n_cols to n.
    if ( n_cols > FLASH_Obj_scalar_width( A ) )
        n_cols = FLASH_Obj_scalar_width( A );

    // Acquire various properties of the hierarchical matrix object.
    dt_A     = FLASH_Obj_datatype( A );
    m_A      = FLASH_Obj_scalar_length( A );
    n_A      = FLASH_Obj_scalar_width( A );
    offm_A   = FLASH_Obj_scalar_row_offset( A );
    offn_A   = FLASH_Obj_scalar_col_offset( A );
    m_A_base = FLASH_Obj_base_scalar_length( A );
    n_A_base = FLASH_Obj_base_scalar_width( A );
    depth    = FLASH_Obj_depth( A );

    // Allocate a pair of temporary arrays for the blocksizes, whose lengths
    // are equal to the object's hierarchical depth.
    b_m = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );
    b_n = ( dim_t* ) FLA_malloc( depth * sizeof( dim_t ) );

    // Accumulate the blocksizes into the blocksize buffers.
    FLASH_Obj_blocksizes( A, b_m, b_n );

    // Adjust n_rows to be (m - n_rows) if the quadrant specified is on
    // the bottom so that the right values get assigned below. Do the same
    // for n_cols.
    if ( side == FLA_BL || side == FLA_BR ) n_rows = m_A - n_rows;
    if ( side == FLA_TR || side == FLA_BR ) n_cols = n_A - n_cols;

    // Set the dimensions of the partitions.
    m_ATL = n_rows;
    n_ATL = n_cols;
    m_ABL = m_A - n_rows;
    n_ABL = n_cols;
    m_ATR = n_rows;
    n_ATR = n_A - n_cols;
    m_ABR = m_A - n_rows;
    n_ABR = n_A - n_cols;

    // Set the offsets.
    offm_ATL = offm_A + 0;
    offn_ATL = offn_A + 0;
    offm_ABL = offm_A + m_ATL;
    offn_ABL = offn_A + 0;
    offm_ATR = offm_A + 0;
    offn_ATR = offn_A + n_ATL;
    offm_ABR = offm_A + m_ATL;
    offn_ABR = offn_A + n_ATL;
    
    // Create bufferless hierarhical objects that have the desired dimensions
    // for the views.
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, ATL );
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, ABL );
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, ATR );
    FLASH_Obj_create_without_buffer_ext( dt_A, m_A_base, n_A_base, depth, b_m, b_n, ABR );

    // Recursively walk the hierarchy and adjust the views so that they
    // collectively refer to the absolute offsets given, and attach the
    // leaf-level numerical buffers of A to the new views.
    FLASH_Obj_adjust_views( TRUE, offm_ATL, offn_ATL, m_ATL, n_ATL, A, ATL );
    FLASH_Obj_adjust_views( TRUE, offm_ABL, offn_ABL, m_ABL, n_ABL, A, ABL );
    FLASH_Obj_adjust_views( TRUE, offm_ATR, offn_ATR, m_ATR, n_ATR, A, ATR );
    FLASH_Obj_adjust_views( TRUE, offm_ABR, offn_ABR, m_ABR, n_ABR, A, ABR );

    // Free the temporary blocksize buffers.
    FLA_free( b_m );
    FLA_free( b_n );

    return FLA_SUCCESS;
}
FLA_Error FLASH_Part_free_2x2 ( FLA_Obj ATL,
FLA_Obj ATR,
FLA_Obj ABL,
FLA_Obj ABR 
)

References FLA_Obj_buffer_at_view(), FLA_Obj_col_stride(), FLA_Obj_elemtype(), FLA_Obj_length(), FLA_Obj_row_stride(), FLA_Obj_width(), and FLASH_print_struct_helper().

{
    dim_t    m_H, n_H, rs, cs, i, j;
    FLA_Obj* buffer_temp;

    m_H = FLA_Obj_length( H );
    n_H = FLA_Obj_width( H );
    rs  = FLA_Obj_row_stride( H );
    cs  = FLA_Obj_col_stride( H );

    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
        FLASH_print_struct_helper( H, 0 );
    else
    {
        for ( j = 0; j < n_H; ++j )
        {
            for ( i = 0; i < m_H; ++i )
            {
                buffer_temp = ( FLA_Obj* ) FLA_Obj_buffer_at_view( H );

                FLASH_print_struct_helper( buffer_temp[ j*cs + i*rs ], 0 );
            }
        }
    }
}
void FLASH_print_struct_helper ( FLA_Obj  H,
int  indent 
)

References FLA_Obj_buffer_at_view(), FLA_Obj_col_stride(), FLA_Obj_datatype(), FLA_Obj_elemtype(), FLA_Obj_length(), FLA_Obj_row_stride(), FLA_Obj_width(), and FLASH_print_struct_helper().

Referenced by FLASH_print_struct(), and FLASH_print_struct_helper().

{
    dim_t    m_H, n_H, rs, cs, i, j, k;
    FLA_Obj* buffer_temp;

    for ( i = 0; i < indent; ++i )
        fprintf( stdout, "  " );

    if ( FLA_Obj_elemtype( H ) == FLA_SCALAR )
    {
        fprintf( stdout, "LEAF (%3d | rs %3lu | cs %3lu | %3lu x %3lu | addr %p)\n",
                         FLA_Obj_datatype( H ),
                         FLA_Obj_row_stride( H ), FLA_Obj_col_stride( H ),
                         FLA_Obj_length( H ), FLA_Obj_width( H ),
                         FLA_Obj_buffer_at_view( H ) );
        fflush( stdout );
    }
    else
    {
        m_H = FLA_Obj_length( H );
        n_H = FLA_Obj_width( H );
        rs  = FLA_Obj_row_stride( H );
        cs  = FLA_Obj_col_stride( H );
        
        fprintf( stdout, "MATRIX (%lux%lu):%d - %p\n",
                         m_H, n_H,
                         FLA_Obj_datatype( H ),
                         FLA_Obj_buffer_at_view( H ) );
        fflush( stdout );
        
        for ( j = 0; j < n_H; ++j )
        {
            for ( i = 0; i < m_H; ++i )
            {
                for ( k = 0; k < indent; ++k )
                    fprintf( stdout, "  " );
                
                buffer_temp = ( FLA_Obj* ) FLA_Obj_buffer_at_view( H );

                FLASH_print_struct_helper( buffer_temp[ j*cs + i*rs ],
                                           indent + 1 );
            }
        }
    }
}