diff --git a/Makefile.verificarlo b/Makefile.verificarlo index b093482..bd0cc22 100644 --- a/Makefile.verificarlo +++ b/Makefile.verificarlo @@ -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 \ diff --git a/include/vfc_hashmap.h b/include/vfc_hashmap.h deleted file mode 100644 index a4e5216..0000000 --- a/include/vfc_hashmap.h +++ /dev/null @@ -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 - -#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)); -} diff --git a/include/vfc_probe.h b/include/vfc_probe.h deleted file mode 100644 index 8d91b19..0000000 --- a/include/vfc_probe.h +++ /dev/null @@ -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 -#include -#include - -#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; -} diff --git a/tests/vfc_test_h5.cpp b/tests/vfc_test_h5.cpp index e02355c..26827db 100644 --- a/tests/vfc_test_h5.cpp +++ b/tests/vfc_test_h5.cpp @@ -13,7 +13,7 @@ #include "Helpers.hpp" #include "SM_Maponi.hpp" #include "SM_Standard.hpp" -#include "vfc_probe.h" +#include 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;