mirror of
https://github.com/TREX-CoE/Sherman-Morrison.git
synced 2024-12-25 13:53:56 +01:00
Code restyled. Added restyling script. Code for determinant is not working because it gets stuck in an infinite recursion loop.
This commit is contained in:
parent
0e5bbbbffb
commit
17c8a1c7a0
@ -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 <typename T> 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 <typename T> 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 <typename T> 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 <typename T> 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 <typename T>
|
||||
bool is_identity2(T *A, unsigned int M, double tolerance) {
|
||||
double det = determinant(A, M);
|
||||
if (det - 1 > tolerance) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T> T norm_max(T *A, unsigned int Dim) {
|
||||
T res = 0;
|
||||
for (unsigned int i = 0; i < Dim; i++) {
|
||||
|
@ -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++) {
|
||||
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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; i<len; i++) {
|
||||
if(str[i] == ',') {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error [verificarlo]: One of your probes has a ',' in its test \
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
if (str[i] == ',') {
|
||||
fprintf(stderr,
|
||||
"Error [verificarlo]: One of your probes has a ',' in its test \
|
||||
or variable name (\"%s\"), which is forbidden\n",
|
||||
str
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
str);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Add a new probe. If an issue with the key is detected (forbidden characters or
|
||||
* a duplicate key), an error will be thrown.
|
||||
*/
|
||||
* Add a new probe. If an issue with the key is detected (forbidden characters
|
||||
* or a duplicate key), an error will be thrown.
|
||||
*/
|
||||
|
||||
int vfc_put_probe(
|
||||
vfc_probes * probes,
|
||||
char * testName, char * varName,
|
||||
double val
|
||||
) {
|
||||
int vfc_put_probe(vfc_probes *probes, char *testName, char *varName,
|
||||
double val) {
|
||||
|
||||
if(probes == NULL) {
|
||||
return 1;
|
||||
}
|
||||
if (probes == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Make sure testName and varName don't contain any ',', which would
|
||||
// interfere with the key/CSV encoding
|
||||
validate_probe_key(testName);
|
||||
validate_probe_key(varName);
|
||||
// Make sure testName and varName don't contain any ',', which would
|
||||
// interfere with the key/CSV encoding
|
||||
validate_probe_key(testName);
|
||||
validate_probe_key(varName);
|
||||
|
||||
// Get the key, which is : testName + "," + varName
|
||||
char * key = gen_probe_key(testName, varName);
|
||||
// Get the key, which is : testName + "," + varName
|
||||
char *key = gen_probe_key(testName, varName);
|
||||
|
||||
// Look for a duplicate key
|
||||
vfc_probe_node * oldProbe = (vfc_probe_node*) vfc_hashmap_get(
|
||||
probes->map, 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
15
tools/restyle.sh
Executable file
15
tools/restyle.sh
Executable file
@ -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
|
Loading…
Reference in New Issue
Block a user