Update integration of vfc_probes

vfc_probes used to be built along the code in the previous versions.
This has been removed so that the verison used is the one provided
system wide by Verificarlo. Moreover, vfc_test_h5.cpp has been update to
reflect the name changes of vfc_probes functions.
This commit is contained in:
Aurélien Delval 2021-09-02 12:37:22 +02:00
parent ecb6018cc0
commit 7e42a000c4
4 changed files with 6 additions and 471 deletions

View File

@ -10,7 +10,7 @@ H5FLAGS = "-I/usr/include/hdf5/serial \
/usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5_cpp.a \
/usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5_hl.a \
/usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5.a \
-lpthread -lsz -lz -ldl -lm \
-lpthread -lsz -lz -ldl -lm -lvfc_probes \
-Wl,-rpath -Wl,/usr/lib/x86_64-linux-gnu/hdf5/serial"
CXXFLAGS = -O0 -g $(H5FLAGS)
## MKL linker flags
@ -20,11 +20,11 @@ ifeq ($(MKL),-DMKL)
ifeq ($(ENV),INTEL)
LFLAGS = -mkl=sequential # implicit
else
LFLAGS = $(H5LFLAGS) -lvfc_probes
LFLAGS = $(H5LFLAGS)
endif
endif
H5CXXFLAGS = $(CXXFLAGS)
FFLAGS = $(CXXFLAGS)
FFLAGS = $(CXXFLAGS) -lvfc_probes_f
INCLUDE = -I $(INC_DIR)/
DEPS_CXX = $(OBJ_DIR)/SM_Maponi.o \

View File

@ -1,248 +0,0 @@
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright 2012 Couchbase, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#define HASH_MULTIPLIER 31
static const unsigned int hashmap_prime_1 = 73;
static const unsigned int hashmap_prime_2 = 5009;
#ifndef __VFC_HASHMAP_HEADER__
struct vfc_hashmap_st {
size_t nbits;
size_t mask;
size_t capacity;
size_t *items;
size_t nitems;
size_t n_deleted_items;
};
typedef struct vfc_hashmap_st *vfc_hashmap_t;
// allocate and initialize the map
vfc_hashmap_t vfc_hashmap_create();
// get the value at an index of a map
size_t get_value_at(size_t *items, size_t i);
// get the key at an index of a map
size_t get_key_at(size_t *items, size_t i);
// set the value at an index of a map
void set_value_at(size_t *items, size_t value, size_t i);
// set the key at an index of a map
void set_key_at(size_t *items, size_t key, size_t i);
// free the map
void vfc_hashmap_destroy(vfc_hashmap_t map);
// insert an element in the map
void vfc_hashmap_insert(vfc_hashmap_t map, size_t key, void *item);
// remove an element of the map
void vfc_hashmap_remove(vfc_hashmap_t map, size_t key);
// test if an element is in the map
char vfc_hashmap_have(vfc_hashmap_t map, size_t key);
// get an element of the map
void *vfc_hashmap_get(vfc_hashmap_t map, size_t key);
// get the number of elements in the map
size_t vfc_hashmap_num_items(vfc_hashmap_t map);
// Hash function
size_t vfc_hashmap_str_function(const char *id);
#endif
/***************** Verificarlo hashmap FUNCTIONS ********************
* The following set of functions are used in backends and wrapper
* to stock and access quickly internal data.
*******************************************************************/
// free the map
void vfc_hashmap_destroy(vfc_hashmap_t map) {
if (map) {
free(map->items);
}
free(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));
if (map == NULL) {
return NULL;
}
map->nbits = 3;
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));
if (map->items == NULL) {
vfc_hashmap_destroy(map);
return NULL;
}
map->nitems = 0;
map->n_deleted_items = 0;
return map;
}
size_t get_value_at(size_t *items, size_t i) { return items[i * 2]; }
size_t get_key_at(size_t *items, size_t i) { return items[(i * 2) + 1]; }
void set_value_at(size_t *items, size_t value, size_t i) {
items[i * 2] = value;
}
void set_key_at(size_t *items, size_t key, size_t i) {
items[(i * 2) + 1] = key;
}
// add a member in the table
static int hashmap_add_member(vfc_hashmap_t map, size_t key, void *item) {
size_t value = (size_t)item;
size_t ii;
if (value == 0 || value == 1) {
return -1;
}
ii = map->mask & (hashmap_prime_1 * key);
while (get_value_at(map->items, ii) != 0 &&
get_value_at(map->items, ii) != 1) {
if (get_value_at(map->items, ii) == value) {
return 0;
} else {
/* search free slot */
ii = map->mask & (ii + hashmap_prime_2);
}
}
map->nitems++;
if (get_value_at(map->items, ii) == 1) {
map->n_deleted_items--;
}
set_value_at(map->items, value, ii);
set_key_at(map->items, key, ii);
return 1;
}
// rehash the table if necessary
static void maybe_rehash_map(vfc_hashmap_t map) {
size_t *old_items;
size_t old_capacity, ii;
if (map->nitems + map->n_deleted_items >= (double)map->capacity * 0.85) {
old_items = map->items;
old_capacity = map->capacity;
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->nitems = 0;
map->n_deleted_items = 0;
for (ii = 0; ii < old_capacity; ii++) {
hashmap_add_member(map, get_key_at(old_items, ii),
(void *)get_value_at(old_items, ii));
}
free(old_items);
}
}
// insert an element in the map
void vfc_hashmap_insert(vfc_hashmap_t map, size_t key, void *item) {
hashmap_add_member(map, key, item);
maybe_rehash_map(map);
}
// remove an element of the map
void vfc_hashmap_remove(vfc_hashmap_t map, size_t key) {
size_t ii = map->mask & (hashmap_prime_1 * key);
while (get_value_at(map->items, ii) != 0) {
if (get_key_at(map->items, ii) == key) {
set_value_at(map->items, 1, ii);
map->nitems--;
map->n_deleted_items++;
break;
} else {
ii = map->mask & (ii + hashmap_prime_2);
}
}
}
// test if an element is in the map
char vfc_hashmap_have(vfc_hashmap_t map, size_t key) {
size_t ii = map->mask & (hashmap_prime_1 * key);
while (get_value_at(map->items, ii) != 0) {
if (get_key_at(map->items, ii) == key) {
return 1;
} else {
ii = map->mask & (ii + hashmap_prime_2);
}
}
return 0;
}
// get an element of the map
void *vfc_hashmap_get(vfc_hashmap_t map, size_t key) {
size_t ii = map->mask & (hashmap_prime_1 * key);
while (get_value_at(map->items, ii) != 0) {
if (get_key_at(map->items, ii) == key) {
return (void *)get_value_at(map->items, ii);
} else {
ii = map->mask & (ii + hashmap_prime_2);
}
}
return NULL;
}
// get the number of elements in the map
size_t vfc_hashmap_num_items(vfc_hashmap_t map) { return map->nitems; }
// Hash function for strings
size_t vfc_hashmap_str_function(const char *id) {
unsigned const char *us;
us = (unsigned const char *)id;
size_t index = 0;
while (*us != '\0') {
index = index * HASH_MULTIPLIER + *us;
us++;
}
return index;
}
// Free the hashmap
void vfc_hashmap_free(vfc_hashmap_t map) {
for (int ii = 0; ii < map->capacity; ii++)
if (get_value_at(map->items, ii) != 0 && get_value_at(map->items, ii) != 0)
free((void *)get_value_at(map->items, ii));
}

