Commit 71227574 authored by CHEVALIER Arthur's avatar CHEVALIER Arthur Committed by Mathieu Faverge
Browse files

feat(parser): Added pastix symbol reader

feat(parser): Parsing symbol file completely
feat(helper): Added helpers to log and set infos in the widget UI
feat(format): Added plugin symbol matrix format
parent 0f351d01
......@@ -25,10 +25,23 @@ set(CMAKE_AUTOUIC ON)
set (MATRIXVISUALIZER_hdrs
MatrixVisualizer.hpp
Helper.hpp
Parsers/Parser.hpp
Parsers/SymbolParser.hpp
Formats/SymbolMatrix.hpp
Parsers/Readers/Pastix.hpp
)
set (MATRIXVISUALIZER_srcs
MatrixVisualizer.cpp
Helper.cpp
Formats/SymbolMatrix.cpp
Parsers/SymbolParser.cpp
Parsers/Readers/Pastix.cpp
)
QT5_WRAP_UI(MATRIXVISUALIZER_forms
......
#include <cstdint>
#include "SymbolMatrix.hpp"
#include "../Helper.hpp"
#include <cstring>
#include <cmath>
static inline int32_t imin(int32_t a, int32_t b)
{
return (a < b) ? a : b;
}
static inline int32_t imax(int32_t a, int32_t b)
{
return (a > b) ? a : b;
}
/* Macros */
#define MEMORY_WRITE(mem) ( ((mem) < 1<<10) ? \
( (double)(mem) ) : \
( ( (mem) < 1<<20 ) ? \
( (double)(mem)/(double)(1<<10) ) : \
( ((mem) < 1<<30 ) ? \
( (double)(mem)/(double)(1<<20) ) : \
( (double)(mem)/(double)(1<<30) ))))
#define MEMORY_UNIT_WRITE(mem) (((mem) < 1<<10) ? \
"o" : \
( ( (mem) < 1<<20 ) ? \
"Ko" : \
( ( (mem) < 1<<30 ) ? \
"Mo" : \
"Go" )))
#define memFree(ptr) free((void*)(ptr))
#define memFree_null(ptr) do \
{ \
memFree( ptr ); \
(ptr) = NULL; \
} while(0)
void symbol_matrix_init(symbol_matrix_t* matrix)
{
memset(matrix, 0, sizeof(symbol_matrix_t));
matrix->m_schurfcol = -1;
return;
}
void symbol_matrix_deinit(symbol_matrix_t* matrix)
{
if (matrix->m_cblktab != nullptr)
memFree_null(matrix->m_cblktab);
if (matrix->m_bloktab != nullptr)
memFree_null(matrix->m_bloktab);
if (matrix->m_browtab != nullptr)
memFree_null(matrix->m_browtab);
memset(matrix, 0, sizeof(symbol_matrix_t));
return;
}
void symbol_matrix_print_stats(symbol_matrix_t* matrix)
{
symbol_cblk_t* cblk;
symbol_blok_t* blok;
int32_t itercblk, dof;
int32_t cblknbr, bloknbr;
int32_t cblkmin, cblkmax;
int32_t blokmin, blokmax;
double cblkavg1, blokavg1;
double cblkavg2, blokavg2;
size_t mem = 0;
cblknbr = matrix->m_cblknbr;
bloknbr = matrix->m_bloknbr;
cblkmin = INT32_MAX;
cblkmax = 0;
cblkavg1 = 0.0;
cblkavg2 = 0.0;
blokmin = INT32_MAX;
blokmax = 0;
blokavg1 = 0.0;
blokavg2 = 0.0;
cblk = matrix->m_cblktab;
blok = matrix->m_bloktab;
for (itercblk = 0; itercblk < cblknbr; ++itercblk, cblk++)
{
int32_t iterblok = cblk[0].m_bloknum + 1;
int32_t lbloknum = cblk[1].m_bloknum;
int32_t colnbr = cblk->m_lcolnum - cblk->m_fcolumn + 1;
cblkmin = imin(cblkmin, colnbr);
cblkmax = imax(cblkmax, colnbr);
cblkavg1 += colnbr;
cblkavg2 += colnbr * colnbr;
blok++;
/* Only extra diagonal */
for (; iterblok < lbloknum; ++iterblok, ++blok)
{
int32_t rownbr = blok->m_lrownum - blok->m_frownum + 1;
blokmin = imin(blokmin, rownbr);
blokmax = imax(blokmax, rownbr);
blokavg1 += rownbr;
blokavg2 += rownbr * rownbr;
}
}
dof = matrix->m_dof;
blokmin *= dof;
blokmax *= dof;
cblkmin *= dof;
cblkmax *= dof;
cblkavg1 = (cblkavg1 * (double)dof) / (double)cblknbr;
blokavg1 = (blokavg1 * (double)dof) / (double)bloknbr;
cblkavg2 = sqrt( ((cblkavg2 * (double)dof * (double)dof) / (double)cblknbr) - cblkavg1 * cblkavg1);
blokavg2 = sqrt( ((blokavg2 * (double)dof * (double)dof) / (double)bloknbr) - blokavg1 * blokavg1);
/* Compute symbol matrix space */
mem = sizeof(symbol_matrix_t);
mem += sizeof(symbol_cblk_t) * (cblknbr + 1);
mem += sizeof(symbol_blok_t) * matrix->m_bloknbr;
mem += sizeof(int32_t) * bloknbr;
Helper::set_infos(
"Symbol Matrix statistics:\n"
" Number of cblk %10ld\n"
" Number of blok %10ld\n"
" Cblk width min %10ld\n"
" Cblk width max %10ld\n"
" Cblk width avg %11.2lf\n"
" Cblk width stdev %11.2lf\n"
" Blok height min %10ld\n"
" Blok height max %10ld\n"
" Blok height avg %11.2lf\n"
" Blok height stdev %11.2lf\n"
" Memory space %11.2lf %s\n",
(long)cblknbr, (long)bloknbr,
(long)cblkmin, (long)cblkmax, cblkavg1, cblkavg2,
(long)blokmin, (long)blokmax, blokavg1, blokavg2,
MEMORY_WRITE( mem ), MEMORY_UNIT_WRITE( mem )
);
}
#ifndef SYMBOL_MATRIX_HPP
#define SYMBOL_MATRIX_HPP
typedef struct symbol_cblk_s
{
int32_t m_fcolumn;
int32_t m_lcolnum;
int32_t m_bloknum;
int32_t m_brownum;
} symbol_cblk_t;
typedef struct symbol_blok_s
{
int32_t m_frownum;
int32_t m_lrownum;
int32_t m_lcblknm;
int32_t m_fcblknm;
} symbol_blok_t;
typedef struct symbol_matrix_s
{
int32_t m_baseval;
int32_t m_dof;
int32_t m_cblknbr;
int32_t m_bloknbr;
int32_t m_nodenbr;
int32_t m_schurfcol;
symbol_cblk_t* m_cblktab;
symbol_blok_t* m_bloktab;
int32_t* m_browtab;
} symbol_matrix_t;
void symbol_matrix_init(symbol_matrix_t* matrix);
void symbol_matrix_deinit(symbol_matrix_t* matrix);
void symbol_matrix_print_stats(symbol_matrix_t* matrix);
#endif
#include "Helper.hpp"
#include <cstdarg>
#include <QWidget>
#include "plugin/Plugin.hpp"
// Generated
#include "ui_widget.h"
#include "Parsers/Parser.hpp"
#include "Formats/SymbolMatrix.hpp"
#include "Parsers/SymbolParser.hpp"
#include "MatrixVisualizer.hpp"
namespace Helper
{
void log(LogStatus status, const char* format, ...)
{
va_list ap;
va_start(ap, format);
Matrix_visualizer::Get()->log(status, format, ap);
va_end(ap);
}
void set_infos(const char* format, ...)
{
va_list ap;
va_start(ap, format);
Matrix_visualizer::Get()->set_infos(format, ap);
va_end(ap);
}
}
#ifndef HELPER_HPP
#define HELPER_HPP
enum LogStatus
{
MESSAGE,
WARNING,
ERROR,
COUNT
};
namespace Helper
{
void log(LogStatus status, const char* format, ...);
void set_infos(const char* format, ...);
}
#endif
......@@ -11,9 +11,17 @@
// Generated
#include "ui_widget.h"
#include "Parsers/Parser.hpp"
#include "Formats/SymbolMatrix.hpp"
#include "Parsers/SymbolParser.hpp"
#include "Helper.hpp"
#include "MatrixVisualizer.hpp"
Plugin *create() { return Matrix_visualizer::Get(); }
Matrix_visualizer* Matrix_visualizer::s_plugin = nullptr;
SymbolParser Matrix_visualizer::s_symbol_parser;
Matrix_visualizer::Matrix_visualizer() {
setupUi(this);
......@@ -23,6 +31,16 @@ Matrix_visualizer::Matrix_visualizer() {
this->connect_widgets();
}
Matrix_visualizer* Matrix_visualizer::Get()
{
static Matrix_visualizer* instance = nullptr;
if (instance == nullptr)
instance = new Matrix_visualizer();
return instance;
}
void Matrix_visualizer::connect_widgets()
{
QObject::connect(this->tool_button_symbol, &QToolButton::clicked,
......@@ -39,7 +57,8 @@ void Matrix_visualizer::connect_widgets()
}
Matrix_visualizer::~Matrix_visualizer(){
std::cout << "Destroying..." << std::endl;
s_plugin = nullptr;
}
void Matrix_visualizer::init(){
......@@ -64,27 +83,36 @@ void Matrix_visualizer::execute(){
if (symbol_filepath.size() == 0)
{
this->log(LogStatus::ERROR, "Empty filepath for symbol matrix file...");
Helper::log(LogStatus::ERROR, "Empty filepath for symbol matrix file...");
return;
}
if (values_filepath.size() == 0)
{
this->log(LogStatus::WARNING, "Empty filepath for values file...");
Helper::log(LogStatus::WARNING, "Empty filepath for values file...");
}
// Parse the symbol file
Helper::log(LogStatus::MESSAGE, "Parsing symbol file...");
symbol_matrix_t* symbol_matrix = s_symbol_parser.parse(symbol_filepath.toStdString());
if (symbol_matrix != nullptr)
{
Helper::log(LogStatus::MESSAGE, "Successfully readed symbol file");
symbol_matrix_print_stats(symbol_matrix);
symbol_matrix_deinit(symbol_matrix);
delete symbol_matrix;
}
}
void Matrix_visualizer::log(LogStatus status, const char* format, ...)
void Matrix_visualizer::log(LogStatus status, const char* format, va_list ap)
{
va_list ap;
va_start(ap, format);
char message[256] = {0};
vsnprintf(message, 256, format, ap);
va_end(ap);
QString previous_text = this->text_edit_logs->toPlainText();
switch(status)
......@@ -106,6 +134,18 @@ void Matrix_visualizer::log(LogStatus status, const char* format, ...)
this->text_edit_logs->setText(previous_text);
}
void Matrix_visualizer::set_infos(const char* format, va_list ap)
{
char message[2048] = {0};
vsnprintf(message, 2048, format, ap);
QString to_print = message;
this->text_edit_infos->clear();
this->text_edit_infos->setText(to_print);
}
/***********************
* Buttons
**********************/
......
......@@ -3,17 +3,7 @@
class Matrix_visualizer : public Plugin, public Ui::Matrix_visualizer_widget_ui {
public:
enum LogStatus
{
MESSAGE,
WARNING,
ERROR,
COUNT
};
public:
Matrix_visualizer();
static Matrix_visualizer* Get();
~Matrix_visualizer();
void init();
......@@ -22,9 +12,12 @@ public:
void set_arguments(std::map<std::string /*argname*/, QVariant* /*argValue*/>);
std::string get_name();
void log(LogStatus status, const char* format, ...);
void log(LogStatus status, const char* format, va_list ap);
void set_infos(const char* format, va_list ap);
private:
Matrix_visualizer();
void connect_widgets();
public slots:
......@@ -38,12 +31,13 @@ private slots:
private:
static Matrix_visualizer* s_plugin;
static SymbolParser s_symbol_parser;
};
extern "C"
#ifdef WIN32
__declspec(dllexport) // no comment
#endif
Plugin *create() { return new Matrix_visualizer(); }
Plugin *create();
#endif
#ifndef PARSER_MATRIX_VISUALIZER_HPP
#define PARSER_MATRIX_VISUALIZER_HPP
template <typename T>
class Parser
{
public:
Parser(){}
virtual T* parse(std::string path) = 0;
virtual float get_percent_loaded() const = 0;
virtual bool is_finished() const = 0;
virtual bool is_cancelled() const = 0;
virtual void set_canceled() = 0;
virtual void finish() = 0;
protected:
bool m_is_finished;
bool m_is_canceled;
};
#endif
#include <cstdlib>
#include <cstdint>
#include <ctype.h>
#include <cstdio>
#include "../../Formats/SymbolMatrix.hpp"
#include "Pastix.hpp"
#include "../../Helper.hpp"
int pastix_read_symbol(FILE* stream, symbol_matrix_t* matrix)
{
int32_t versval;
int32_t i, j;
int32_t cblknum;
int32_t bloknum;
if ((pastix_read_int(stream, &versval) +
pastix_read_int(stream, &matrix->m_cblknbr) +
pastix_read_int(stream, &matrix->m_bloknbr) +
pastix_read_int(stream, &matrix->m_nodenbr) +
pastix_read_int(stream, &matrix->m_baseval) != 5) ||
(versval < 0) ||
(versval > 1) ||
(matrix->m_bloknbr < matrix->m_cblknbr) ||
(matrix->m_nodenbr < matrix->m_cblknbr))
{
Helper::log(LogStatus::ERROR, "Loading symbol file %s, bad header !");
return 1;
}
Helper::log(LogStatus::MESSAGE,
"Loaded header:\n"
" Version: %10d\n"
" Number of cblk: %10d\n"
" Number of blok: %10d\n"
" Number of nodes: %10d\n"
" Base value: %10d\n",
versval,
matrix->m_cblknbr, matrix->m_bloknbr,
matrix->m_nodenbr, matrix->m_baseval
);
matrix->m_cblktab = (symbol_cblk_t*)malloc((matrix->m_cblknbr + 1) * sizeof(symbol_cblk_t));
matrix->m_bloktab = (symbol_blok_t*)malloc(matrix->m_bloknbr * sizeof(symbol_blok_t));
if (matrix->m_cblktab == nullptr || matrix->m_bloktab == nullptr)
{
Helper::log(LogStatus::ERROR, "Out of memory while allocating tabs !");
return 1;
}
int32_t cblknbr = matrix->m_cblknbr;
for (cblknum = 0; cblknum < cblknbr; ++cblknum)
{
if ((pastix_read_int(stream, &matrix->m_cblktab[cblknum].m_fcolumn) +
pastix_read_int(stream, &matrix->m_cblktab[cblknum].m_lcolnum) +
pastix_read_int(stream, &matrix->m_cblktab[cblknum].m_bloknum) != 3) ||
(matrix->m_cblktab[cblknum].m_fcolumn > matrix->m_cblktab[cblknum].m_lcolnum))
{
Helper::log(LogStatus::ERROR, "Bad input while reading cblk !");
return 1;
}
}
matrix->m_cblktab[cblknbr].m_fcolumn = matrix->m_cblktab[cblknbr].m_lcolnum = matrix->m_nodenbr + matrix->m_baseval;
int32_t bloknbr = matrix->m_bloknbr;
for (bloknum = 0; bloknum < bloknbr; ++bloknum)
{
if ((pastix_read_int(stream, &matrix->m_bloktab[bloknum].m_frownum) +
pastix_read_int(stream, &matrix->m_bloktab[bloknum].m_lrownum) +
pastix_read_int(stream, &matrix->m_bloktab[bloknum].m_fcblknm) != 3) ||
(matrix->m_bloktab[bloknum].m_frownum > matrix->m_bloktab[bloknum].m_lrownum))
{
Helper::log(LogStatus::ERROR, "Bad input while reading blok %d !", bloknum);
Helper::log(LogStatus::MESSAGE, "%d %d %d", matrix->m_bloktab[bloknum].m_frownum,
matrix->m_bloktab[bloknum].m_lrownum,
matrix->m_bloktab[bloknum].m_fcblknm);
return 1;
}
}
return 0;
}
int pastix_read_int(FILE* stream, int32_t* const value)
{
int32_t val;
int sign;
int car;
sign = 0;
for ( ; ; )
{
car = getc(stream);
if (isspace(car))
continue;
if ((car >= '0') && (car <= '9'))
break;
if (car == '-')
{
sign = 1;
car = getc(stream);
break;
}
if (car == '+')
{
car = getc(stream);
break;
}
return (0);
}
if ((car < '0') || (car > '9'))
{
return (0);
}
val = car - '0';
for ( ; ; )
{
car = getc(stream);
if ((car < '0') || (car > '9'))
{
ungetc(car, stream);
break;
}
val = val * 10 + (car - '0');
}
// Maybe do: *value = (sign << 31 | val);
*value = (sign != 0) ? (-val) : val;
return (1);
}
#ifndef READER_PASTIX_HPP
#define READER_PASTIX_HPP
// Functionnal
int pastix_read_int(FILE* stream, int32_t* value);
// Reader
int pastix_read_symbol(FILE* stream, symbol_matrix_t* matrix);