Skip to content

Commit 4dccfba

Browse files
committed
tests : add --list-ops and --show-coverage options
This commit adds two new command-line options to the test-backend-ops.cpp that allow users to list all available GGML operations and to show test coverage of these operations. The motivation for this is that it can be useful to quickly see which operations are currently covered by tests and which are not. Also it migth be useful when using the `support` mode.
1 parent 9961d24 commit 4dccfba

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

tests/test-backend-ops.cpp

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <memory>
3535
#include <random>
3636
#include <regex>
37+
#include <set>
3738
#include <string>
3839
#include <string_view>
3940
#include <thread>
@@ -6629,8 +6630,90 @@ static bool test_backend(ggml_backend_t backend, test_mode mode, const char * op
66296630
GGML_ABORT("fatal error");
66306631
}
66316632

6633+
static void list_all_ops() {
6634+
printf("GGML operations:\n");
6635+
std::set<std::string> all_ops;
6636+
6637+
for (int i = 1; i < GGML_OP_COUNT; i++) {
6638+
all_ops.insert(ggml_op_name((enum ggml_op)i));
6639+
}
6640+
for (int i = 0; i < GGML_UNARY_OP_COUNT; i++) {
6641+
all_ops.insert(ggml_unary_op_name((enum ggml_unary_op)i));
6642+
}
6643+
for (int i = 0; i < GGML_GLU_OP_COUNT; i++) {
6644+
all_ops.insert(ggml_glu_op_name((enum ggml_glu_op)i));
6645+
}
6646+
for (const auto & op : all_ops) {
6647+
printf(" %s\n", op.c_str());
6648+
}
6649+
printf("\nTotal: %zu operations\n", all_ops.size());
6650+
}
6651+
6652+
static void show_test_coverage() {
6653+
std::set<std::string> all_ops;
6654+
for (int i = 1; i < GGML_OP_COUNT; i++) {
6655+
all_ops.insert(ggml_op_name((enum ggml_op)i));
6656+
}
6657+
for (int i = 0; i < GGML_UNARY_OP_COUNT; i++) {
6658+
all_ops.insert(ggml_unary_op_name((enum ggml_unary_op)i));
6659+
}
6660+
for (int i = 0; i < GGML_GLU_OP_COUNT; i++) {
6661+
all_ops.insert(ggml_glu_op_name((enum ggml_glu_op)i));
6662+
}
6663+
auto test_cases = make_test_cases_eval();
6664+
std::set<std::string> tested_ops;
6665+
6666+
ggml_init_params params = {
6667+
/* .mem_size = */ ggml_tensor_overhead()*128 + ggml_graph_overhead(),
6668+
/* .mem_base = */ NULL,
6669+
/* .no_alloc = */ true,
6670+
};
6671+
6672+
for (auto & test_case : test_cases) {
6673+
ggml_context * ctx = ggml_init(params);
6674+
if (ctx) {
6675+
test_case->mode = MODE_TEST;
6676+
ggml_tensor * out = test_case->build_graph(ctx);
6677+
if (out && out->op != GGML_OP_NONE) {
6678+
if (out->op == GGML_OP_UNARY) {
6679+
tested_ops.insert(ggml_unary_op_name(ggml_get_unary_op(out)));
6680+
} else if (out->op == GGML_OP_GLU) {
6681+
tested_ops.insert(ggml_glu_op_name(ggml_get_glu_op(out)));
6682+
} else {
6683+
tested_ops.insert(ggml_op_name(out->op));
6684+
}
6685+
}
6686+
ggml_free(ctx);
6687+
}
6688+
}
6689+
std::set<std::string> covered_ops;
6690+
std::set<std::string> uncovered_ops;
6691+
for (const auto & op : all_ops) {
6692+
if (tested_ops.count(op) > 0) {
6693+
covered_ops.insert(op);
6694+
} else {
6695+
uncovered_ops.insert(op);
6696+
}
6697+
}
6698+
6699+
printf("Operations covered by tests (%zu):\n", covered_ops.size());
6700+
for (const auto & op : covered_ops) {
6701+
printf(" ✓ %s\n", op.c_str());
6702+
}
6703+
printf("\nOperations without tests (%zu):\n", uncovered_ops.size());
6704+
for (const auto & op : uncovered_ops) {
6705+
printf(" ✗ %s\n", op.c_str());
6706+
}
6707+
6708+
printf("\nCoverage Summary:\n");
6709+
printf(" Total operations: %zu\n", all_ops.size());
6710+
printf(" Tested operations: %zu\n", covered_ops.size());
6711+
printf(" Untested operations: %zu\n", uncovered_ops.size());
6712+
printf(" Coverage: %.1f%%\n", (double)covered_ops.size() / all_ops.size() * 100.0);
6713+
}
6714+
66326715
static void usage(char ** argv) {
6633-
printf("Usage: %s [mode] [-o <op,..>] [-b <backend>] [-p <params regex>] [--output <console|sql|csv>]\n", argv[0]);
6716+
printf("Usage: %s [mode] [-o <op,..>] [-b <backend>] [-p <params regex>] [--output <console|sql|csv>] [--list-ops] [--show-coverage]\n", argv[0]);
66346717
printf(" valid modes:\n");
66356718
printf(" - test (default, compare with CPU backend for correctness)\n");
66366719
printf(" - grad (compare gradients from backpropagation with method of finite differences)\n");
@@ -6639,6 +6722,8 @@ static void usage(char ** argv) {
66396722
printf(" op names for -o are as given by ggml_op_desc() (e.g. ADD, MUL_MAT, etc),\n");
66406723
printf(" optionally including the full test case string (e.g. \"ADD(type=f16,ne=[1,1,8,1],nr=[1,1,1,1],nf=1)\")\n");
66416724
printf(" --output specifies output format (default: console, options: console, sql, csv)\n");
6725+
printf(" --list-ops lists all available GGML operations\n");
6726+
printf(" --show-coverage shows test coverage\n");
66426727
}
66436728

66446729
int main(int argc, char ** argv) {
@@ -6688,6 +6773,12 @@ int main(int argc, char ** argv) {
66886773
usage(argv);
66896774
return 1;
66906775
}
6776+
} else if (strcmp(argv[i], "--list-ops") == 0) {
6777+
list_all_ops();
6778+
return 0;
6779+
} else if (strcmp(argv[i], "--show-coverage") == 0) {
6780+
show_test_coverage();
6781+
return 0;
66916782
} else {
66926783
usage(argv);
66936784
return 1;

0 commit comments

Comments
 (0)