View File

@ -1,217 +0,0 @@
/*
* 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 "vfc_hashmap.h"
#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
*/
struct vfc_probe_node {
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.
*/
struct vfc_probes {
vfc_hashmap_t map;
};
typedef struct vfc_probes vfc_probes;
/*
* Initialize an empty vfc_probes instance
*/
vfc_probes vfc_init_probes() {
vfc_probes probes;
probes.map = vfc_hashmap_create();
return probes;
}
/*
* Free all 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);
}
}
}
vfc_hashmap_free(probes->map);
}
/*
* 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);
return key;
}
/*
* Helper function to detect forbidden character ',' in the keys
*/
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 \
or variable name (\"%s\"), which is forbidden\n",
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.
*/
int vfc_put_probe(vfc_probes *probes, char *testName, char *varName,
double val) {
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);
// 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));
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);
}
}
// 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);
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");
if (fp == NULL) {
fprintf(stderr,
"Error [verificarlo]: impossible to open the CSV file to save your \
probes (\"%s\")\n",
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);
}
}
fclose(fp);
vfc_free_probes(probes);
return 0;
}

View File

@ -13,7 +13,7 @@
#include "Helpers.hpp"
#include "SM_Maponi.hpp"
#include "SM_Standard.hpp"
#include "vfc_probe.h"
#include <vfc_probes.h>
using namespace H5;
// #define DEBUG
@ -140,9 +140,9 @@ int test_cycle(H5File file, int cycle, std::string version,
showMatrix(res, dim, "Result");
#endif
vfc_put_probe(probes, &(zero_padded_group)[0], &("frob2_" + version)[0],
vfc_probe(probes, &(zero_padded_group)[0], &("frob2_" + version)[0],
frob2);
vfc_put_probe(probes, &(zero_padded_group)[0], &("res2_" + version)[0], res2);
vfc_probe(probes, &(zero_padded_group)[0], &("res2_" + version)[0], res2);
delete[] res, updates, u, col_update_index, slater_matrix, slater_inverse;