mirror of
https://github.com/TREX-CoE/Sherman-Morrison.git
synced 2024-11-03 20:54:08 +01:00
7e42a000c4
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.
184 lines
5.2 KiB
C++
184 lines
5.2 KiB
C++
// This files is almost the same as test_h5.cpp, with the difference that it
|
|
// dumps Verificarlo probes for vfc_ci integration, and that it reads a list of
|
|
// cycles in a CSV file, instead of accepting a start and an end cycle (which
|
|
// makes it easier to select the exact cycles we are interested in with vfc_ci).
|
|
|
|
#include <hdf5/serial/H5Cpp.h>
|
|
#include <hdf5/serial/hdf5.h>
|
|
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
#include "Helpers.hpp"
|
|
#include "SM_Maponi.hpp"
|
|
#include "SM_Standard.hpp"
|
|
#include <vfc_probes.h>
|
|
|
|
using namespace H5;
|
|
// #define DEBUG
|
|
|
|
const H5std_string FILE_NAME("datasets/ci_dataset.hdf5");
|
|
|
|
void read_int(H5File file, std::string key, unsigned int *data) {
|
|
DataSet ds = file.openDataSet(key);
|
|
ds.read(data, PredType::STD_U32LE);
|
|
ds.close();
|
|
}
|
|
|
|
void read_double(H5File file, std::string key, double *data) {
|
|
DataSet ds = file.openDataSet(key);
|
|
ds.read(data, PredType::IEEE_F64LE);
|
|
ds.close();
|
|
}
|
|
|
|
/* Return a vector containing all cycles to execute by reading a data file */
|
|
std::vector<int> get_cycles_list(std::string path) {
|
|
std::ifstream file_stream(path);
|
|
std::stringstream string_stream;
|
|
string_stream << file_stream.rdbuf();
|
|
|
|
std::string cycle_str;
|
|
std::vector<int> cycles_list = {};
|
|
|
|
while (string_stream >> cycle_str) {
|
|
cycles_list.push_back(std::stoi(cycle_str));
|
|
}
|
|
|
|
return cycles_list;
|
|
}
|
|
|
|
int test_cycle(H5File file, int cycle, std::string version,
|
|
vfc_probes *probes) {
|
|
|
|
/* Read the data */
|
|
|
|
std::string group = "cycle_" + std::to_string(cycle);
|
|
|
|
// This will result in the same string as group but with the cycle number
|
|
// being zero-padded. This is used when calling vfc_put_probe later on.
|
|
std::string zero_padded_group = std::to_string(cycle);
|
|
zero_padded_group = "cycle_" +
|
|
std::string(5 - zero_padded_group.length(), '0') +
|
|
zero_padded_group;
|
|
|
|
try {
|
|
file.openGroup(group);
|
|
} catch (H5::Exception &e) {
|
|
std::cerr << "group " << group << "not found" << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
unsigned int dim, nupdates, col, i, j;
|
|
read_int(file, group + "/slater_matrix_dim", &dim);
|
|
read_int(file, group + "/nupdates", &nupdates);
|
|
|
|
double *slater_matrix = new double[dim * dim];
|
|
read_double(file, group + "/slater_matrix", slater_matrix);
|
|
|
|
double *slater_inverse = new double[dim * dim];
|
|
read_double(file, group + "/slater_inverse", slater_inverse);
|
|
// slater_inverse = transpose(slater_inverse, dim);
|
|
|
|
unsigned int *col_update_index = new unsigned int[nupdates];
|
|
read_int(file, group + "/col_update_index", col_update_index);
|
|
|
|
double *updates = new double[nupdates * dim];
|
|
read_double(file, group + "/updates", updates);
|
|
|
|
double *u = new double[nupdates * dim];
|
|
|
|
/* Test */
|
|
#ifdef DEBUG2
|
|
showMatrix(slater_matrix, dim, "OLD Slater");
|
|
#endif
|
|
|
|
#ifdef DEBUG2
|
|
showMatrix(slater_inverse, dim, "OLD Inverse");
|
|
#endif
|
|
|
|
for (j = 0; j < nupdates; j++) {
|
|
for (i = 0; i < dim; i++) {
|
|
col = col_update_index[j];
|
|
u[i + j * dim] =
|
|
updates[i + j * dim] - slater_matrix[i * dim + (col - 1)];
|
|
slater_matrix[i * dim + (col - 1)] = updates[i + j * dim];
|
|
}
|
|
}
|
|
|
|
if (version == "maponia3") {
|
|
MaponiA3(slater_inverse, dim, nupdates, u, col_update_index);
|
|
} else if (version == "sm1") {
|
|
SM1(slater_inverse, dim, nupdates, u, col_update_index);
|
|
} else if (version == "sm2") {
|
|
SM2(slater_inverse, dim, nupdates, u, col_update_index);
|
|
} else if (version == "sm3") {
|
|
SM3(slater_inverse, dim, nupdates, u, col_update_index);
|
|
} else if (version == "sm4") {
|
|
SM4(slater_inverse, dim, nupdates, u, col_update_index);
|
|
} else {
|
|
std::cerr << "Unknown version " << version << std::endl;
|
|
exit(1);
|
|
}
|
|
|
|
#ifdef DEBUG2
|
|
showMatrix(slater_matrix, dim, "NEW Slater");
|
|
#endif
|
|
|
|
#ifdef DEBUG2
|
|
showMatrix(slater_inverse, dim, "NEW Inverse");
|
|
#endif
|
|
|
|
double *res = new double[dim * dim]{0};
|
|
matMul(slater_matrix, slater_inverse, res, dim);
|
|
bool ok = is_identity(res, dim, 1e-3);
|
|
|
|
double res2 = residual2(res, dim);
|
|
double frob2 = norm_frobenius2(res, dim);
|
|
|
|
#ifdef DEBUG2
|
|
showMatrix(res, dim, "Result");
|
|
#endif
|
|
|
|
vfc_probe(probes, &(zero_padded_group)[0], &("frob2_" + version)[0],
|
|
frob2);
|
|
vfc_probe(probes, &(zero_padded_group)[0], &("res2_" + version)[0], res2);
|
|
|
|
delete[] res, updates, u, col_update_index, slater_matrix, slater_inverse;
|
|
|
|
return ok;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc != 2) {
|
|
std::cerr << "Execute from within '/'" << std::endl;
|
|
std::cerr << "usage: vfc_test_h5 <path to cycles file>" << std::endl;
|
|
return 1;
|
|
}
|
|
std::vector<int> cycles_list = get_cycles_list(argv[1]);
|
|
H5File file(FILE_NAME, H5F_ACC_RDONLY);
|
|
|
|
vfc_probes probes = vfc_init_probes();
|
|
probes = vfc_init_probes();
|
|
|
|
std::vector<std::string> versions = {"maponia3", "sm1", "sm2", "sm3", "sm4"};
|
|
|
|
bool ok;
|
|
for (int i = 0; i < cycles_list.size(); i++) {
|
|
|
|
for (const auto &version : versions) {
|
|
|
|
ok = test_cycle(file, cycles_list[i], version, &probes);
|
|
if (ok) {
|
|
std::cout << "ok -- cycle " << std::to_string(i) << std::endl;
|
|
} else {
|
|
std::cerr << "failed -- cycle " << std::to_string(i) << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
vfc_dump_probes(&probes);
|
|
|
|
return ok;
|
|
}
|