diff --git a/include/SM_Helpers.hpp b/include/SM_Helpers.hpp index 8f7d6e8..0840dcc 100644 --- a/include/SM_Helpers.hpp +++ b/include/SM_Helpers.hpp @@ -81,53 +81,102 @@ T1 *outProd(T1 *vec1, T2 *vec2, unsigned int M) { } return C; } + +// // This flat version doesn't work. Get's stuck in an infinite recursion loop. +// template T determinant(T *A, unsigned int M) { +// std::cout << "determinant() called..." << std::endl; +// T det = 0; +// int p, h, k, i, j; +// T *temp = new T[M * M]; +// if (M == 1) { +// return A[0]; +// } else if (M == 2) { +// det = (A[0] * A[3] - A[1] * A[2]); +// return det; +// } else { +// for (p = 0; p < M; p++) { +// h = 0; +// k = 0; +// for (i = 1; i < M; i++) { +// for (j = 0; j < M; j++) { +// if (j == p) { +// continue; +// } +// temp[h * M + k] = A[i * M + j]; +// k++; +// if (k == M - 1) { +// h++; +// k = 0; +// } +// } +// } +// det = det + A[p] * pow(-1, p) * determinant(temp, M - 1); +// } +// return det; +// } +// delete temp; +// } -template T matDet(T **A, unsigned int M) { - int det = 0, p, h, k, i, j; - T **temp = new T *[M]; - for (int i = 0; i < M; i++) - temp[i] = new T[M]; - if (M == 1) { - return A[0][0]; - } else if (M == 2) { - det = (A[0][0] * A[1][1] - A[0][1] * A[1][0]); - return det; - } else { - for (p = 0; p < M; p++) { - h = 0; - k = 0; - for (i = 1; i < M; i++) { - for (j = 0; j < M; j++) { - if (j == p) { - continue; - } - temp[h][k] = A[i][j]; - k++; - if (k == M - 1) { - h++; - k = 0; - } - } - } - det = det + A[0][p] * pow(-1, p) * matDet(temp, M - 1); - } - return det; - } - delete[] temp; -} +// // This version also gets stuck in a recursion loop +// template T determinant(T **A, unsigned int M) { +// int p, h, k, i, j; +// T det = 0; +// T **temp = new T *[M]; +// for (int i = 0; i < M; i++) { +// temp[i] = new T[M]; +// } +// if (M == 1) { +// return A[0][0]; +// } else if (M == 2) { +// det = (A[0][0] * A[1][1] - A[0][1] * A[1][0]); +// return det; +// } else { +// for (p = 0; p < M; p++) { +// h = 0; +// k = 0; +// for (i = 1; i < M; i++) { +// for (j = 0; j < M; j++) { +// if (j == p) { +// continue; +// } +// temp[h][k] = A[i][j]; +// k++; +// if (k == M - 1) { +// h++; +// k = 0; +// } +// } +// } +// det = det + A[0][p] * pow(-1, p) * determinant(temp, M - 1); +// } +// return det; +// } +// delete[] temp; +// } template bool is_identity(T *A, unsigned int M, double tolerance) { for (unsigned int i = 0; i < M; i++) { for (unsigned int j = 0; j < M; j++) { - if (i == j && std::fabs(A[i * M + j] - 1) > tolerance) + if (i == j && std::fabs(A[i * M + j] - 1) > tolerance) { return false; - if (i != j && std::fabs(A[i * M + j]) > tolerance) + } + if (i != j && std::fabs(A[i * M + j]) > tolerance) { return false; + } } } return true; } +template +bool is_identity2(T *A, unsigned int M, double tolerance) { + double det = determinant(A, M); + if (det - 1 > tolerance) { + return false; + } + return true; +} + template T norm_max(T *A, unsigned int Dim) { T res = 0; for (unsigned int i = 0; i < Dim; i++) { diff --git a/include/vfc_hashmap.h b/include/vfc_hashmap.h index c314f0e..a4e5216 100644 --- a/include/vfc_hashmap.h +++ b/include/vfc_hashmap.h @@ -87,7 +87,7 @@ void vfc_hashmap_destroy(vfc_hashmap_t map) { // allocate and initialize the map vfc_hashmap_t vfc_hashmap_create() { - vfc_hashmap_t map = (vfc_hashmap_t) calloc(1, sizeof(struct vfc_hashmap_st)); + vfc_hashmap_t map = (vfc_hashmap_t)calloc(1, sizeof(struct vfc_hashmap_st)); if (map == NULL) { return NULL; @@ -96,7 +96,7 @@ vfc_hashmap_t vfc_hashmap_create() { map->capacity = (size_t)(1 << map->nbits); map->mask = map->capacity - 1; // an item is now a value and a key - map->items = (size_t *) calloc(map->capacity, 2 * sizeof(size_t)); + map->items = (size_t *)calloc(map->capacity, 2 * sizeof(size_t)); if (map->items == NULL) { vfc_hashmap_destroy(map); return NULL; @@ -160,7 +160,7 @@ static void maybe_rehash_map(vfc_hashmap_t map) { map->nbits++; map->capacity = (size_t)(1 << map->nbits); map->mask = map->capacity - 1; - map->items = (size_t *) calloc(map->capacity, 2 * sizeof(size_t)); + map->items = (size_t *)calloc(map->capacity, 2 * sizeof(size_t)); map->nitems = 0; map->n_deleted_items = 0; for (ii = 0; ii < old_capacity; ii++) { diff --git a/include/vfc_probe.h b/include/vfc_probe.h index 0d716d1..8d91b19 100644 --- a/include/vfc_probe.h +++ b/include/vfc_probe.h @@ -1,254 +1,217 @@ /* -* This file defines "vfc_probes", a hashtable-based structure which can be used -* to place "probes" in a code and store the different values of test variables. -* These test results can then be exported in a CSV file, and used to generate a -* Verificarlo test report. -*/ - + * This file defines "vfc_probes", a hashtable-based structure which can be used + * to place "probes" in a code and store the different values of test variables. + * These test results can then be exported in a CSV file, and used to generate a + * Verificarlo test report. + */ +#include #include #include -#include #include "vfc_hashmap.h" -#define VAR_NAME(var) #var // Simply returns the name of var into a string - +#define VAR_NAME(var) #var // Simply returns the name of var into a string /* -* A probe containing a double value as well as its key, which is needed when -* dumping the probes -*/ + * A probe containing a double value as well as its key, which is needed when + * dumping the probes + */ struct vfc_probe_node { - char * key; - double value; + char *key; + double value; }; typedef struct vfc_probe_node vfc_probe_node; - - /* -* The probes structure. It simply acts as a wrapper for a Verificarlo hashmap. -*/ + * The probes structure. It simply acts as a wrapper for a Verificarlo hashmap. + */ struct vfc_probes { - vfc_hashmap_t map; + vfc_hashmap_t map; }; typedef struct vfc_probes vfc_probes; - /* -* Initialize an empty vfc_probes instance -*/ + * Initialize an empty vfc_probes instance + */ vfc_probes vfc_init_probes() { - vfc_probes probes; - probes.map = vfc_hashmap_create(); + vfc_probes probes; + probes.map = vfc_hashmap_create(); - return probes; + return probes; } - - /* -* Free all probes -*/ + * Free all probes + */ -void vfc_free_probes(vfc_probes * probes) { +void vfc_free_probes(vfc_probes *probes) { - // Before freeing the map, iterate manually over all items to free the keys - vfc_probe_node * probe = NULL; - for(int i = 0; i < probes->map->capacity; i++) { - probe = (vfc_probe_node*) get_value_at(probes->map->items, i); - if(probe != NULL) { - if(probe->key != NULL) { - free(probe->key); - } - } + // Before freeing the map, iterate manually over all items to free the keys + vfc_probe_node *probe = NULL; + for (int i = 0; i < probes->map->capacity; i++) { + probe = (vfc_probe_node *)get_value_at(probes->map->items, i); + if (probe != NULL) { + if (probe->key != NULL) { + free(probe->key); + } } + } - vfc_hashmap_free(probes->map); + vfc_hashmap_free(probes->map); } - - /* -* Helper function to generate the key from test and variable name -*/ + * Helper function to generate the key from test and variable name + */ -char * gen_probe_key(char * testName, char * varName) { - char * key = (char *) malloc(strlen(testName) + strlen(varName) + 2); - strcpy(key, testName); - strcat(key, ","); - strcat(key, varName); +char *gen_probe_key(char *testName, char *varName) { + char *key = (char *)malloc(strlen(testName) + strlen(varName) + 2); + strcpy(key, testName); + strcat(key, ","); + strcat(key, varName); - return key; + return key; } - - /* -* Helper function to detect forbidden character ',' in the keys -*/ + * Helper function to detect forbidden character ',' in the keys + */ -void validate_probe_key(char * str) { - unsigned int len = strlen(str); +void validate_probe_key(char *str) { + unsigned int len = strlen(str); - for(unsigned int i=0; imap, vfc_hashmap_str_function(key) - ); + // Look for a duplicate key + vfc_probe_node *oldProbe = (vfc_probe_node *)vfc_hashmap_get( + probes->map, vfc_hashmap_str_function(key)); - if(oldProbe != NULL) { - if(strcmp(key, oldProbe->key) == 0) { - fprintf( - stderr, - "Error [verificarlo]: you have a duplicate error with one of \ + if (oldProbe != NULL) { + if (strcmp(key, oldProbe->key) == 0) { + fprintf(stderr, + "Error [verificarlo]: you have a duplicate error with one of \ your probes (\"%s\"). Please make sure to use different names.\n", - key - ); - exit(1); - } + key); + exit(1); } + } - // Insert the element in the hashmap - vfc_probe_node * newProbe = (vfc_probe_node*) malloc(sizeof(vfc_probe_node)); - newProbe->key = key; - newProbe->value = val; + // Insert the element in the hashmap + vfc_probe_node *newProbe = (vfc_probe_node *)malloc(sizeof(vfc_probe_node)); + newProbe->key = key; + newProbe->value = val; - vfc_hashmap_insert( - probes->map, vfc_hashmap_str_function(key), newProbe - ); + vfc_hashmap_insert(probes->map, vfc_hashmap_str_function(key), newProbe); + return 0; +} + +/* + * Remove (free) an element from the hash table + */ + +int vfc_remove_probe(vfc_probes *probes, char *testName, char *varName) { + + if (probes == NULL) { + return 1; + } + + // Get the key, which is : testName + "," + varName + char *key = gen_probe_key(testName, varName); + + vfc_hashmap_remove(probes->map, vfc_hashmap_str_function(key)); + + return 0; +} + +/* + * Return the number of probes stored in the hashmap + */ + +unsigned int vfc_num_probes(vfc_probes *probes) { + return vfc_hashmap_num_items(probes->map); +} + +/* + * Dump probes in a .csv file (the double values are converted to hex), then + * free it. + */ + +int vfc_dump_probes(vfc_probes *probes) { + + if (probes == NULL) { + return 1; + } + + // Get export path from the VFC_PROBES_OUTPUT env variable + char *exportPath = getenv("VFC_PROBES_OUTPUT"); + if (!exportPath) { + printf("Warning [verificarlo]: VFC_PROBES_OUTPUT is not set, probes will \ + not be dumped\n"); + vfc_free_probes(probes); return 0; -} + } + FILE *fp = fopen(exportPath, "w"); - -/* -* Remove (free) an element from the hash table -*/ - -int vfc_remove_probe(vfc_probes * probes, char * testName, char * varName) { - - if(probes == NULL) { - return 1; - } - - // Get the key, which is : testName + "," + varName - char * key = gen_probe_key(testName, varName); - - vfc_hashmap_remove(probes->map, vfc_hashmap_str_function(key)); - - return 0; -} - - - -/* -* Return the number of probes stored in the hashmap -*/ - -unsigned int vfc_num_probes(vfc_probes * probes) { - return vfc_hashmap_num_items(probes->map); -} - - - -/* -* Dump probes in a .csv file (the double values are converted to hex), then -* free it. -*/ - -int vfc_dump_probes(vfc_probes * probes) { - - if(probes == NULL) { - return 1; - } - - // Get export path from the VFC_PROBES_OUTPUT env variable - char* exportPath = getenv("VFC_PROBES_OUTPUT"); - if(!exportPath) { - printf( - "Warning [verificarlo]: VFC_PROBES_OUTPUT is not set, probes will \ - not be dumped\n" - ); - vfc_free_probes(probes); - return 0; - } - - FILE * fp = fopen(exportPath, "w"); - - if(fp == NULL) { - fprintf( - stderr, + if (fp == NULL) { + fprintf(stderr, "Error [verificarlo]: impossible to open the CSV file to save your \ probes (\"%s\")\n", - exportPath - ); - exit(1); + exportPath); + exit(1); + } + + // First line gives the column names + fprintf(fp, "test,variable,value\n"); + + // Iterate over all table elements + vfc_probe_node *probe = NULL; + for (int i = 0; i < probes->map->capacity; i++) { + probe = (vfc_probe_node *)get_value_at(probes->map->items, i); + if (probe != NULL) { + fprintf(fp, "%s,%a\n", probe->key, probe->value); } + } - // First line gives the column names - fprintf(fp, "test,variable,value\n"); + fclose(fp); - // Iterate over all table elements - vfc_probe_node * probe = NULL; - for(int i = 0; i < probes->map->capacity; i++) { - probe = (vfc_probe_node*) get_value_at(probes->map->items, i); - if(probe != NULL) { - fprintf( - fp, "%s,%a\n", - probe->key, - probe->value - ); - } - } + vfc_free_probes(probes); - fclose(fp); - - vfc_free_probes(probes); - - return 0; + return 0; } diff --git a/tests/test_h5.cpp b/tests/test_h5.cpp index 6fe6bea..2724512 100644 --- a/tests/test_h5.cpp +++ b/tests/test_h5.cpp @@ -100,6 +100,19 @@ int test_cycle(H5File file, int cycle, std::string version, double tolerance) { double res_max = residual_max(res, dim); double res2 = residual_frobenius2(res, dim); + // double det; + // double **tmp = new double *[dim]; + // for (int i = 0; i < dim; i++) { + // tmp[i] = new double[dim]; + // for (int j = 0; j < dim; j++) { + // tmp[i][j] = res[i * dim + j]; + // } + // } + // det = determinant(tmp, dim); + // delete[] tmp; + // std::cout << "Residual = " << version << " " << cycle << " " << res_max << + // " " + // << res2 << " " << det << std::endl; std::cout << "Residual = " << version << " " << cycle << " " << res_max << " " << res2 << std::endl; diff --git a/tools/restyle.sh b/tools/restyle.sh new file mode 100755 index 0000000..ba07f81 --- /dev/null +++ b/tools/restyle.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +STYLE='--style=LLVM' +FORMATER='clang-format -i' + +if [[ -z $SMVARS ]] +then + echo '$SMVARS is not set. Please source '/path/to/Sherman-Morrison/smvars.sh'' + exit 1 +fi + +for ext in c cpp h hpp +do + find $SMROOT -type f -iname "*.${ext}" -exec echo "$FORMATER $STYLE" {} \; +done \ No newline at end of file