Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 2d3311d1 authored by Mathieu Faverge's avatar Mathieu Faverge
Browse files

Merge branch 'treewalk' into 'master'

Treewalk

See merge request !3
parents d5a94704 72a3ff38
No related branches found
No related tags found
1 merge request!3Treewalk
;; C style for Emacs, to assist in following DAGuE coding conventions (originally from PETSc project)
((nil . ((indent-tabs-mode . nil)
(tab-width . 8)
(show-trailing-whitespace . t)))
(c-mode . ((c-tab-always-indent . t)
(c-basic-offset . 4)
(c-comment-only-line-offset . 0)
(c-hanging-braces-alist . ((substatement-open after)
(brace-list-open after)
(brace-entry-open)
(defun-open after)
(class-open after)
(inline-open after)
(block-open after)
(block-close . c-snug-do-while)
(statement-case-open after)
(substatement after)))
(c-hanging-colons-alist . ((member-init-intro before)
(inher-intro)
(case-label after)
(label after)
(access-label after)))
(c-hanging-semi&comma-criteria . (c-semi&comma-no-newlines-before-nonblanks))
(c-cleanup-list . (scope-operator
brace-else-brace
brace-elseif-brace
brace-catch-brace
empty-defun-braces
list-close-comma
defun-close-semi))
(c-offsets-alist . ((inexpr-class . +)
(inexpr-statement . +)
(lambda-intro-cont . +)
(inlambda . c-lineup-inexpr-block)
(template-args-cont c-lineup-template-args +)
(incomposition . +)
(inmodule . +)
(innamespace . +)
(inextern-lang . +)
(composition-close . 0)
(module-close . 0)
(namespace-close . 0)
(extern-lang-close . 0)
(composition-open . 0)
(module-open . 0)
(namespace-open . 0)
(extern-lang-open . 0)
(objc-method-call-cont c-lineup-ObjC-method-call-colons c-lineup-ObjC-method-call +)
(objc-method-args-cont . c-lineup-ObjC-method-args)
(objc-method-intro .
[0])
(friend . 0)
(cpp-define-intro c-lineup-cpp-define +)
(cpp-macro-cont . +)
(cpp-macro .
[0])
(inclass . +)
(stream-op . c-lineup-streamop)
(arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist)
(arglist-cont c-lineup-gcc-asm-reg 0)
(arglist-intro . +)
(catch-clause . 0)
(else-clause . 0)
(do-while-closure . 0)
(label . 2)
(access-label . -)
(substatement-label . 2)
(substatement . +)
(statement-case-open . 0)
(statement-case-intro . +)
(statement-block-intro . +)
(statement-cont . +)
(statement . 0)
(brace-entry-open . 0)
(brace-list-entry . 0)
(brace-list-intro . +)
(brace-list-close . 0)
(brace-list-open . 0)
(block-close . 0)
(inher-cont . c-lineup-multi-inher)
(inher-intro . +)
(member-init-cont . c-lineup-multi-inher)
(member-init-intro . +)
(annotation-var-cont . +)
(annotation-top-cont . 0)
(topmost-intro-cont . c-lineup-topmost-intro-cont)
(topmost-intro . 0)
(knr-argdecl . 0)
(func-decl-cont . +)
(inline-close . 0)
(inline-open . +)
(class-close . 0)
(class-open . 0)
(defun-block-intro . +)
(defun-close . 0)
(defun-open . 0)
(string . c-lineup-dont-change)
(arglist-close . c-lineup-arglist)
(substatement-open . 0)
(case-label . 0)
(block-open . 0)
(c . 1)
(comment-intro . 0)
(knr-argdecl-intro . -)))
(fill-column . 80))))
Makefile 0 → 100644
CC = gcc
CFLAGS = -Iinclude -Wall -g3
LDFLAGS = -lm
LIBHQR=src/libhqr.a
default: testing_pivgen testing_treewalk
src/queue.o: include/queue.h include/common.h
src/libhqr.o: include/common.h include/libhqr.h
src/libhqr_dbg.o: include/common.h include/libhqr.h
src/libhqr_systolic.o: include/common.h include/libhqr.h
src/treewalk.o: include/common.h include/libhqr.h include/queue.h
$(LIBHQR): src/libhqr.o src/libhqr_dbg.o src/libhqr_systolic.o src/treewalk.o src/queue.o
ar cr $@ $^
%.o : %.c
$(CC) -c $< -o $@ $(CFLAGS)
testing_pivgen : testings/testing_pivgen.o ${LIBHQR}
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
testing_treewalk : testings/testing_treewalk.c ${LIBHQR}
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
clean :
rm -f include/*~
rm -f src/*.o src/*~
rm -f testings/*.o testings/*~
cleanall: clean
rm -f ${LIBHQR}
rm -f testing_pivgen testing_treewalk
/**
*
* @file common.h
*
* Header file for common maccro
*
* @copyright 2010-2017 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
*
* @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
*
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-04-05
*
*/
#ifndef _COMMON_H_
#define _COMMON_H_
#undef BEGIN_C_DECLS
#undef END_C_DECLS
#if defined(c_plusplus) || defined(__cplusplus)
# define BEGIN_C_DECLS extern "C" {
# define END_C_DECLS }
#else
# define BEGIN_C_DECLS /* empty */
# define END_C_DECLS /* empty */
#endif
#endif /* _COMMON_H_ */
/* /**
* Copyright (c) 2010 The University of Tennessee and The University *
* of Tennessee Research Foundation. All rights * @file libhqr.h
* reserved. *
* @copyright 2010-2017 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
*
* @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
* *
* @precisions normal z -> z c d s * @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-03-21
* *
*/ */
#ifndef _LIBHQR_H_ #ifndef _LIBHQR_H_
#define _LIBHQR_H_ #define _LIBHQR_H_
#undef BEGIN_C_DECLS #include "common.h"
#undef END_C_DECLS
#if defined(c_plusplus) || defined(__cplusplus)
# define BEGIN_C_DECLS extern "C" {
# define END_C_DECLS }
#else
#define BEGIN_C_DECLS /* empty */
#define END_C_DECLS /* empty */
#endif
BEGIN_C_DECLS BEGIN_C_DECLS
static inline int libhqr_imin(int a, int b){ static inline int libhqr_imin(int a, int b){
return (a > b) ? b : a; return (a > b) ? b : a;
} }
static inline int libhqr_imax(int a, int b){ static inline int libhqr_imax(int a, int b){
return (a > b) ? a : b; return (a > b) ? a : b;
} }
static inline int libhqr_iceil(int a, int b){ static inline int libhqr_iceil(int a, int b){
return (a + b - 1) / b; return (a + b - 1) / b;
} }
/* /**
* LIBHQR_KILLED_BY_TS needs to be set to 0 for all variant of QR * @brief Define to which tree level the tile belongs to.
* factorization to distinguish TT kernels from TS kernels in jdf *
* Four levels of trees are available:
* - The top one (LIBHQR_KILLED_BY_DISTTREE) is meant to be the communication
* tree, and should be of size the number of nodes per panel
* - The middle one (LIBHQR_KILLED_BY_LOCALTREE) is meant to create parallelism
* within a single node between local tiles
* - LIBHQR_KILLED_BY_TS is the lowest level tree that is used to keep a high
* efficiency kernels within each node.
* - LIBHQR_KILLED_BY_DOMINO is the connection tree between the distributed and
* the local trees in order to generate a better pipeline for tall and skinny
* matrices.
*
* @remark LIBHQR_KILLED_BY_TS needs to be stay 0 for all variant of QR
* factorizations in order to distinguish TT kernels from TS kernels in compuations
*
*/ */
typedef enum libhqr_type_ { typedef enum libhqr_type_ {
LIBHQR_KILLED_BY_TS = 0, LIBHQR_KILLED_BY_TS = 0,
...@@ -44,6 +59,9 @@ typedef enum libhqr_type_ { ...@@ -44,6 +59,9 @@ typedef enum libhqr_type_ {
LIBHQR_KILLED_BY_DISTTREE = 3, LIBHQR_KILLED_BY_DISTTREE = 3,
} libhqr_type_e; } libhqr_type_e;
/**
* @brief Define the type of trees that can be used for the reduction.
*/
typedef enum libhqr_tree_ { typedef enum libhqr_tree_ {
LIBHQR_FLAT_TREE = 0, LIBHQR_FLAT_TREE = 0,
LIBHQR_GREEDY_TREE = 1, LIBHQR_GREEDY_TREE = 1,
...@@ -52,26 +70,24 @@ typedef enum libhqr_tree_ { ...@@ -52,26 +70,24 @@ typedef enum libhqr_tree_ {
LIBHQR_GREEDY1P_TREE = 4, LIBHQR_GREEDY1P_TREE = 4,
} libqr_tree_e; } libqr_tree_e;
/**
* @brief Define the type of factorization to apply: QR or LQ.
*/
typedef enum libhqr_typefacto_ { typedef enum libhqr_typefacto_ {
LIBHQR_QR = 0, LIBHQR_QR = 0,
LIBHQR_LQ = 1, LIBHQR_LQ = 1,
} libhqr_typefacto_e; } libhqr_typefacto_e;
/**
* @brief Minimal structure to define the shape of the matrix to factorize.
*/
typedef struct libhqr_tiledesc_s{ typedef struct libhqr_tiledesc_s{
int mt; int mt; /**< The number of rows of tiles */
int nt; int nt; /**< The number of columns of tiles */
int nodes; int nodes; /**< The number of nodes involved in the data distribution */
int p; int p; /**< The number of nodes per column in the data distribution */
} libhqr_tiledesc_t; } libhqr_tiledesc_t;
typedef struct libhqr_file_tile_s{
struct libhqr_file_tile_s *prev;
struct libhqr_file_tile_s *next;
int numero;
}libhqr_file_tile_t;
struct libhqr_tree_s; struct libhqr_tree_s;
typedef struct libhqr_tree_s libhqr_tree_t; typedef struct libhqr_tree_s libhqr_tree_t;
...@@ -79,75 +95,72 @@ typedef struct libhqr_context_s libhqr_context_t; ...@@ -79,75 +95,72 @@ typedef struct libhqr_context_s libhqr_context_t;
struct libhqr_tree_s { struct libhqr_tree_s {
/** /**
* getnbgeqrf * @brief Return the number of geqrt/gelqt kernels in the column/row k
* @param[in] arg arguments specific to the reduction tree used * @param[in] arg arguments specific to the reduction tree used
* @param[in] k Factorization step * @param[in] k Factorization step
*
* @return The number of geqrt applied to the panel k * @return The number of geqrt applied to the panel k
*/ */
int (*getnbgeqrf)( const libhqr_tree_t *arg, int k ); int (*getnbgeqrf)( const libhqr_tree_t *arg, int k );
/** /**
* getm: * @brief Compute the row/column index of the i^th geqrt/gelqt kernel in the
* @param[in] arg arguments specific to the reduction tree used * column/row k
* @param[in] k Factorization step * @param[in] arg arguments specific to the reduction tree used
* @param[in] i Index of the geqrt applied on the panel k * @param[in] k Factorization step
* * @param[in] i Index of the geqrt applied on the panel k
* @return The row index of the i-th geqrt applied on the panel k * @return The row index of the i-th geqrt applied on the panel k
*/ */
int (*getm)( const libhqr_tree_t *arg, int k, int i ); int (*getm)( const libhqr_tree_t *arg, int k, int i );
/** /**
* geti: * @brief Compute the index of the row/column m in the list of geqrt/gelqt
* @param[in] arg arguments specific to the reduction tree used * kernels in the column/row k
* @param[in] k Factorization step * @param[in] arg arguments specific to the reduction tree used
* @param[in] m Row index where a geqrt is applied on panel k * @param[in] k Factorization step
* * @param[in] m Row index where a geqrt is applied on panel k
* @returns the index in the list of geqrt applied to panel k * @return the index in the list of geqrt applied to panel k
*/ */
int (*geti)( const libhqr_tree_t *qrtree, int k, int m ); int (*geti)( const libhqr_tree_t *qrtree, int k, int m );
/** /**
* gettype: * @brief Return the tree level the tile belongs to.
* @param[in] arg arguments specific to the reduction tree used * @param[in] arg arguments specific to the reduction tree used
* @param[in] k Factorization step * @param[in] k Factorization step
* @param[in] m Row index of the one we request the type * @param[in] m Row index of the one we request the type
* * @return The type of kernel used to kill the row m at step k:
* @returns The type of kernel used to kill the row m at step k: * - 0 if it is a TS kernel
* - 0 if it is a TS kernel * - >0 otherwise. (TT kernel)
* - >0 otherwise. (TT kernel)
*/ */
int (*gettype)( const libhqr_tree_t *qrtree, int k, int m ); int (*gettype)( const libhqr_tree_t *qrtree, int k, int m );
/** /**
* currpiv * @brief Return the row/column index of the pivot for m at the step k.
* @param[in] arg arguments specific to the reduction tree used * @param[in] arg arguments specific to the reduction tree used
* @param[in] k Factorization step * @param[in] k Factorization step
* @param[in] m line you want to eliminate * @param[in] m line you want to eliminate
* * @return The index of the row annihilating the row m at step k
* @return The index of the row annihilating the row m at step k
*/ */
int (*currpiv)( const libhqr_tree_t *qrtree, int k, int m ); int (*currpiv)( const libhqr_tree_t *qrtree, int k, int m );
/** /**
* nextpiv * @brief Return the next row/column index for which p is a pivot at the step k.
* @param[in] arg arguments specific to the reduction tree used * @param[in] arg arguments specific to the reduction tree used
* @param[in] k Factorization step * @param[in] k Factorization step
* @param[in] p line currently used as an annihilator to kill the row m at step k * @param[in] p line currently used as an annihilator to kill the row m at step k
* @param[in] m line actually annihilated by the row p at step k. (k < m <= MT) * @param[in] m line actually annihilated by the row p at step k. (k < m <= MT)
* m = MT to find the first time p is used as an annihilator during step k * m = MT to find the first time p is used as an annihilator during step k
* *
* @return the next line that the row p will kill during step k * @return the next line that the row p will kill during step k
* desc->mt if p will never be used again as an annihilator. * desc->mt if p will never be used again as an annihilator.
*/ */
int (*nextpiv)(const libhqr_tree_t *qrtree, int k, int p, int m); int (*nextpiv)(const libhqr_tree_t *qrtree, int k, int p, int m);
/** /**
* prevpiv * @brief Return the previous row/column index for which p is a pivot at the step k.
* @param[in] arg arguments specific to the reduction tree used * @param[in] arg arguments specific to the reduction tree used
* @param[in] k Factorization step * @param[in] k Factorization step
* @param[in] p line currently used as an annihilator to kill the row m at step k * @param[in] p line currently used as an annihilator to kill the row m at step k
* @param[in] m line actually annihilated by the row p at step k. (k < m <= MT) * @param[in] m line actually annihilated by the row p at step k. (k < m <= MT)
* m = p to find the last time p has been used as an annihilator during step k * m = p to find the last time p has been used as an annihilator during step k
* *
* @return the previous line killed by the row p during step k * @return the previous line killed by the row p during step k
* desc->mt if p has never been used before as an annihilator. * desc->mt if p has never been used before as an annihilator.
*/ */
int (*prevpiv)(const libhqr_tree_t *qrtree, int k, int p, int m); int (*prevpiv)(const libhqr_tree_t *qrtree, int k, int p, int m);
...@@ -162,43 +175,30 @@ struct libhqr_tree_s { ...@@ -162,43 +175,30 @@ struct libhqr_tree_s {
}; };
int libhqr_systolic_init( libhqr_tree_t *qrtree, int libhqr_systolic_init( libhqr_tree_t *qrtree,
libhqr_typefacto_e trans, libhqr_tiledesc_t *A, libhqr_typefacto_e trans, libhqr_tiledesc_t *A,
int p, int q ); int p, int q );
void libhqr_systolic_finalize( libhqr_tree_t *qrtree ); void libhqr_systolic_finalize( libhqr_tree_t *qrtree );
int libhqr_svd_init( libhqr_tree_t *qrtree, int libhqr_svd_init( libhqr_tree_t *qrtree,
libhqr_typefacto_e trans, libhqr_tiledesc_t *A, libhqr_typefacto_e trans, libhqr_tiledesc_t *A,
int type_hlvl, int p, int nbcores_per_node, int ratio ); int type_hlvl, int p, int nbcores_per_node, int ratio );
int libhqr_hqr_init( libhqr_tree_t *qrtree, int libhqr_hqr_init( libhqr_tree_t *qrtree,
libhqr_typefacto_e trans, libhqr_tiledesc_t *A, libhqr_typefacto_e trans, libhqr_tiledesc_t *A,
int type_llvl, int type_hlvl, int type_llvl, int type_hlvl,
int a, int p, int domino, int tsrr ); int a, int p, int domino, int tsrr );
void libhqr_hqr_finalize( libhqr_tree_t *qrtree ); void libhqr_hqr_finalize( libhqr_tree_t *qrtree );
/*
* functions for manipulate file
*/
libhqr_file_tile_t *libhqr_file_tile_new (void);
void libhqr_file_tile_post (libhqr_file_tile_t ** file_tile,int numero);
int libhqr_file_tile_get (libhqr_file_tile_t ** file_tile);
void libhqr_file_tile_delete (libhqr_file_tile_t ** file_tile);
/* /*
* function for treewalk * function for treewalk
*/ */
void libhqr_treewalk(libhqr_tree_t *qrtree,int k); void libhqr_treewalk(const libhqr_tree_t *qrtree,int k);
/* /*
* Debugging functions * Debugging functions
*/ */
int libhqr_tree_check ( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ); int libhqr_tree_check ( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree );
void libhqr_tree_print_dag ( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, char *filename ); void libhqr_tree_print_dag ( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, char *filename );
void libhqr_tree_print_type ( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ); void libhqr_tree_print_type ( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree );
......
/**
*
* @file queue.h
*
* Queue module for the treewalk algorithm.
*
* @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
*
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-03-21
*
*/
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include "common.h"
BEGIN_C_DECLS
typedef struct libhqr_queue_tile_s{
struct libhqr_queue_tile_s *prev;
struct libhqr_queue_tile_s *next;
int numero;
} libhqr_queue_tile_t;
libhqr_queue_tile_t *libhqr_queue_tile_new (void);
void libhqr_queue_tile_post (libhqr_queue_tile_t ** queue_tile, int numero);
int libhqr_queue_tile_get (libhqr_queue_tile_t ** queue_tile);
void libhqr_queue_tile_delete(libhqr_queue_tile_t ** queue_tile);
void libhqr_queue_tile_first (libhqr_queue_tile_t ** queue_tile);
void libhqr_queue_tile_prev (libhqr_queue_tile_t ** queue_tile);
void libhqr_queue_tile_last (libhqr_queue_tile_t ** queue_tile);
void libhqr_queue_tile_next (libhqr_queue_tile_t ** queue_tile);
END_C_DECLS
#endif /* _QUEUE_H_ */
/* /**
* Copyright (c) 2010 The University of Tennessee and The University *
* of Tennessee Research Foundation. All rights * @file libhqr.c
* reserved.
* *
* @precisions normal z -> s d c * @copyright 2010-2017 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
* *
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-03-21
* *
* This file contains all the function to describe the dependencies * This file contains all the function to describe the dependencies
* used in the Xgeqrf_param.jdf file. * used in the Xgeqrf_param.jdf file.
...@@ -75,9 +82,7 @@ ...@@ -75,9 +82,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
//#if defined(LIBHQR_HAVE_STRING_H)
#include <string.h> #include <string.h>
//#endif /* defined(PARSEC_HAVE_STRING_H) */
#define PRINT_PIVGEN 0 #define PRINT_PIVGEN 0
#ifdef PRINT_PIVGEN #ifdef PRINT_PIVGEN
......
/* /**
* Copyright (c) 2010 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* *
* @precisions normal z -> s d c * @file libhqr_dbg.c
* *
* @copyright 2010-2017 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* *
* This file contains all the function to describe the dependencies * @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* used in the Xgeqrf_param.jdf file. * Univ. Bordeaux. All rights reserved.
* The QR factorization done with this file relies on three levels:
* - the first one is using a flat tree with TS kernels. The
* height of this tree is defined by the parameter 'a'. If 'a'
* is set to A->mt, the factorization is identical to the one
* perform by PLASMA_zgeqrf.
* For all subdiagonal "macro-tiles", the line reduced is always the first.
* For all diagonal "macro-tiles", the factorization performed
* is identical to the one performed by PLASMA_zgeqrf.
* *
* - the third level is using a reduction tree of size 'p'. By * @version 1.0.0
* default, the parameter 'p' should be equal to the number of * @author Raphael Boucherie
* processors used for the computation, but can be set * @author Mathieu Faverge
* differently. (see further example). The type of tree used at * @date 2017-03-21
* this level is defined by the hlvl parameter. It can be flat
* or greedy.
* CODE DETAILS: This tree and all the function related to it
* are performing a QR factorization on a band matrix with 'p'
* the size of the band. All the functions take global indices
* as input and return global indices as output.
* *
* - Finally, a second 'low' level of reduction tree is applied.
* The size of this tree is induced by the parameters 'a' and 'p'
* from the first and third levels and is A->mt / ( p * a ). This
* tree is reproduced p times for each subset of tiles
* S_k = {i in [0, A->mt-1] \ i%p*a = k } with k in [0, p-1].
* The tree used for the reduction is defined by the llvl
* parameter and can be: flat, greedy, fibonacci or binary.
* CODE DETAILS: For commodity, the size of this tree is always
* ceil(A->mt / (p * a) ) inducing some extra tests in the code.
* All the functions related to this level of tree take as input
* the local indices in the A->mt / (p*a) matrix and the global
* k. They return the local index. The reductions are so
* performed on a trapezoidal matrices where the step is defined
* by a:
* <- min( lhlvl_mt, min( mt, nt ) ) ->
* __a__ a a
* | |_____
* | |_____
* | |_____
* llvl_mt = ceil(MT/ (a*p)) | |_____
* | |_____
* |___________________________________|
*
*
*
* At each step of the factorization, the lines of tiles are divided
* in 4 types:
* - QRPARAM_TILE_TS: They are the lines annihilated by a TS
* kernel, these lines are never used as an annihilator. They are
* the lines i, with 1 < (i/p)%a < a and i > (k+1)*p
* - QRPARAM_TILE_LOCALTT: They are the lines used as annhilitor
* in the TS kernels annihiling the QRPARAM_TILE_TS lines. They
* are themselves annihilated by the TT kernel of the low level
* reduction tree. The roots of the local trees are the lines i,
* with i/p = k.
* - QRPARAM_TILE_DOMINO: These are the lines that are
* annhilihated with a domino effect in the band defined by (i/p)
* <= k and i >= k
* - QRPARAM_TILE_DISTTT: These are the lines annihilated by the
* high level tree to reduce communications.
* These lines are defined by (i-k)/p = 0.
*/ */
#include "libhqr.h" #include "libhqr.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
//#if defined(LIBHQR_HAVE_STRING_H)
#include <string.h> #include <string.h>
//#endif /* defined(LIBHQR_HAVE_STRING_H) */
/* static int dplasma_qrtree_getinon0( const qr_piv_t *arg, */ /* static int libhqr_qrtree_getinon0( const qr_piv_t *arg, */
/* const int k, int i, int mt ); */ /* const int k, int i, int mt ); */
#define ENDCHECK( test, ret ) \ #define ENDCHECK( test, ret ) \
if ( !test ) \ if ( !test ) \
return ret; return ret;
int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree) int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree)
{ {
...@@ -98,204 +40,204 @@ int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree) ...@@ -98,204 +40,204 @@ int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree)
* Check Formula for NB geqrt * Check Formula for NB geqrt
*/ */
{ {
/* libhqr_tree_print_type( A, qrtree ); */ /* libhqr_tree_print_type( A, qrtree ); */
/* libhqr_tree_print_nbgeqrt( A, qrtree ); */ /* libhqr_tree_print_nbgeqrt( A, qrtree ); */
check = 1; check = 1;
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
nb = 0; nb = 0;
for (m=k; m < A->mt; m++) { for (m=k; m < A->mt; m++) {
if ( qrtree->gettype( qrtree, k, m ) > 0 ) if ( qrtree->gettype( qrtree, k, m ) > 0 )
nb++; nb++;
} }
if ( nb != qrtree->getnbgeqrf( qrtree, k ) ) { if ( nb != qrtree->getnbgeqrf( qrtree, k ) ) {
check = 0; check = 0;
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Check number of geqrt:\n" " Check number of geqrt:\n"
" For k=%d => return %d instead of %d", " For k=%d => return %d instead of %d",
a, p, A->mt, A->nt, k, qrtree->getnbgeqrf( qrtree, k ), nb ); a, p, A->mt, A->nt, k, qrtree->getnbgeqrf( qrtree, k ), nb );
} }
} }
ENDCHECK( check, 1 ); ENDCHECK( check, 1 );
} }
/* /*
* Check indices of geqrt * Check indices of geqrt
*/ */
{ {
int prevm = -1; int prevm = -1;
check = 1; check = 1;
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
/* libhqr_tree_print_geqrt_k( A, qrtree, k ); */ /* libhqr_tree_print_geqrt_k( A, qrtree, k ); */
nb = qrtree->getnbgeqrf( qrtree, k ); nb = qrtree->getnbgeqrf( qrtree, k );
prevm = -1; prevm = -1;
for (i=0; i < nb; i++) { for (i=0; i < nb; i++) {
m = qrtree->getm( qrtree, k, i ); m = qrtree->getm( qrtree, k, i );
/* /*
* getm has to be the inverse of geti * getm has to be the inverse of geti
*/ */
if ( i != qrtree->geti( qrtree, k, m) ) { if ( i != qrtree->geti( qrtree, k, m) ) {
check = 0; check = 0;
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Check indices of geqrt:\n" " Check indices of geqrt:\n"
" getm( k=%d, i=%d ) => m = %d && geti( k=%d, m=%d ) => i = %d\n", " getm( k=%d, i=%d ) => m = %d && geti( k=%d, m=%d ) => i = %d\n",
a, p, A->mt, A->nt, a, p, A->mt, A->nt,
k, i, m, k, m, qrtree->geti( qrtree, k, m)); k, i, m, k, m, qrtree->geti( qrtree, k, m));
} }
/* tile before the diagonal are factorized and /* tile before the diagonal are factorized and
* the m is a growing list (not true with round-robin inside TS) * the m is a growing list (not true with round-robin inside TS)
*/ */
else if ( (a == 1) && (( m < k ) || ( m < prevm )) ) { else if ( (a == 1) && (( m < k ) || ( m < prevm )) ) {
check = 0; check = 0;
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Check indices of geqrt:\n" " Check indices of geqrt:\n"
" getm( k=%d, i=%d ) => m = %d", " getm( k=%d, i=%d ) => m = %d",
a, p, A->mt, A->nt, k, i, m); a, p, A->mt, A->nt, k, i, m);
} }
#if 0 #if 0
else if ( m != qrtree->getinon0( qrtree, k, i, A->mt ) ) { else if ( m != qrtree->getinon0( qrtree, k, i, A->mt ) ) {
check = 0; check = 0;
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Check indices of geqrt:\n" " Check indices of geqrt:\n"
" getm( k=%d, i=%d ) => m = %d but should be %d", " getm( k=%d, i=%d ) => m = %d but should be %d",
a, p, A->mt, A->nt, k, i, m, qrtree->getinon0( qrtree, k, i, A->mt)); a, p, A->mt, A->nt, k, i, m, qrtree->getinon0( qrtree, k, i, A->mt));
} }
#endif #endif
prevm = m; prevm = m;
} }
} }
ENDCHECK( check, 2 ); ENDCHECK( check, 2 );
} }
/* /*
* Check number of exit in next * Check number of exit in next
*/ */
{ {
int s; int s;
check = 1; check = 1;
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
for(m=k; m<A->mt; m++) { for(m=k; m<A->mt; m++) {
nb = 0; nb = 0;
for(s=A->mt; s>k; s--) { for(s=A->mt; s>k; s--) {
if ( qrtree->nextpiv(qrtree, k, m, s) == A->mt ) if ( qrtree->nextpiv(qrtree, k, m, s) == A->mt )
nb++; nb++;
} }
if ( nb > 1 ) { if ( nb > 1 ) {
libhqr_tree_print_next_k( A, qrtree, k); libhqr_tree_print_next_k( A, qrtree, k);
libhqr_tree_print_prev_k( A, qrtree, k); libhqr_tree_print_prev_k( A, qrtree, k);
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Next of line %d for step %d contains more than one exit:\n", " Next of line %d for step %d contains more than one exit:\n",
a, p, A->mt, A->nt, a, p, A->mt, A->nt,
m, k); m, k);
check = 0; check = 0;
return 3; return 3;
} }
else if ( nb == 0 ) { else if ( nb == 0 ) {
libhqr_tree_print_next_k( A, qrtree, k); libhqr_tree_print_next_k( A, qrtree, k);
libhqr_tree_print_prev_k( A, qrtree, k); libhqr_tree_print_prev_k( A, qrtree, k);
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Next of line %d for step %d needs one exit:\n", " Next of line %d for step %d needs one exit:\n",
a, p, A->mt, A->nt, a, p, A->mt, A->nt,
m, k); m, k);
check = 0; check = 0;
return 3; return 3;
} }
} }
} }
ENDCHECK( check, 3 ); ENDCHECK( check, 3 );
} }
/* /*
* Check number of exit in prev * Check number of exit in prev
*/ */
{ {
int s; int s;
check = 1; check = 1;
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
for(m=k; m<A->mt; m++) { for(m=k; m<A->mt; m++) {
nb = 0; nb = 0;
for(s=k; s<A->mt; s++) { for(s=k; s<A->mt; s++) {
if ( qrtree->prevpiv(qrtree, k, m, s) == A->mt ) if ( qrtree->prevpiv(qrtree, k, m, s) == A->mt )
nb++; nb++;
} }
if ( nb > 1 ) { if ( nb > 1 ) {
libhqr_tree_print_next_k( A, qrtree, k); libhqr_tree_print_next_k( A, qrtree, k);
libhqr_tree_print_prev_k( A, qrtree, k); libhqr_tree_print_prev_k( A, qrtree, k);
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Prev of line %d for step %d contains more than one exit:\n", " Prev of line %d for step %d contains more than one exit:\n",
a, p, A->mt, A->nt, a, p, A->mt, A->nt,
m, k); m, k);
check = 0; check = 0;
return 3; return 3;
} }
else if ( nb == 0 ) { else if ( nb == 0 ) {
libhqr_tree_print_next_k( A, qrtree, k); libhqr_tree_print_next_k( A, qrtree, k);
libhqr_tree_print_prev_k( A, qrtree, k); libhqr_tree_print_prev_k( A, qrtree, k);
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Prev of line %d for step %d needs one exit:\n", " Prev of line %d for step %d needs one exit:\n",
a, p, A->mt, A->nt, a, p, A->mt, A->nt,
m, k); m, k);
check = 0; check = 0;
return 3; return 3;
} }
} }
} }
ENDCHECK( check, 3 ); ENDCHECK( check, 3 );
} }
/* /*
* Check next/prev * Check next/prev
*/ */
{ {
int start, next, prev; int start, next, prev;
check = 1; check = 1;
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
start = A->mt; start = A->mt;
for(m=k; m<A->mt; m++) { for(m=k; m<A->mt; m++) {
do { do {
next = qrtree->nextpiv(qrtree, k, m, start); next = qrtree->nextpiv(qrtree, k, m, start);
if ( next == A->mt ) if ( next == A->mt )
prev = qrtree->prevpiv(qrtree, k, m, m); prev = qrtree->prevpiv(qrtree, k, m, m);
else else
prev = qrtree->prevpiv(qrtree, k, m, next); prev = qrtree->prevpiv(qrtree, k, m, next);
if ( start != prev ) { if ( start != prev ) {
libhqr_tree_print_next_k( A, qrtree, k); libhqr_tree_print_next_k( A, qrtree, k);
libhqr_tree_print_prev_k( A, qrtree, k); libhqr_tree_print_prev_k( A, qrtree, k);
printf(" ----------------------------------------------------\n" printf(" ----------------------------------------------------\n"
" - a = %d, p = %d, M = %d, N = %d\n" " - a = %d, p = %d, M = %d, N = %d\n"
" Check next/prev:\n" " Check next/prev:\n"
" next( m=%d, k=%d, start=%d ) => %d && prev( m=%d, k=%d, start=%d ) => %d\n ( %d != %d )", " next( m=%d, k=%d, start=%d ) => %d && prev( m=%d, k=%d, start=%d ) => %d\n ( %d != %d )",
a, p, A->mt, A->nt, a, p, A->mt, A->nt,
m, k, start, next, m, k, next, prev, start, prev); m, k, start, next, m, k, next, prev, start, prev);
check = 0; check = 0;
return 3; return 3;
} }
start = next; start = next;
} while ( start != A->mt ); } while ( start != A->mt );
} }
} }
ENDCHECK( check, 3 ); ENDCHECK( check, 3 );
} }
return 0; return 0;
...@@ -311,29 +253,29 @@ void libhqr_tree_print_type( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ) ...@@ -311,29 +253,29 @@ void libhqr_tree_print_type( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree )
printf("\n------------ Localization = Type of pivot --------------\n"); printf("\n------------ Localization = Type of pivot --------------\n");
for(m=0; m<A->mt; m++) { for(m=0; m<A->mt; m++) {
printf("%3d | ", m); printf("%3d | ", m);
for (k=0; k<libhqr_imin(minMN, m+1); k++) { for (k=0; k<libhqr_imin(minMN, m+1); k++) {
printf( "%3d ", qrtree->gettype( qrtree, k, m ) ); printf( "%3d ", qrtree->gettype( qrtree, k, m ) );
} }
for (k=libhqr_imin(minMN, m+1); k<minMN; k++) { for (k=libhqr_imin(minMN, m+1); k<minMN; k++) {
printf( " " ); printf( " " );
} }
printf(" "); printf(" ");
printf("%2d,%3d | ", rank, lmg); printf("%2d,%3d | ", rank, lmg);
for (k=0; k<libhqr_imin(minMN, lmg+1); k++) { for (k=0; k<libhqr_imin(minMN, lmg+1); k++) {
printf( "%3d ", qrtree->gettype( qrtree, k, lmg) ); printf( "%3d ", qrtree->gettype( qrtree, k, lmg) );
} }
for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) { for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) {
printf( " " ); printf( " " );
} }
lm++; lmg+=qrtree->p; lm++; lmg+=qrtree->p;
if ( lmg >= A->mt ) { if ( lmg >= A->mt ) {
rank++; rank++;
lmg = rank; lmg = rank;
lm = 0; lm = 0;
} }
printf("\n"); printf("\n");
} }
} }
...@@ -346,29 +288,29 @@ void libhqr_tree_print_pivot( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ) ...@@ -346,29 +288,29 @@ void libhqr_tree_print_pivot( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree )
int rank = 0; int rank = 0;
printf("\n------------ Current Pivot--------------\n"); printf("\n------------ Current Pivot--------------\n");
for(m=0; m<A->mt; m++) { for(m=0; m<A->mt; m++) {
printf("%3d | ", m); printf("%3d | ", m);
for (k=0; k<libhqr_imin(minMN, m+1); k++) { for (k=0; k<libhqr_imin(minMN, m+1); k++) {
printf( "%3d ", qrtree->currpiv(qrtree, k, m) ); printf( "%3d ", qrtree->currpiv(qrtree, k, m) );
} }
for (k=libhqr_imin(minMN, m+1); k<minMN; k++) { for (k=libhqr_imin(minMN, m+1); k<minMN; k++) {
printf( " " ); printf( " " );
} }
printf(" "); printf(" ");
printf("%2d,%3d | ", rank, lmg); printf("%2d,%3d | ", rank, lmg);
for (k=0; k<libhqr_imin(minMN, lmg+1); k++) { for (k=0; k<libhqr_imin(minMN, lmg+1); k++) {
printf( "%3d ", qrtree->currpiv(qrtree, k, lmg) ); printf( "%3d ", qrtree->currpiv(qrtree, k, lmg) );
} }
for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) { for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) {
printf( " " ); printf( " " );
} }
lm++; lmg+=qrtree->p; lm++; lmg+=qrtree->p;
if ( lmg >= A->mt ) { if ( lmg >= A->mt ) {
rank++; rank++;
lmg = rank; lmg = rank;
lm = 0; lm = 0;
} }
printf("\n"); printf("\n");
} }
} }
...@@ -379,15 +321,15 @@ void libhqr_tree_print_next_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int ...@@ -379,15 +321,15 @@ void libhqr_tree_print_next_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int
printf( " " ); printf( " " );
for(s=A->mt; s>0; s--) for(s=A->mt; s>0; s--)
printf( "%3d ", s ); printf( "%3d ", s );
printf( "\n" ); printf( "\n" );
for(m=0; m<A->mt; m++) { for(m=0; m<A->mt; m++) {
printf("%3d | ", m); printf("%3d | ", m);
for(s=A->mt; s>0; s--) { for(s=A->mt; s>0; s--) {
printf( "%3d ", qrtree->nextpiv(qrtree, k, m, s) ); printf( "%3d ", qrtree->nextpiv(qrtree, k, m, s) );
} }
printf("\n"); printf("\n");
} }
} }
...@@ -398,15 +340,15 @@ void libhqr_tree_print_prev_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int ...@@ -398,15 +340,15 @@ void libhqr_tree_print_prev_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int
printf( " " ); printf( " " );
for(s=A->mt; s>-1; s--) for(s=A->mt; s>-1; s--)
printf( "%3d ", s ); printf( "%3d ", s );
printf( "\n" ); printf( "\n" );
for(m=0; m<A->mt; m++) { for(m=0; m<A->mt; m++) {
printf("%3d | ", m); printf("%3d | ", m);
for(s=A->mt; s>-1; s--) { for(s=A->mt; s>-1; s--) {
printf( "%3d ", qrtree->prevpiv(qrtree, k, m, s) ); printf( "%3d ", qrtree->prevpiv(qrtree, k, m, s) );
} }
printf("\n"); printf("\n");
} }
} }
...@@ -418,19 +360,19 @@ void libhqr_tree_print_perm( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int *p ...@@ -418,19 +360,19 @@ void libhqr_tree_print_perm( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int *p
printf("\n------------ Permutation --------------\n"); printf("\n------------ Permutation --------------\n");
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
printf( "%3d ", k ); printf( "%3d ", k );
} }
printf( "\n" ); printf( "\n" );
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
printf( "----" ); printf( "----" );
} }
printf( "\n" ); printf( "\n" );
for (m=0; m < A->mt+1; m++) { for (m=0; m < A->mt+1; m++) {
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
printf( "%3d ", perm[ k*(A->mt+1) + m ] ); printf( "%3d ", perm[ k*(A->mt+1) + m ] );
} }
printf( "\n" ); printf( "\n" );
} }
printf( "\n" ); printf( "\n" );
} }
...@@ -443,22 +385,22 @@ void libhqr_tree_print_nbgeqrt( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ) ...@@ -443,22 +385,22 @@ void libhqr_tree_print_nbgeqrt( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree )
printf("\n------------ Nb GEQRT per k --------------\n"); printf("\n------------ Nb GEQRT per k --------------\n");
printf(" k : "); printf(" k : ");
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
printf( "%3d ", k ); printf( "%3d ", k );
} }
printf( "\n" ); printf( "\n" );
printf(" Compute: "); printf(" Compute: ");
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
nb = 0; nb = 0;
for (m=k; m < A->mt; m++) { for (m=k; m < A->mt; m++) {
if ( qrtree->gettype(qrtree, k, m) > 0 ) if ( qrtree->gettype(qrtree, k, m) > 0 )
nb++; nb++;
} }
printf( "%3d ", nb ); printf( "%3d ", nb );
} }
printf( "\n" ); printf( "\n" );
printf(" Formula: "); printf(" Formula: ");
for (k=0; k<minMN; k++) { for (k=0; k<minMN; k++) {
printf( "%3d ", qrtree->getnbgeqrf( qrtree, k ) ); printf( "%3d ", qrtree->getnbgeqrf( qrtree, k ) );
} }
printf( "\n" ); printf( "\n" );
} }
...@@ -473,11 +415,11 @@ void libhqr_tree_print_geqrt_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int ...@@ -473,11 +415,11 @@ void libhqr_tree_print_geqrt_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int
printf( " m:"); printf( " m:");
nb = qrtree->getnbgeqrf( qrtree, k ); nb = qrtree->getnbgeqrf( qrtree, k );
for (i=0; i < nb; i++) { for (i=0; i < nb; i++) {
m = qrtree->getm( qrtree, k, i ); m = qrtree->getm( qrtree, k, i );
if ( i == qrtree->geti( qrtree, k, m) ) if ( i == qrtree->geti( qrtree, k, m) )
printf( "%3d ", m ); printf( "%3d ", m );
else else
printf( "x%2d ", qrtree->geti( qrtree, k, m) ); printf( "x%2d ", qrtree->geti( qrtree, k, m) );
} }
printf( "\n" ); printf( "\n" );
} }
...@@ -537,64 +479,64 @@ void libhqr_tree_print_dag( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, char *f ...@@ -537,64 +479,64 @@ void libhqr_tree_print_dag( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, char *f
/* Print header */ /* Print header */
fprintf(f, DAG_HEADER ); /*, A->mt+2, minMN+2 );*/ fprintf(f, DAG_HEADER ); /*, A->mt+2, minMN+2 );*/
for(m=0; m < A->mt; m++) { for(m=0; m < A->mt; m++) {
fprintf(f, DAG_LABELNODE, m, m, m); fprintf(f, DAG_LABELNODE, m, m, m);
} }
for(k=0; k<minMN; k++ ) { for(k=0; k<minMN; k++ ) {
int nb2reduce = A->mt - k - 1; int nb2reduce = A->mt - k - 1;
for(m=k; m < A->mt; m++) { for(m=k; m < A->mt; m++) {
fprintf(f, DAG_STARTNODE, m, A->mt, k, pos[m], m, color[ (m%qrtree->p) % DAG_NBCOLORS ]); fprintf(f, DAG_STARTNODE, m, A->mt, k, pos[m], m, color[ (m%qrtree->p) % DAG_NBCOLORS ]);
next[m] = qrtree->nextpiv( qrtree, k, m, A->mt); next[m] = qrtree->nextpiv( qrtree, k, m, A->mt);
} }
while( nb2reduce > 0 ) { while( nb2reduce > 0 ) {
memset(done, 0, A->mt * sizeof(int) ); memset(done, 0, A->mt * sizeof(int) );
for(m=A->mt-1; m > (k-1); m--) { for(m=A->mt-1; m > (k-1); m--) {
n = next[m]; n = next[m];
if ( next[n] != A->mt ) if ( next[n] != A->mt )
continue; continue;
if ( n != A->mt ) { if ( n != A->mt ) {
lpos = libhqr_imax( pos[m], pos[n] ); lpos = libhqr_imax( pos[m], pos[n] );
lpos++; lpos++;
pos[m] = lpos; pos[m] = lpos;
pos[n] = lpos; pos[n] = lpos;
fprintf(f, DAG_NODE, m, n, k, pos[m], m, color[ (m%qrtree->p) % DAG_NBCOLORS ]); fprintf(f, DAG_NODE, m, n, k, pos[m], m, color[ (m%qrtree->p) % DAG_NBCOLORS ]);
prev = qrtree->prevpiv( qrtree, k, m, n ); prev = qrtree->prevpiv( qrtree, k, m, n );
fprintf(f, DAG_EDGE_PIV, fprintf(f, DAG_EDGE_PIV,
m, prev, k, m, prev, k,
m, n, k, m, n, k,
color[ (m%qrtree->p) % DAG_NBCOLORS ]); color[ (m%qrtree->p) % DAG_NBCOLORS ]);
prev = qrtree->prevpiv( qrtree, k, n, n ); prev = qrtree->prevpiv( qrtree, k, n, n );
if ( qrtree->gettype(qrtree, k, n) == 0 ) if ( qrtree->gettype(qrtree, k, n) == 0 )
fprintf(f, DAG_EDGE_TS, fprintf(f, DAG_EDGE_TS,
n, prev, k, n, prev, k,
m, n, k, m, n, k,
color[ (m%qrtree->p) % DAG_NBCOLORS ]); color[ (m%qrtree->p) % DAG_NBCOLORS ]);
else else
fprintf(f, DAG_EDGE_TT, fprintf(f, DAG_EDGE_TT,
n, prev, k, n, prev, k,
m, n, k, m, n, k,
color[ (m%qrtree->p) % DAG_NBCOLORS ]); color[ (m%qrtree->p) % DAG_NBCOLORS ]);
next[m] = qrtree->nextpiv( qrtree, k, m, n); next[m] = qrtree->nextpiv( qrtree, k, m, n);
done[m] = done[n] = 1; done[m] = done[n] = 1;
nb2reduce--; nb2reduce--;
} }
} }
} }
} }
length = 0; length = 0;
for(m=0; m < A->mt; m++) { for(m=0; m < A->mt; m++) {
length = libhqr_imax(length, pos[m]); length = libhqr_imax(length, pos[m]);
} }
length++; length++;
for(k=0; k<length; k++) for(k=0; k<length; k++)
fprintf(f, DAG_LENGTHNODE, k, k, k); fprintf(f, DAG_LENGTHNODE, k, k, k);
fprintf(f, DAG_FOOTER); fprintf(f, DAG_FOOTER);
printf("Tic Max = %d\n", length-1); printf("Tic Max = %d\n", length-1);
......
/* /**
* Copyright (c) 2010 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* *
* @precisions normal z -> s d c * @file libhqr_systolic.c
* *
* @copyright 2010-2017 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* *
* This file contains all the function to describe the dependencies * @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* used in the Xgeqrf_param.jdf file. * Univ. Bordeaux. All rights reserved.
*
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-03-21
* *
*/ */
#include "libhqr.h" #include "libhqr.h"
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
//#if defined(LIBHQR_HAVE_STRING_H)
#include <string.h>
//#endif /* defined(LIBHQR_HAVE_STRING_H) */
#define PRINT_PIVGEN 0 #define PRINT_PIVGEN 0
#ifdef PRINT_PIVGEN #ifdef PRINT_PIVGEN
...@@ -63,11 +63,11 @@ static int systolic_gettype( const libhqr_tree_t *qrtree, int k, int m ) { ...@@ -63,11 +63,11 @@ static int systolic_gettype( const libhqr_tree_t *qrtree, int k, int m ) {
/* Local eliminations with a TS kernel */ /* Local eliminations with a TS kernel */
if ( m >= k + pq ) if ( m >= k + pq )
return 0; return 0;
/* Element to be reduce with a single pivot */ /* Element to be reduce with a single pivot */
else if ( m >= k+p ) else if ( m >= k+p )
return 1; return 1;
/* Element to be reduced with sq_p pivot */ /* Element to be reduced with sq_p pivot */
else return 3; else return 3;
...@@ -88,16 +88,16 @@ static int systolic_currpiv(const libhqr_tree_t *qrtree, int k, int m) ...@@ -88,16 +88,16 @@ static int systolic_currpiv(const libhqr_tree_t *qrtree, int k, int m)
switch( systolic_gettype( qrtree, k, m ) ) switch( systolic_gettype( qrtree, k, m ) )
{ {
case 0: case 0:
return (m - k) % pq + k; return (m - k) % pq + k;
break; break;
case 1: case 1:
return (m - k) % p + k; return (m - k) % p + k;
break; break;
case 3: case 3:
return k; return k;
break; break;
default: default:
return qrtree->mt; return qrtree->mt;
} }
}; };
...@@ -136,59 +136,59 @@ static int systolic_nextpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s ...@@ -136,59 +136,59 @@ static int systolic_nextpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s
lp = systolic_gettype( qrtree, k, pivot ); lp = systolic_gettype( qrtree, k, pivot );
switch( ls ) switch( ls )
{ {
case -1: case -1:
if ( lp == LIBHQR_KILLED_BY_TS ) { if ( lp == LIBHQR_KILLED_BY_TS ) {
myassert( start == mt ); myassert( start == mt );
return mt; return mt;
} }
case LIBHQR_KILLED_BY_TS: case LIBHQR_KILLED_BY_TS:
if ( start == mt ) if ( start == mt )
nextp = pivot + pq; nextp = pivot + pq;
else else
nextp = start + pq; nextp = start + pq;
if ( nextp < mt ) if ( nextp < mt )
return nextp; return nextp;
start = mt; start = mt;
case LIBHQR_KILLED_BY_LOCALTREE: case LIBHQR_KILLED_BY_LOCALTREE:
if (lp < LIBHQR_KILLED_BY_DISTTREE) if (lp < LIBHQR_KILLED_BY_DISTTREE)
return mt; return mt;
if ( start == mt ) if ( start == mt )
nextp = pivot + p; nextp = pivot + p;
else else
nextp = start + p; nextp = start + p;
if ( (nextp >= k + p) && if ( (nextp >= k + p) &&
(nextp < k + pq) && (nextp < k + pq) &&
(nextp < mt) ) (nextp < mt) )
return nextp; return nextp;
start = mt; start = mt;
case LIBHQR_KILLED_BY_DISTTREE: case LIBHQR_KILLED_BY_DISTTREE:
if (pivot > k) if (pivot > k)
return mt; return mt;
if ( start == mt ) if ( start == mt )
nextp = pivot + 1; nextp = pivot + 1;
else else
nextp = start + 1; nextp = start + 1;
if ( nextp < k + p ) if ( nextp < k + p )
return nextp; return nextp;
default: default:
return mt; return mt;
} }
} }
/** /**
...@@ -232,63 +232,63 @@ static int systolic_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s ...@@ -232,63 +232,63 @@ static int systolic_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s
myassert( lp >= ls ); myassert( lp >= ls );
switch( ls ) switch( ls )
{ {
case LIBHQR_KILLED_BY_DISTTREE: case LIBHQR_KILLED_BY_DISTTREE:
if ( pivot == k ) { if ( pivot == k ) {
if ( start == pivot ) { if ( start == pivot ) {
nextp = start + p-1; nextp = start + p-1;
while( pivot < nextp && nextp >= mt ) while( pivot < nextp && nextp >= mt )
nextp--; nextp--;
} else { } else {
nextp = start - 1; nextp = start - 1;
} }
if ( pivot < nextp && if ( pivot < nextp &&
nextp < k + p ) nextp < k + p )
return nextp; return nextp;
} }
start = pivot; start = pivot;
case LIBHQR_KILLED_BY_LOCALTREE: case LIBHQR_KILLED_BY_LOCALTREE:
if ( lp > LIBHQR_KILLED_BY_LOCALTREE ) { if ( lp > LIBHQR_KILLED_BY_LOCALTREE ) {
if ( start == pivot ) { if ( start == pivot ) {
nextp = start + (q-1) * p; nextp = start + (q-1) * p;
while( pivot < nextp && while( pivot < nextp &&
nextp >= mt ) nextp >= mt )
nextp -= p; nextp -= p;
} else { } else {
nextp = start - p; nextp = start - p;
} }
if ( pivot < nextp && if ( pivot < nextp &&
nextp < k + pq ) nextp < k + pq )
return nextp; return nextp;
} }
start = pivot; start = pivot;
case LIBHQR_KILLED_BY_TS: case LIBHQR_KILLED_BY_TS:
/* Search for predecessor in TS tree */ /* Search for predecessor in TS tree */
if ( lp > LIBHQR_KILLED_BY_TS ) { if ( lp > LIBHQR_KILLED_BY_TS ) {
if ( start == pivot ) { if ( start == pivot ) {
nextp = mt - (mt - rpivot - 1)%pq - 1; nextp = mt - (mt - rpivot - 1)%pq - 1;
while( pivot < nextp && nextp >= mt ) while( pivot < nextp && nextp >= mt )
nextp -= pq; nextp -= pq;
} else { } else {
nextp = start - pq; nextp = start - pq;
} }
assert(nextp < mt); assert(nextp < mt);
if ( pivot < nextp ) if ( pivot < nextp )
return nextp; return nextp;
} }
default: default:
return mt; return mt;
} }
}; };
/** /**
...@@ -349,29 +349,29 @@ static int systolic_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s ...@@ -349,29 +349,29 @@ static int systolic_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s
******************************************************************************/ ******************************************************************************/
int int
libhqr_systolic_init( libhqr_tree_t *qrtree, libhqr_systolic_init( libhqr_tree_t *qrtree,
libhqr_typefacto_e trans, libhqr_tiledesc_t *A, libhqr_typefacto_e trans, libhqr_tiledesc_t *A,
int p, int q ) int p, int q )
{ {
if (qrtree == NULL) { if (qrtree == NULL) {
fprintf(stderr, "libhqr_systolic_init, illegal value of qrtree"); fprintf(stderr, "libhqr_systolic_init, illegal value of qrtree");
return -1; return -1;
} }
if ((trans != LIBHQR_QR) && if ((trans != LIBHQR_QR) &&
(trans != LIBHQR_LQ)) { (trans != LIBHQR_LQ)) {
fprintf(stderr, "libhqr_systolic_init, illegal value of trans"); fprintf(stderr, "libhqr_systolic_init, illegal value of trans");
return -2; return -2;
} }
if (A == NULL) { if (A == NULL) {
fprintf(stderr, "libhqr_systolic_init, illegal value of A"); fprintf(stderr, "libhqr_systolic_init, illegal value of A");
return -3; return -3;
} }
if ( p < 0 ) { if ( p < 0 ) {
fprintf(stderr, "libhqr_systolic_init, illegal value of p"); fprintf(stderr, "libhqr_systolic_init, illegal value of p");
return -4; return -4;
} }
if ( q < -1 ) { if ( q < -1 ) {
fprintf(stderr, "libhqr_systolic_init, illegal value of q"); fprintf(stderr, "libhqr_systolic_init, illegal value of q");
return -5; return -5;
} }
qrtree->getnbgeqrf = systolic_getnbgeqrf; qrtree->getnbgeqrf = systolic_getnbgeqrf;
...@@ -415,6 +415,6 @@ void ...@@ -415,6 +415,6 @@ void
libhqr_systolic_finalize( libhqr_tree_t *qrtree ) libhqr_systolic_finalize( libhqr_tree_t *qrtree )
{ {
if ( qrtree->args != NULL) { if ( qrtree->args != NULL) {
free( qrtree->args ); free( qrtree->args );
} }
} }
/**
*
* @file queue.c
*
* File for queue functions.
*
* @copyright 2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
*
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-04-05
*
*/
#include "queue.h"
#include <stdlib.h>
#include <stdio.h>
/****************************************************
* Generic functions for queue
***************************************************/
libhqr_queue_tile_t *libhqr_queue_tile_new (void)
{
return (NULL);
}
void libhqr_queue_tile_first (libhqr_queue_tile_t ** queue_tile)
{
if (queue_tile != NULL && *queue_tile != NULL)
{
while ((*queue_tile)->prev != NULL)
libhqr_queue_tile_prev (queue_tile);
}
return;
}
void libhqr_queue_tile_prev (libhqr_queue_tile_t ** queue_tile)
{
if (queue_tile != NULL && *queue_tile != NULL)
*queue_tile = (*queue_tile)->prev;
return;
}
void libhqr_queue_tile_last (libhqr_queue_tile_t ** queue_tile)
{
if (queue_tile != NULL && *queue_tile != NULL)
{
while ((*queue_tile)->next != NULL)
libhqr_queue_tile_next (queue_tile);
}
return;
}
void libhqr_queue_tile_next (libhqr_queue_tile_t ** queue_tile)
{
if (queue_tile != NULL && *queue_tile != NULL)
*queue_tile = (*queue_tile)->next;
return;
}
void libhqr_queue_tile_post (libhqr_queue_tile_t ** queue_tile, int numero)
{
if (queue_tile != NULL)
{
libhqr_queue_tile_t *p_l = NULL;
libhqr_queue_tile_t *p_p = NULL;
libhqr_queue_tile_first (queue_tile);
p_l = *queue_tile;
p_p = malloc (sizeof (*p_p));
if (p_p != NULL)
{
p_p->numero = numero;
p_p->next = p_l;
p_p->prev = NULL;
if (p_l != NULL)
p_l->prev = p_p;
*queue_tile = p_p;
}
else
{
fprintf (stderr, "Memoire insuffisante\n");
exit (EXIT_FAILURE);
}
}
return;
}
int libhqr_queue_tile_get (libhqr_queue_tile_t ** queue_tile)
{
int ret;
if (queue_tile != NULL && *queue_tile != NULL)
{
libhqr_queue_tile_t *p_l = NULL;
libhqr_queue_tile_t *p_p = NULL;
libhqr_queue_tile_last (queue_tile);
p_l = *queue_tile;
if (p_l != NULL)
p_p = p_l->prev;
ret = p_l->numero;
free (p_l);
p_l = NULL;
if (p_p != NULL)
p_p->next = NULL;
*queue_tile = p_p;
}
return (ret);
}
void libhqr_queue_tile_delete (libhqr_queue_tile_t ** queue_tile)
{
if (queue_tile != NULL && *queue_tile != NULL)
{
while (*queue_tile != NULL)
libhqr_queue_tile_get (queue_tile);
}
return;
}
/**
*
* @file treewalk.c
*
* File for algorithm of treewalking.
*
* @copyright 2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
*
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-03-21
*
*/
#include "libhqr.h" #include "libhqr.h"
#include <assert.h> #include "queue.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <math.h>
//#if defined(LIBHQR_HAVE_STRING_H)
#include <string.h>
//#endif /* defined(PARSEC_HAVE_STRING_H) */
#define PRINT_PIVGEN 0
#ifdef PRINT_PIVGEN
#define myassert( test ) {if ( ! (test) ) return -1;}
#else
#define myassert(test) {assert((test)); return -1;}
#endif
/**************************************************** /****************************************************
* * LIBHQR_TREEWALK
* Generic functions for file
*
***************************************************/ ***************************************************/
/**
static void libhqr_file_tile_first (libhqr_file_tile_t ** file_tile); * libhqr_treewalk
static void libhqr_file_tile_last (libhqr_file_tile_t ** file_tile);
static void libhqr_file_tile_prev (libhqr_file_tile_t ** file_tile);
static void libhqr_file_tile_next (libhqr_file_tile_t ** file_tile);
libhqr_file_tile_t *libhqr_file_tile_new (void)
{
return (NULL);
}
static void libhqr_file_tile_first (libhqr_file_tile_t ** file_tile)
{
if (file_tile != NULL && *file_tile != NULL)
{
while ((*file_tile)->prev != NULL)
libhqr_file_tile_prev (file_tile);
}
return;
}
static void libhqr_file_tile_prev (libhqr_file_tile_t ** file_tile)
{
if (file_tile != NULL && *file_tile != NULL)
*file_tile = (*file_tile)->prev;
return;
}
static void libhqr_file_tile_last (libhqr_file_tile_t ** file_tile)
{
if (file_tile != NULL && *file_tile != NULL)
{
while ((*file_tile)->next != NULL)
libhqr_file_tile_next (file_tile);
}
return;
}
static void libhqr_file_tile_next (libhqr_file_tile_t ** file_tile)
{
if (file_tile != NULL && *file_tile != NULL)
*file_tile = (*file_tile)->next;
return;
}
void libhqr_file_tile_post (libhqr_file_tile_t ** file_tile, int numero)
{
if (file_tile != NULL)
{
libhqr_file_tile_t *p_l = NULL;
libhqr_file_tile_t *p_p = NULL;
libhqr_file_tile_first (file_tile);
p_l = *file_tile;
p_p = malloc (sizeof (*p_p));
if (p_p != NULL)
{
p_p->numero = numero;
p_p->next = p_l;
p_p->prev = NULL;
if (p_l != NULL)
p_l->prev = p_p;
*file_tile = p_p;
}
else
{
fprintf (stderr, "Memoire insuffisante\n");
exit (EXIT_FAILURE);
}
}
return;
}
int libhqr_file_tile_get (libhqr_file_tile_t ** file_tile)
{
int ret;
if (file_tile != NULL && *file_tile != NULL)
{
libhqr_file_tile_t *p_l = NULL;
libhqr_file_tile_t *p_p = NULL;
libhqr_file_tile_last (file_tile);
p_l = *file_tile;
if (p_l != NULL)
p_p = p_l->prev;
ret = p_l->numero;
free (p_l);
p_l = NULL;
if (p_p != NULL)
p_p->next = NULL;
*file_tile = p_p;
}
return (ret);
}
void libhqr_file_tile_delete (libhqr_file_tile_t ** file_tile)
{
if (file_tile != NULL && *file_tile != NULL)
{
while (*file_tile != NULL)
libhqr_file_tile_get (file_tile);
}
return;
}
/****************************************************
* *
* fonctions pour parcourir arbre * @param[in] arg
* Arguments specific to the reduction tree used
* *
***************************************************/ * @param[in] k
* Factorization step
*
*/
void libhqr_treewalk(libhqr_tree_t *qrtree,int k){ void libhqr_treewalk(const libhqr_tree_t *qrtree,int k){
libhqr_file_tile_t **tt; int pivot = qrtree->mt;
libhqr_file_tile_t **ts; printf("%d\n" , pivot);
libhqr_file_tile_t *p_l = NULL;
libhqr_file_tile_t *p_p = NULL;
int pivot = qrtree->p;
int p = pivot; int p = pivot;
while(p = qrtree->nextpiv(qrtree, k, pivot,p)){ printf("%d\n" , qrtree->prevpiv(qrtree, k, pivot, p));
int a,b;
while(p = qrtree->prevpiv(qrtree, k , pivot, p)){ libhqr_queue_tile_t *tt = libhqr_queue_tile_new();
libhqr_queue_tile_t *ts = libhqr_queue_tile_new();
if(qrtree->gettype(qrtree, k, p)) libhqr_file_tile_post(tt,p); while(p = qrtree->prevpiv(qrtree, k, pivot, p)){
libhqr_file_tile_post(ts, p); while(p = qrtree->nextpiv(qrtree, k, pivot, p)){
if(qrtree->gettype(qrtree, k, p)){
} libhqr_queue_tile_post(&tt,p);
libhqr_file_tile_last(ts); }
p_l = *ts; libhqr_queue_tile_post(&ts, p);
libhqr_file_tile_last(tt); }
p_p = *tt; libhqr_queue_tile_last(&ts);
int a = p_l->numero; libhqr_queue_tile_last(&tt);
int b = p_p->numero; a = ts->numero;
while(a != b){ printf("%d\n" , a);
libhqr_file_tile_get(ts); b = tt->numero;
libhqr_file_tile_last(ts); printf("%d\n" , b);
p_l = *ts; while(a != b){
a = p_l->numero; libhqr_queue_tile_get(&ts);
printf("%d/n" , a); libhqr_queue_tile_last(&ts);
} a = ts->numero;
libhqr_file_tile_get(tt); printf("%d\n" , a);
}
libhqr_queue_tile_last(&tt);
libhqr_queue_tile_get(&tt);
} }
libhqr_file_tile_delete(tt);
libhqr_file_tile_delete(ts);
}
/****************************************************
*
* fonction utilisant l'algo de parcours d'arbre
*
***************************************************/
void libhqr_print_tree(libhqr_tree_t qrtree){
} }
/* /**
* Copyright (c) 2009-2011 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* *
* @precisions normal z -> s d c * @file testing_pivgen.c
*
* Testing file for all combinations of trees.
*
* @copyright 2010-2017 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
*
* @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
*
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-03-21
* *
*/ */
#include "libhqr.h" #include "libhqr.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <math.h>
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
...@@ -41,7 +49,7 @@ int main(int argc, char ** argv) ...@@ -41,7 +49,7 @@ int main(int argc, char ** argv)
todo += nbtreel * nbM * nbN * (2 * nbA - 1) * (1 + 2 * nbtreeh * nbP); todo += nbtreel * nbM * nbN * (2 * nbA - 1) * (1 + 2 * nbtreeh * nbP);
/* systolic */ /* systolic */
todo += nbM * nbN * nbA * nbP; todo += nbM * nbN * nbA * nbP;
/* /*
* *
* Tests for HQR code * Tests for HQR code
......
/* /**
* Copyright (c) 2009-2011 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* *
* @precisions normal z -> s d c * @file testing_treewalk.c
*
* Testing the treewalk algorithm using different kind of matrix
*
* @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
*
* @version 1.0.0
* @author Raphael Boucherie
* @author Mathieu Faverge
* @date 2017-03-21
* *
*/ */
#include "libhqr.h" #include "libhqr.h"
#include <stdlib.h> #include "queue.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <math.h>
int
main(int argc, char ** argv)
int main(int argc, char ** argv)
{ {
libhqr_tree_t qrtree; libhqr_tree_t qrtree;
libhqr_tiledesc_t matrix; libhqr_tiledesc_t matrix;
/* int minMN, k, rc ;
*
* Tests for HQR code /*
* * Test treewalk for HQR trees
*/ */
matrix.nodes = 1; matrix.nodes = 1;
matrix.p = 1; matrix.p = 1;
matrix.mt = 10; matrix.mt = 4;
matrix.nt = 13; matrix.nt = 13;
libhqr_hqr_init( &qrtree, LIBHQR_QR, &matrix, 0, 0, 1, -1, 0, 0); libhqr_hqr_init( &qrtree, LIBHQR_QR, &matrix, -1 , -1 , -1 , -1, 0, 0);
libhqr_treewalk( &qrtree, 0); minMN = libhqr_imin(matrix.mt, matrix.nt );
return 1; rc = libhqr_tree_check( &matrix, &qrtree );
printf("%d\n", rc);
for (k=0; k<minMN; k++) {
libhqr_treewalk( &qrtree, k);
}
libhqr_hqr_finalize( &qrtree );
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment