diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000000000000000000000000000000000000..abafe9600e9d9399f1959fade428d9943941f565 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,105 @@ +;; 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)))) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f4e9c8a759f89f3eb4e836341b41ffcc04e36b69 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +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 diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000000000000000000000000000000000000..c61ff309e6ead805defaa844f5abb324c0aaea03 --- /dev/null +++ b/include/common.h @@ -0,0 +1,34 @@ +/** + * + * @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_ */ diff --git a/include/libhqr.h b/include/libhqr.h index 526055421361130bcd83e7cacb7657a5b1d17d4b..d724e48ddf717e239ee9873f5f0f06bce003690e 100644 --- a/include/libhqr.h +++ b/include/libhqr.h @@ -1,41 +1,56 @@ -/* - * Copyright (c) 2010 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. +/** + * + * @file libhqr.h + * + * @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_ #define _LIBHQR_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 +#include "common.h" BEGIN_C_DECLS 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){ - return (a > b) ? a : b; + return (a > b) ? a : 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 - * factorization to distinguish TT kernels from TS kernels in jdf +/** + * @brief Define to which tree level the tile belongs to. + * + * 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_ { LIBHQR_KILLED_BY_TS = 0, @@ -44,6 +59,9 @@ typedef enum libhqr_type_ { LIBHQR_KILLED_BY_DISTTREE = 3, } libhqr_type_e; +/** + * @brief Define the type of trees that can be used for the reduction. + */ typedef enum libhqr_tree_ { LIBHQR_FLAT_TREE = 0, LIBHQR_GREEDY_TREE = 1, @@ -52,26 +70,24 @@ typedef enum libhqr_tree_ { LIBHQR_GREEDY1P_TREE = 4, } libqr_tree_e; +/** + * @brief Define the type of factorization to apply: QR or LQ. + */ typedef enum libhqr_typefacto_ { - LIBHQR_QR = 0, - LIBHQR_LQ = 1, + LIBHQR_QR = 0, + LIBHQR_LQ = 1, } libhqr_typefacto_e; +/** + * @brief Minimal structure to define the shape of the matrix to factorize. + */ typedef struct libhqr_tiledesc_s{ - int mt; - int nt; - int nodes; - int p; + int mt; /**< The number of rows of tiles */ + int nt; /**< The number of columns of tiles */ + int nodes; /**< The number of nodes involved in the data distribution */ + int p; /**< The number of nodes per column in the data distribution */ } 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; typedef struct libhqr_tree_s libhqr_tree_t; @@ -79,75 +95,72 @@ typedef struct libhqr_context_s libhqr_context_t; struct libhqr_tree_s { /** - * getnbgeqrf - * @param[in] arg arguments specific to the reduction tree used - * @param[in] k Factorization step - * + * @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] k Factorization step * @return The number of geqrt applied to the panel k */ int (*getnbgeqrf)( const libhqr_tree_t *arg, int k ); /** - * getm: - * @param[in] arg arguments specific to the reduction tree used - * @param[in] k Factorization step - * @param[in] i Index of the geqrt applied on the panel k - * + * @brief Compute the row/column index of the i^th geqrt/gelqt kernel in the + * column/row k + * @param[in] arg arguments specific to the reduction tree used + * @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 */ int (*getm)( const libhqr_tree_t *arg, int k, int i ); /** - * geti: - * @param[in] arg arguments specific to the reduction tree used - * @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 + * @brief Compute the index of the row/column m in the list of geqrt/gelqt + * kernels in the column/row k + * @param[in] arg arguments specific to the reduction tree used + * @param[in] k Factorization step + * @param[in] m Row index where a geqrt is applied on 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 ); /** - * gettype: - * @param[in] arg arguments specific to the reduction tree used - * @param[in] k Factorization step - * @param[in] m Row index of the one we request the type - * - * @returns The type of kernel used to kill the row m at step k: - * - 0 if it is a TS kernel - * - >0 otherwise. (TT kernel) + * @brief Return the tree level the tile belongs to. + * @param[in] arg arguments specific to the reduction tree used + * @param[in] k Factorization step + * @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: + * - 0 if it is a TS kernel + * - >0 otherwise. (TT kernel) */ int (*gettype)( const libhqr_tree_t *qrtree, int k, int m ); /** - * currpiv - * @param[in] arg arguments specific to the reduction tree used - * @param[in] k Factorization step - * @param[in] m line you want to eliminate - * - * @return The index of the row annihilating the row m at step k + * @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] k Factorization step + * @param[in] m line you want to eliminate + * @return The index of the row annihilating the row m at step k */ int (*currpiv)( const libhqr_tree_t *qrtree, int k, int m ); /** - * nextpiv - * @param[in] arg arguments specific to the reduction tree used - * @param[in] k Factorization step - * @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) - * m = MT to find the first time p is used as an annihilator during step k + * @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] k Factorization step + * @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) + * 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 - * desc->mt if p will never be used again as an annihilator. + * @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. */ int (*nextpiv)(const libhqr_tree_t *qrtree, int k, int p, int m); /** - * prevpiv - * @param[in] arg arguments specific to the reduction tree used - * @param[in] k Factorization step - * @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) - * m = p to find the last time p has been used as an annihilator during step k + * @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] k Factorization step + * @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) + * 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 - * desc->mt if p has never been used before as an annihilator. + * @return the previous line killed by the row p during step k + * 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); @@ -162,43 +175,30 @@ struct libhqr_tree_s { }; int libhqr_systolic_init( libhqr_tree_t *qrtree, - libhqr_typefacto_e trans, libhqr_tiledesc_t *A, - int p, int q ); + libhqr_typefacto_e trans, libhqr_tiledesc_t *A, + int p, int q ); void libhqr_systolic_finalize( libhqr_tree_t *qrtree ); int libhqr_svd_init( libhqr_tree_t *qrtree, - libhqr_typefacto_e trans, libhqr_tiledesc_t *A, - int type_hlvl, int p, int nbcores_per_node, int ratio ); + libhqr_typefacto_e trans, libhqr_tiledesc_t *A, + int type_hlvl, int p, int nbcores_per_node, int ratio ); int libhqr_hqr_init( libhqr_tree_t *qrtree, - libhqr_typefacto_e trans, libhqr_tiledesc_t *A, - int type_llvl, int type_hlvl, - int a, int p, int domino, int tsrr ); + libhqr_typefacto_e trans, libhqr_tiledesc_t *A, + int type_llvl, int type_hlvl, + int a, int p, int domino, int tsrr ); 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 */ -void libhqr_treewalk(libhqr_tree_t *qrtree,int k); - +void libhqr_treewalk(const libhqr_tree_t *qrtree,int k); /* * Debugging functions */ + 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_type ( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ); diff --git a/include/queue.h b/include/queue.h new file mode 100644 index 0000000000000000000000000000000000000000..1af84b4d3a2e6e9cac2f1cf6569be89928909cdd --- /dev/null +++ b/include/queue.h @@ -0,0 +1,40 @@ +/** + * + * @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_ */ diff --git a/src/libhqr.c b/src/libhqr.c index 36b4c8dc69b3aef07f51f02310274bca9e78c9d5..434bf2fb4e9cdca5237def9ce60e89086a119cdc 100644 --- a/src/libhqr.c +++ b/src/libhqr.c @@ -1,10 +1,17 @@ -/* - * Copyright (c) 2010 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. +/** + * + * @file libhqr.c * - * @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 * used in the Xgeqrf_param.jdf file. @@ -75,9 +82,7 @@ #include <stdlib.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 diff --git a/src/libhqr_dbg.c b/src/libhqr_dbg.c index 023f1c0890e599b5423c9fadf47f0bf598fa4fcf..46d82ef0a7e92db340cc4ab08271813c3cbd97cd 100644 --- a/src/libhqr_dbg.c +++ b/src/libhqr_dbg.c @@ -1,89 +1,31 @@ -/* - * 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 - * used in the Xgeqrf_param.jdf file. - * 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. + * @copyright 2012-2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, + * Univ. Bordeaux. All rights reserved. * - * - the third level is using a reduction tree of size 'p'. By - * default, the parameter 'p' should be equal to the number of - * processors used for the computation, but can be set - * differently. (see further example). The type of tree used at - * 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. + * @version 1.0.0 + * @author Raphael Boucherie + * @author Mathieu Faverge + * @date 2017-03-21 * - * - 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 <stdio.h> #include <stdlib.h> -#include <math.h> -//#if defined(LIBHQR_HAVE_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 ); */ #define ENDCHECK( test, ret ) \ if ( !test ) \ - return ret; + return ret; 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 */ { - /* libhqr_tree_print_type( A, qrtree ); */ - /* libhqr_tree_print_nbgeqrt( A, qrtree ); */ - check = 1; - for (k=0; k<minMN; k++) { - nb = 0; - for (m=k; m < A->mt; m++) { - if ( qrtree->gettype( qrtree, k, m ) > 0 ) - nb++; - } - - if ( nb != qrtree->getnbgeqrf( qrtree, k ) ) { - check = 0; - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Check number of geqrt:\n" - " For k=%d => return %d instead of %d", - a, p, A->mt, A->nt, k, qrtree->getnbgeqrf( qrtree, k ), nb ); - } - } - - ENDCHECK( check, 1 ); + /* libhqr_tree_print_type( A, qrtree ); */ + /* libhqr_tree_print_nbgeqrt( A, qrtree ); */ + check = 1; + for (k=0; k<minMN; k++) { + nb = 0; + for (m=k; m < A->mt; m++) { + if ( qrtree->gettype( qrtree, k, m ) > 0 ) + nb++; + } + + if ( nb != qrtree->getnbgeqrf( qrtree, k ) ) { + check = 0; + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Check number of geqrt:\n" + " For k=%d => return %d instead of %d", + a, p, A->mt, A->nt, k, qrtree->getnbgeqrf( qrtree, k ), nb ); + } + } + + ENDCHECK( check, 1 ); } /* * Check indices of geqrt */ { - int prevm = -1; - check = 1; - for (k=0; k<minMN; k++) { - /* libhqr_tree_print_geqrt_k( A, qrtree, k ); */ - nb = qrtree->getnbgeqrf( qrtree, k ); - prevm = -1; - for (i=0; i < nb; i++) { - - m = qrtree->getm( qrtree, k, i ); - - /* - * getm has to be the inverse of geti - */ - if ( i != qrtree->geti( qrtree, k, m) ) { - check = 0; - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Check indices of geqrt:\n" - " getm( k=%d, i=%d ) => m = %d && geti( k=%d, m=%d ) => i = %d\n", - a, p, A->mt, A->nt, - k, i, m, k, m, qrtree->geti( qrtree, k, m)); - } - /* tile before the diagonal are factorized and - * the m is a growing list (not true with round-robin inside TS) - */ - else if ( (a == 1) && (( m < k ) || ( m < prevm )) ) { - check = 0; - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Check indices of geqrt:\n" - " getm( k=%d, i=%d ) => m = %d", - a, p, A->mt, A->nt, k, i, m); - } + int prevm = -1; + check = 1; + for (k=0; k<minMN; k++) { + /* libhqr_tree_print_geqrt_k( A, qrtree, k ); */ + nb = qrtree->getnbgeqrf( qrtree, k ); + prevm = -1; + for (i=0; i < nb; i++) { + + m = qrtree->getm( qrtree, k, i ); + + /* + * getm has to be the inverse of geti + */ + if ( i != qrtree->geti( qrtree, k, m) ) { + check = 0; + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Check indices of geqrt:\n" + " getm( k=%d, i=%d ) => m = %d && geti( k=%d, m=%d ) => i = %d\n", + a, p, A->mt, A->nt, + k, i, m, k, m, qrtree->geti( qrtree, k, m)); + } + /* tile before the diagonal are factorized and + * the m is a growing list (not true with round-robin inside TS) + */ + else if ( (a == 1) && (( m < k ) || ( m < prevm )) ) { + check = 0; + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Check indices of geqrt:\n" + " getm( k=%d, i=%d ) => m = %d", + a, p, A->mt, A->nt, k, i, m); + } #if 0 - else if ( m != qrtree->getinon0( qrtree, k, i, A->mt ) ) { - check = 0; - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Check indices of geqrt:\n" - " 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)); - } + else if ( m != qrtree->getinon0( qrtree, k, i, A->mt ) ) { + check = 0; + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Check indices of geqrt:\n" + " 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)); + } #endif - prevm = m; - } - } - ENDCHECK( check, 2 ); + prevm = m; + } + } + ENDCHECK( check, 2 ); } /* * Check number of exit in next */ { - int s; - check = 1; - - for (k=0; k<minMN; k++) { - for(m=k; m<A->mt; m++) { - nb = 0; - for(s=A->mt; s>k; s--) { - if ( qrtree->nextpiv(qrtree, k, m, s) == A->mt ) - nb++; - } - if ( nb > 1 ) { - libhqr_tree_print_next_k( A, qrtree, k); - libhqr_tree_print_prev_k( A, qrtree, k); - - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Next of line %d for step %d contains more than one exit:\n", - a, p, A->mt, A->nt, - m, k); - check = 0; - return 3; - } - else if ( nb == 0 ) { - libhqr_tree_print_next_k( A, qrtree, k); - libhqr_tree_print_prev_k( A, qrtree, k); - - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Next of line %d for step %d needs one exit:\n", - a, p, A->mt, A->nt, - m, k); - check = 0; - return 3; - } - } - } - ENDCHECK( check, 3 ); + int s; + check = 1; + + for (k=0; k<minMN; k++) { + for(m=k; m<A->mt; m++) { + nb = 0; + for(s=A->mt; s>k; s--) { + if ( qrtree->nextpiv(qrtree, k, m, s) == A->mt ) + nb++; + } + if ( nb > 1 ) { + libhqr_tree_print_next_k( A, qrtree, k); + libhqr_tree_print_prev_k( A, qrtree, k); + + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Next of line %d for step %d contains more than one exit:\n", + a, p, A->mt, A->nt, + m, k); + check = 0; + return 3; + } + else if ( nb == 0 ) { + libhqr_tree_print_next_k( A, qrtree, k); + libhqr_tree_print_prev_k( A, qrtree, k); + + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Next of line %d for step %d needs one exit:\n", + a, p, A->mt, A->nt, + m, k); + check = 0; + return 3; + } + } + } + ENDCHECK( check, 3 ); } /* * Check number of exit in prev */ { - int s; - check = 1; - - for (k=0; k<minMN; k++) { - for(m=k; m<A->mt; m++) { - nb = 0; - for(s=k; s<A->mt; s++) { - if ( qrtree->prevpiv(qrtree, k, m, s) == A->mt ) - nb++; - } - if ( nb > 1 ) { - libhqr_tree_print_next_k( A, qrtree, k); - libhqr_tree_print_prev_k( A, qrtree, k); - - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Prev of line %d for step %d contains more than one exit:\n", - a, p, A->mt, A->nt, - m, k); - check = 0; - return 3; - } - else if ( nb == 0 ) { - libhqr_tree_print_next_k( A, qrtree, k); - libhqr_tree_print_prev_k( A, qrtree, k); - - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Prev of line %d for step %d needs one exit:\n", - a, p, A->mt, A->nt, - m, k); - check = 0; - return 3; - } - } - } - ENDCHECK( check, 3 ); + int s; + check = 1; + + for (k=0; k<minMN; k++) { + for(m=k; m<A->mt; m++) { + nb = 0; + for(s=k; s<A->mt; s++) { + if ( qrtree->prevpiv(qrtree, k, m, s) == A->mt ) + nb++; + } + if ( nb > 1 ) { + libhqr_tree_print_next_k( A, qrtree, k); + libhqr_tree_print_prev_k( A, qrtree, k); + + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Prev of line %d for step %d contains more than one exit:\n", + a, p, A->mt, A->nt, + m, k); + check = 0; + return 3; + } + else if ( nb == 0 ) { + libhqr_tree_print_next_k( A, qrtree, k); + libhqr_tree_print_prev_k( A, qrtree, k); + + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Prev of line %d for step %d needs one exit:\n", + a, p, A->mt, A->nt, + m, k); + check = 0; + return 3; + } + } + } + ENDCHECK( check, 3 ); } /* * Check next/prev */ { - int start, next, prev; - check = 1; - - for (k=0; k<minMN; k++) { - start = A->mt; - for(m=k; m<A->mt; m++) { - - do { - next = qrtree->nextpiv(qrtree, k, m, start); - if ( next == A->mt ) - prev = qrtree->prevpiv(qrtree, k, m, m); - else - prev = qrtree->prevpiv(qrtree, k, m, next); - - if ( start != prev ) { - libhqr_tree_print_next_k( A, qrtree, k); - libhqr_tree_print_prev_k( A, qrtree, k); - - printf(" ----------------------------------------------------\n" - " - a = %d, p = %d, M = %d, N = %d\n" - " Check next/prev:\n" - " 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, - m, k, start, next, m, k, next, prev, start, prev); - check = 0; - return 3; - } - start = next; - } while ( start != A->mt ); - } - } - ENDCHECK( check, 3 ); + int start, next, prev; + check = 1; + + for (k=0; k<minMN; k++) { + start = A->mt; + for(m=k; m<A->mt; m++) { + + do { + next = qrtree->nextpiv(qrtree, k, m, start); + if ( next == A->mt ) + prev = qrtree->prevpiv(qrtree, k, m, m); + else + prev = qrtree->prevpiv(qrtree, k, m, next); + + if ( start != prev ) { + libhqr_tree_print_next_k( A, qrtree, k); + libhqr_tree_print_prev_k( A, qrtree, k); + + printf(" ----------------------------------------------------\n" + " - a = %d, p = %d, M = %d, N = %d\n" + " Check next/prev:\n" + " 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, + m, k, start, next, m, k, next, prev, start, prev); + check = 0; + return 3; + } + start = next; + } while ( start != A->mt ); + } + } + ENDCHECK( check, 3 ); } return 0; @@ -311,29 +253,29 @@ void libhqr_tree_print_type( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ) printf("\n------------ Localization = Type of pivot --------------\n"); for(m=0; m<A->mt; m++) { - printf("%3d | ", m); - for (k=0; k<libhqr_imin(minMN, m+1); k++) { - printf( "%3d ", qrtree->gettype( qrtree, k, m ) ); - } - for (k=libhqr_imin(minMN, m+1); k<minMN; k++) { - printf( " " ); - } - - printf(" "); - printf("%2d,%3d | ", rank, lmg); - for (k=0; k<libhqr_imin(minMN, lmg+1); k++) { - printf( "%3d ", qrtree->gettype( qrtree, k, lmg) ); - } - for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) { - printf( " " ); - } - lm++; lmg+=qrtree->p; - if ( lmg >= A->mt ) { - rank++; - lmg = rank; - lm = 0; - } - printf("\n"); + printf("%3d | ", m); + for (k=0; k<libhqr_imin(minMN, m+1); k++) { + printf( "%3d ", qrtree->gettype( qrtree, k, m ) ); + } + for (k=libhqr_imin(minMN, m+1); k<minMN; k++) { + printf( " " ); + } + + printf(" "); + printf("%2d,%3d | ", rank, lmg); + for (k=0; k<libhqr_imin(minMN, lmg+1); k++) { + printf( "%3d ", qrtree->gettype( qrtree, k, lmg) ); + } + for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) { + printf( " " ); + } + lm++; lmg+=qrtree->p; + if ( lmg >= A->mt ) { + rank++; + lmg = rank; + lm = 0; + } + printf("\n"); } } @@ -346,29 +288,29 @@ void libhqr_tree_print_pivot( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree ) int rank = 0; printf("\n------------ Current Pivot--------------\n"); for(m=0; m<A->mt; m++) { - printf("%3d | ", m); - for (k=0; k<libhqr_imin(minMN, m+1); k++) { - printf( "%3d ", qrtree->currpiv(qrtree, k, m) ); - } - for (k=libhqr_imin(minMN, m+1); k<minMN; k++) { - printf( " " ); - } - - printf(" "); - printf("%2d,%3d | ", rank, lmg); - for (k=0; k<libhqr_imin(minMN, lmg+1); k++) { - printf( "%3d ", qrtree->currpiv(qrtree, k, lmg) ); - } - for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) { - printf( " " ); - } - lm++; lmg+=qrtree->p; - if ( lmg >= A->mt ) { - rank++; - lmg = rank; - lm = 0; - } - printf("\n"); + printf("%3d | ", m); + for (k=0; k<libhqr_imin(minMN, m+1); k++) { + printf( "%3d ", qrtree->currpiv(qrtree, k, m) ); + } + for (k=libhqr_imin(minMN, m+1); k<minMN; k++) { + printf( " " ); + } + + printf(" "); + printf("%2d,%3d | ", rank, lmg); + for (k=0; k<libhqr_imin(minMN, lmg+1); k++) { + printf( "%3d ", qrtree->currpiv(qrtree, k, lmg) ); + } + for (k=libhqr_imin(minMN, lmg+1); k<minMN; k++) { + printf( " " ); + } + lm++; lmg+=qrtree->p; + if ( lmg >= A->mt ) { + rank++; + lmg = rank; + lm = 0; + } + printf("\n"); } } @@ -379,15 +321,15 @@ void libhqr_tree_print_next_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int printf( " " ); for(s=A->mt; s>0; s--) - printf( "%3d ", s ); + printf( "%3d ", s ); printf( "\n" ); for(m=0; m<A->mt; m++) { - printf("%3d | ", m); - for(s=A->mt; s>0; s--) { - printf( "%3d ", qrtree->nextpiv(qrtree, k, m, s) ); - } - printf("\n"); + printf("%3d | ", m); + for(s=A->mt; s>0; s--) { + printf( "%3d ", qrtree->nextpiv(qrtree, k, m, s) ); + } + printf("\n"); } } @@ -398,15 +340,15 @@ void libhqr_tree_print_prev_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int printf( " " ); for(s=A->mt; s>-1; s--) - printf( "%3d ", s ); + printf( "%3d ", s ); printf( "\n" ); for(m=0; m<A->mt; m++) { - printf("%3d | ", m); - for(s=A->mt; s>-1; s--) { - printf( "%3d ", qrtree->prevpiv(qrtree, k, m, s) ); - } - printf("\n"); + printf("%3d | ", m); + for(s=A->mt; s>-1; s--) { + printf( "%3d ", qrtree->prevpiv(qrtree, k, m, s) ); + } + printf("\n"); } } @@ -418,19 +360,19 @@ void libhqr_tree_print_perm( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int *p printf("\n------------ Permutation --------------\n"); for (k=0; k<minMN; k++) { - printf( "%3d ", k ); + printf( "%3d ", k ); } printf( "\n" ); for (k=0; k<minMN; k++) { - printf( "----" ); + printf( "----" ); } printf( "\n" ); for (m=0; m < A->mt+1; m++) { - for (k=0; k<minMN; k++) { - printf( "%3d ", perm[ k*(A->mt+1) + m ] ); - } - printf( "\n" ); + for (k=0; k<minMN; k++) { + printf( "%3d ", perm[ k*(A->mt+1) + m ] ); + } + printf( "\n" ); } printf( "\n" ); } @@ -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(" k : "); for (k=0; k<minMN; k++) { - printf( "%3d ", k ); + printf( "%3d ", k ); } printf( "\n" ); printf(" Compute: "); for (k=0; k<minMN; k++) { - nb = 0; - for (m=k; m < A->mt; m++) { - if ( qrtree->gettype(qrtree, k, m) > 0 ) - nb++; - } - printf( "%3d ", nb ); + nb = 0; + for (m=k; m < A->mt; m++) { + if ( qrtree->gettype(qrtree, k, m) > 0 ) + nb++; + } + printf( "%3d ", nb ); } printf( "\n" ); printf(" Formula: "); for (k=0; k<minMN; k++) { - printf( "%3d ", qrtree->getnbgeqrf( qrtree, k ) ); + printf( "%3d ", qrtree->getnbgeqrf( qrtree, k ) ); } printf( "\n" ); } @@ -473,11 +415,11 @@ void libhqr_tree_print_geqrt_k( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, int printf( " m:"); nb = qrtree->getnbgeqrf( qrtree, k ); for (i=0; i < nb; i++) { - m = qrtree->getm( qrtree, k, i ); - if ( i == qrtree->geti( qrtree, k, m) ) - printf( "%3d ", m ); - else - printf( "x%2d ", qrtree->geti( qrtree, k, m) ); + m = qrtree->getm( qrtree, k, i ); + if ( i == qrtree->geti( qrtree, k, m) ) + printf( "%3d ", m ); + else + printf( "x%2d ", qrtree->geti( qrtree, k, m) ); } printf( "\n" ); } @@ -537,64 +479,64 @@ void libhqr_tree_print_dag( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree, char *f /* Print header */ fprintf(f, DAG_HEADER ); /*, A->mt+2, minMN+2 );*/ 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++ ) { - int nb2reduce = A->mt - k - 1; - - for(m=k; m < A->mt; m++) { - 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); - } - - while( nb2reduce > 0 ) { - memset(done, 0, A->mt * sizeof(int) ); - for(m=A->mt-1; m > (k-1); m--) { - n = next[m]; - if ( next[n] != A->mt ) - continue; - if ( n != A->mt ) { - lpos = libhqr_imax( pos[m], pos[n] ); - lpos++; - pos[m] = lpos; - pos[n] = lpos; - - fprintf(f, DAG_NODE, m, n, k, pos[m], m, color[ (m%qrtree->p) % DAG_NBCOLORS ]); - - prev = qrtree->prevpiv( qrtree, k, m, n ); - fprintf(f, DAG_EDGE_PIV, - m, prev, k, - m, n, k, - color[ (m%qrtree->p) % DAG_NBCOLORS ]); - - prev = qrtree->prevpiv( qrtree, k, n, n ); - if ( qrtree->gettype(qrtree, k, n) == 0 ) - fprintf(f, DAG_EDGE_TS, - n, prev, k, - m, n, k, - color[ (m%qrtree->p) % DAG_NBCOLORS ]); - else - fprintf(f, DAG_EDGE_TT, - n, prev, k, - m, n, k, - color[ (m%qrtree->p) % DAG_NBCOLORS ]); - - next[m] = qrtree->nextpiv( qrtree, k, m, n); - done[m] = done[n] = 1; - nb2reduce--; - } - } - } + int nb2reduce = A->mt - k - 1; + + for(m=k; m < A->mt; m++) { + 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); + } + + while( nb2reduce > 0 ) { + memset(done, 0, A->mt * sizeof(int) ); + for(m=A->mt-1; m > (k-1); m--) { + n = next[m]; + if ( next[n] != A->mt ) + continue; + if ( n != A->mt ) { + lpos = libhqr_imax( pos[m], pos[n] ); + lpos++; + pos[m] = lpos; + pos[n] = lpos; + + fprintf(f, DAG_NODE, m, n, k, pos[m], m, color[ (m%qrtree->p) % DAG_NBCOLORS ]); + + prev = qrtree->prevpiv( qrtree, k, m, n ); + fprintf(f, DAG_EDGE_PIV, + m, prev, k, + m, n, k, + color[ (m%qrtree->p) % DAG_NBCOLORS ]); + + prev = qrtree->prevpiv( qrtree, k, n, n ); + if ( qrtree->gettype(qrtree, k, n) == 0 ) + fprintf(f, DAG_EDGE_TS, + n, prev, k, + m, n, k, + color[ (m%qrtree->p) % DAG_NBCOLORS ]); + else + fprintf(f, DAG_EDGE_TT, + n, prev, k, + m, n, k, + color[ (m%qrtree->p) % DAG_NBCOLORS ]); + + next[m] = qrtree->nextpiv( qrtree, k, m, n); + done[m] = done[n] = 1; + nb2reduce--; + } + } + } } length = 0; for(m=0; m < A->mt; m++) { - length = libhqr_imax(length, pos[m]); + length = libhqr_imax(length, pos[m]); } length++; for(k=0; k<length; k++) - fprintf(f, DAG_LENGTHNODE, k, k, k); + fprintf(f, DAG_LENGTHNODE, k, k, k); fprintf(f, DAG_FOOTER); printf("Tic Max = %d\n", length-1); diff --git a/src/libhqr_systolic.c b/src/libhqr_systolic.c index f76dbf80efa0036f71e668442d9835b087909aea..66153a3b0e66ccefdbc371c6aef8167cb8e87da9 100644 --- a/src/libhqr_systolic.c +++ b/src/libhqr_systolic.c @@ -1,24 +1,24 @@ -/* - * 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 - * used in the Xgeqrf_param.jdf file. + * @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 <assert.h> #include <stdio.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 #ifdef PRINT_PIVGEN @@ -63,11 +63,11 @@ static int systolic_gettype( const libhqr_tree_t *qrtree, int k, int m ) { /* Local eliminations with a TS kernel */ if ( m >= k + pq ) - return 0; + return 0; /* Element to be reduce with a single pivot */ else if ( m >= k+p ) - return 1; + return 1; /* Element to be reduced with sq_p pivot */ else return 3; @@ -88,16 +88,16 @@ static int systolic_currpiv(const libhqr_tree_t *qrtree, int k, int m) switch( systolic_gettype( qrtree, k, m ) ) { case 0: - return (m - k) % pq + k; - break; + return (m - k) % pq + k; + break; case 1: - return (m - k) % p + k; - break; + return (m - k) % p + k; + break; case 3: - return k; - break; + return k; + break; 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 lp = systolic_gettype( qrtree, k, pivot ); switch( ls ) - { - case -1: + { + case -1: - if ( lp == LIBHQR_KILLED_BY_TS ) { - myassert( start == mt ); - return mt; - } + if ( lp == LIBHQR_KILLED_BY_TS ) { + myassert( start == mt ); + return mt; + } - case LIBHQR_KILLED_BY_TS: + case LIBHQR_KILLED_BY_TS: - if ( start == mt ) - nextp = pivot + pq; - else - nextp = start + pq; + if ( start == mt ) + nextp = pivot + pq; + else + nextp = start + pq; - if ( nextp < mt ) - return nextp; + if ( nextp < mt ) + return nextp; - start = mt; + start = mt; - case LIBHQR_KILLED_BY_LOCALTREE: + case LIBHQR_KILLED_BY_LOCALTREE: - if (lp < LIBHQR_KILLED_BY_DISTTREE) - return mt; + if (lp < LIBHQR_KILLED_BY_DISTTREE) + return mt; - if ( start == mt ) - nextp = pivot + p; - else - nextp = start + p; + if ( start == mt ) + nextp = pivot + p; + else + nextp = start + p; - if ( (nextp >= k + p) && - (nextp < k + pq) && - (nextp < mt) ) - return nextp; + if ( (nextp >= k + p) && + (nextp < k + pq) && + (nextp < mt) ) + return nextp; - start = mt; + start = mt; - case LIBHQR_KILLED_BY_DISTTREE: + case LIBHQR_KILLED_BY_DISTTREE: - if (pivot > k) - return mt; + if (pivot > k) + return mt; - if ( start == mt ) - nextp = pivot + 1; - else - nextp = start + 1; + if ( start == mt ) + nextp = pivot + 1; + else + nextp = start + 1; - if ( nextp < k + p ) - return nextp; + if ( nextp < k + p ) + return nextp; - default: - return mt; - } + default: + return mt; + } } /** @@ -232,63 +232,63 @@ static int systolic_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s myassert( lp >= ls ); switch( ls ) - { - case LIBHQR_KILLED_BY_DISTTREE: - - if ( pivot == k ) { - if ( start == pivot ) { - nextp = start + p-1; - - while( pivot < nextp && nextp >= mt ) - nextp--; - } else { - nextp = start - 1; - } - - if ( pivot < nextp && - nextp < k + p ) - return nextp; - } - start = pivot; - - case LIBHQR_KILLED_BY_LOCALTREE: - - if ( lp > LIBHQR_KILLED_BY_LOCALTREE ) { - if ( start == pivot ) { - nextp = start + (q-1) * p; - - while( pivot < nextp && - nextp >= mt ) - nextp -= p; - } else { - nextp = start - p; - } - - if ( pivot < nextp && - nextp < k + pq ) - return nextp; - } - start = pivot; - - case LIBHQR_KILLED_BY_TS: - /* Search for predecessor in TS tree */ - if ( lp > LIBHQR_KILLED_BY_TS ) { - if ( start == pivot ) { - nextp = mt - (mt - rpivot - 1)%pq - 1; - - while( pivot < nextp && nextp >= mt ) - nextp -= pq; - } else { - nextp = start - pq; - } - assert(nextp < mt); - if ( pivot < nextp ) - return nextp; - } - - default: - return mt; - } + { + case LIBHQR_KILLED_BY_DISTTREE: + + if ( pivot == k ) { + if ( start == pivot ) { + nextp = start + p-1; + + while( pivot < nextp && nextp >= mt ) + nextp--; + } else { + nextp = start - 1; + } + + if ( pivot < nextp && + nextp < k + p ) + return nextp; + } + start = pivot; + + case LIBHQR_KILLED_BY_LOCALTREE: + + if ( lp > LIBHQR_KILLED_BY_LOCALTREE ) { + if ( start == pivot ) { + nextp = start + (q-1) * p; + + while( pivot < nextp && + nextp >= mt ) + nextp -= p; + } else { + nextp = start - p; + } + + if ( pivot < nextp && + nextp < k + pq ) + return nextp; + } + start = pivot; + + case LIBHQR_KILLED_BY_TS: + /* Search for predecessor in TS tree */ + if ( lp > LIBHQR_KILLED_BY_TS ) { + if ( start == pivot ) { + nextp = mt - (mt - rpivot - 1)%pq - 1; + + while( pivot < nextp && nextp >= mt ) + nextp -= pq; + } else { + nextp = start - pq; + } + assert(nextp < mt); + if ( pivot < nextp ) + return nextp; + } + + default: + return mt; + } }; /** @@ -349,29 +349,29 @@ static int systolic_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int s ******************************************************************************/ int libhqr_systolic_init( libhqr_tree_t *qrtree, - libhqr_typefacto_e trans, libhqr_tiledesc_t *A, - int p, int q ) + libhqr_typefacto_e trans, libhqr_tiledesc_t *A, + int p, int q ) { if (qrtree == NULL) { - fprintf(stderr, "libhqr_systolic_init, illegal value of qrtree"); - return -1; + fprintf(stderr, "libhqr_systolic_init, illegal value of qrtree"); + return -1; } if ((trans != LIBHQR_QR) && - (trans != LIBHQR_LQ)) { - fprintf(stderr, "libhqr_systolic_init, illegal value of trans"); - return -2; + (trans != LIBHQR_LQ)) { + fprintf(stderr, "libhqr_systolic_init, illegal value of trans"); + return -2; } if (A == NULL) { - fprintf(stderr, "libhqr_systolic_init, illegal value of A"); - return -3; + fprintf(stderr, "libhqr_systolic_init, illegal value of A"); + return -3; } if ( p < 0 ) { - fprintf(stderr, "libhqr_systolic_init, illegal value of p"); - return -4; + fprintf(stderr, "libhqr_systolic_init, illegal value of p"); + return -4; } if ( q < -1 ) { - fprintf(stderr, "libhqr_systolic_init, illegal value of q"); - return -5; + fprintf(stderr, "libhqr_systolic_init, illegal value of q"); + return -5; } qrtree->getnbgeqrf = systolic_getnbgeqrf; @@ -415,6 +415,6 @@ void libhqr_systolic_finalize( libhqr_tree_t *qrtree ) { if ( qrtree->args != NULL) { - free( qrtree->args ); + free( qrtree->args ); } } diff --git a/src/queue.c b/src/queue.c new file mode 100644 index 0000000000000000000000000000000000000000..e0ce90521153bc993c960d2e85255d2cfebc3867 --- /dev/null +++ b/src/queue.c @@ -0,0 +1,122 @@ +/** + * + * @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; +} diff --git a/src/treewalk.c b/src/treewalk.c index d38c366f9a1606b0654a8b7e24b435544c68c484..0fbd5f26e978ba6af94d5fe513b31829b84c90c7 100644 --- a/src/treewalk.c +++ b/src/treewalk.c @@ -1,182 +1,65 @@ +/** + * + * @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 <assert.h> -#include <stdlib.h> -#include <string.h> +#include "queue.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 - /**************************************************** - * - * Generic functions for file - * + * LIBHQR_TREEWALK ***************************************************/ - -static void libhqr_file_tile_first (libhqr_file_tile_t ** file_tile); -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; -} - -/**************************************************** +/** + * libhqr_treewalk * - * 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){ - libhqr_file_tile_t **tt; - libhqr_file_tile_t **ts; - libhqr_file_tile_t *p_l = NULL; - libhqr_file_tile_t *p_p = NULL; - int pivot = qrtree->p; +void libhqr_treewalk(const libhqr_tree_t *qrtree,int k){ + int pivot = qrtree->mt; + printf("%d\n" , pivot); int p = pivot; - while(p = qrtree->nextpiv(qrtree, k, pivot,p)){ - - while(p = qrtree->prevpiv(qrtree, k , pivot, p)){ - - if(qrtree->gettype(qrtree, k, p)) libhqr_file_tile_post(tt,p); - libhqr_file_tile_post(ts, p); - - } - libhqr_file_tile_last(ts); - p_l = *ts; - libhqr_file_tile_last(tt); - p_p = *tt; - int a = p_l->numero; - int b = p_p->numero; - while(a != b){ - libhqr_file_tile_get(ts); - libhqr_file_tile_last(ts); - p_l = *ts; - a = p_l->numero; - printf("%d/n" , a); - } - libhqr_file_tile_get(tt); + printf("%d\n" , qrtree->prevpiv(qrtree, k, pivot, p)); + int a,b; + libhqr_queue_tile_t *tt = libhqr_queue_tile_new(); + libhqr_queue_tile_t *ts = libhqr_queue_tile_new(); + while(p = qrtree->prevpiv(qrtree, k, pivot, p)){ + while(p = qrtree->nextpiv(qrtree, k, pivot, p)){ + if(qrtree->gettype(qrtree, k, p)){ + libhqr_queue_tile_post(&tt,p); + } + libhqr_queue_tile_post(&ts, p); + } + libhqr_queue_tile_last(&ts); + libhqr_queue_tile_last(&tt); + a = ts->numero; + printf("%d\n" , a); + b = tt->numero; + printf("%d\n" , b); + while(a != b){ + libhqr_queue_tile_get(&ts); + libhqr_queue_tile_last(&ts); + a = ts->numero; + 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){ - - - } diff --git a/testings/testing_pivgen.c b/testings/testing_pivgen.c index 135f61a7d6e78f099fddd77085060678fb43a8d0..3fa5adde0a311b8dbcc183520723ca87cd2b784e 100644 --- a/testings/testing_pivgen.c +++ b/testings/testing_pivgen.c @@ -1,17 +1,25 @@ -/* - * 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 <stdlib.h> #include <stdio.h> -#include <string.h> -#include <math.h> 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); /* systolic */ todo += nbM * nbN * nbA * nbP; - + /* * * Tests for HQR code diff --git a/testings/testing_treewalk.c b/testings/testing_treewalk.c index 933c64d5e1e741807899a60c462ea9f4b16c77eb..af457479ef8de2af2f9000c573d36fa559822dc2 100644 --- a/testings/testing_treewalk.c +++ b/testings/testing_treewalk.c @@ -1,34 +1,42 @@ -/* - * 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 <stdlib.h> +#include "queue.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_tiledesc_t matrix; - /* - * - * Tests for HQR code - * - */ - matrix.nodes = 1; - matrix.p = 1; - matrix.mt = 10; - matrix.nt = 13; - libhqr_hqr_init( &qrtree, LIBHQR_QR, &matrix, 0, 0, 1, -1, 0, 0); - libhqr_treewalk( &qrtree, 0); - return 1; + libhqr_tree_t qrtree; + libhqr_tiledesc_t matrix; + int minMN, k, rc ; + + /* + * Test treewalk for HQR trees + */ + matrix.nodes = 1; + matrix.p = 1; + matrix.mt = 4; + matrix.nt = 13; + libhqr_hqr_init( &qrtree, LIBHQR_QR, &matrix, -1 , -1 , -1 , -1, 0, 0); + minMN = libhqr_imin(matrix.mt, matrix.nt ); + rc = libhqr_tree_check( &matrix, &qrtree ); + printf("%d\n", rc); + for (k=0; k<minMN; k++) { + libhqr_treewalk( &qrtree, k); + } + libhqr_hqr_finalize( &qrtree ); }