1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*
* Copyright © 2013-2020 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include "hwloc/diff.h"
#include "misc.h"
void usage(const char *callname __hwloc_attribute_unused, FILE *where)
{
fprintf(where, "Usage: hwloc-diff [options] <old.xml> <new.xml> [<output.diff.xml>]\n");
fprintf(where, "Options:\n");
fprintf(where, " --refname <name> Change the XML reference identifier to <name> in the output\n");
fprintf(where, " (default is the filename of the first topology\n");
fprintf(where, " --version Report version and exit\n");
}
int main(int argc, char *argv[])
{
hwloc_topology_t topo1, topo2;
hwloc_topology_diff_t firstdiff = NULL, diff;
unsigned long flags = HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED | HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT;
char *callname, *input1, *input2, *output, *outputname, *refname = NULL;
char *xmlbuffer;
int xmlbuflen;
unsigned i, j;
int err;
callname = argv[0];
/* skip argv[0], handle options */
argc--;
argv++;
hwloc_utils_check_api_version(callname);
if (!getenv("HWLOC_XML_VERBOSE"))
putenv((char *) "HWLOC_XML_VERBOSE=1");
while (argc && *argv[0] == '-') {
if (!strcmp (argv[0], "--refname")) {
if (argc < 2) {
usage(callname, stderr);
exit(EXIT_FAILURE);
}
refname = argv[1];
argc--;
argv++;
} else if (!strcmp (argv[0], "--version")) {
printf("%s %s\n", callname, HWLOC_VERSION);
exit(EXIT_SUCCESS);
} else if (!strcmp (argv[0], "-h") || !strcmp (argv[0], "--help")) {
usage(callname, stdout);
exit(EXIT_SUCCESS);
} else {
fprintf(stderr, "Unrecognized options: %s\n", argv[0]);
usage(callname, stderr);
exit(EXIT_FAILURE);
}
argc--;
argv++;
}
if (argc < 2) {
usage(callname, stderr);
exit(EXIT_FAILURE);
}
input1 = argv[0];
input2 = argv[1];
argc -= 2;
argv += 2;
if (argc >= 1) {
output = argv[0];
outputname = argv[0];
argc--;
argv++;
} else {
output = NULL;
outputname = (char *) "stdout";
}
hwloc_topology_init(&topo1);
hwloc_topology_set_all_types_filter(topo1, HWLOC_TYPE_FILTER_KEEP_ALL);
hwloc_topology_set_flags(topo1, flags);
err = hwloc_topology_set_xml(topo1, input1);
if (err < 0) {
fprintf(stderr, "Failed to load 1st XML topology %s\n", input1);
goto out_with_topo1;
}
err = hwloc_topology_load(topo1);
if (err < 0) {
fprintf(stderr, "Failed to load 1st topology %s\n", input1);
goto out_with_topo1;
}
hwloc_topology_init(&topo2);
hwloc_topology_set_all_types_filter(topo2, HWLOC_TYPE_FILTER_KEEP_ALL);
hwloc_topology_set_flags(topo2, flags);
err = hwloc_topology_set_xml(topo2, input2);
if (err < 0) {
fprintf(stderr, "Failed to load 2nd XML topology %s\n", input2);
goto out_with_topo2;
}
err = hwloc_topology_load(topo2);
if (err < 0) {
fprintf(stderr, "Failed to load 2nd topology %s\n", input2);
goto out_with_topo2;
}
if (!refname) {
refname = strrchr(input1, '/');
if (refname)
refname++;
else
refname = input1;
}
err = hwloc_topology_diff_build(topo1, topo2, 0, &firstdiff);
if (err < 0) {
fprintf(stderr, "Failed to compute the diff (%s)\n", strerror(errno));
goto out_with_topo2;
}
diff = firstdiff;
i = 0, j = 0;
while (diff) {
i++;
if (diff->generic.type == HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX)
j++;
diff = diff->generic.next;
}
if (!i) {
fprintf(stderr, "Found no difference, exporting empty topology diff to %s\n", outputname);
} else if (!j) {
fprintf(stderr, "Found %u differences, exporting to %s\n", i, outputname);
} else {
fprintf(stderr, "Found %u differences, including %u too complex ones.\n", i, j);
fprintf(stderr, "Cannot export differences to %s\n", outputname);
}
if (!j) {
if (output) {
err = hwloc_topology_diff_export_xml(firstdiff, refname, output);
} else {
err = hwloc_topology_diff_export_xmlbuffer(firstdiff, refname, &xmlbuffer, &xmlbuflen);
if (!err) {
printf("%s\n", xmlbuffer);
hwloc_free_xmlbuffer(topo1, xmlbuffer);
}
}
if (err < 0)
fprintf(stderr, "Failed to export topology diff %s\n", output);
}
hwloc_topology_diff_destroy(firstdiff);
hwloc_topology_destroy(topo2);
hwloc_topology_destroy(topo1);
if (j)
exit(EXIT_FAILURE);
else
exit(EXIT_SUCCESS);
out_with_topo2:
hwloc_topology_destroy(topo2);
out_with_topo1:
hwloc_topology_destroy(topo1);
exit(EXIT_FAILURE);
}
|