3434#include < memory>
3535#include < random>
3636#include < regex>
37+ #include < set>
3738#include < string>
3839#include < string_view>
3940#include < thread>
@@ -6741,8 +6742,90 @@ static bool test_backend(ggml_backend_t backend, test_mode mode, const char * op
67416742 GGML_ABORT (" fatal error" );
67426743}
67436744
6745+ static void list_all_ops () {
6746+ printf (" GGML operations:\n " );
6747+ std::set<std::string> all_ops;
6748+
6749+ for (int i = 1 ; i < GGML_OP_COUNT; i++) {
6750+ all_ops.insert (ggml_op_name ((enum ggml_op)i));
6751+ }
6752+ for (int i = 0 ; i < GGML_UNARY_OP_COUNT; i++) {
6753+ all_ops.insert (ggml_unary_op_name ((enum ggml_unary_op)i));
6754+ }
6755+ for (int i = 0 ; i < GGML_GLU_OP_COUNT; i++) {
6756+ all_ops.insert (ggml_glu_op_name ((enum ggml_glu_op)i));
6757+ }
6758+ for (const auto & op : all_ops) {
6759+ printf (" %s\n " , op.c_str ());
6760+ }
6761+ printf (" \n Total: %zu operations\n " , all_ops.size ());
6762+ }
6763+
6764+ static void show_test_coverage () {
6765+ std::set<std::string> all_ops;
6766+ for (int i = 1 ; i < GGML_OP_COUNT; i++) {
6767+ all_ops.insert (ggml_op_name ((enum ggml_op)i));
6768+ }
6769+ for (int i = 0 ; i < GGML_UNARY_OP_COUNT; i++) {
6770+ all_ops.insert (ggml_unary_op_name ((enum ggml_unary_op)i));
6771+ }
6772+ for (int i = 0 ; i < GGML_GLU_OP_COUNT; i++) {
6773+ all_ops.insert (ggml_glu_op_name ((enum ggml_glu_op)i));
6774+ }
6775+ auto test_cases = make_test_cases_eval ();
6776+ std::set<std::string> tested_ops;
6777+
6778+ ggml_init_params params = {
6779+ /* .mem_size = */ ggml_tensor_overhead ()*128 + ggml_graph_overhead (),
6780+ /* .mem_base = */ NULL ,
6781+ /* .no_alloc = */ true ,
6782+ };
6783+
6784+ for (auto & test_case : test_cases) {
6785+ ggml_context * ctx = ggml_init (params);
6786+ if (ctx) {
6787+ test_case->mode = MODE_TEST;
6788+ ggml_tensor * out = test_case->build_graph (ctx);
6789+ if (out && out->op != GGML_OP_NONE) {
6790+ if (out->op == GGML_OP_UNARY) {
6791+ tested_ops.insert (ggml_unary_op_name (ggml_get_unary_op (out)));
6792+ } else if (out->op == GGML_OP_GLU) {
6793+ tested_ops.insert (ggml_glu_op_name (ggml_get_glu_op (out)));
6794+ } else {
6795+ tested_ops.insert (ggml_op_name (out->op ));
6796+ }
6797+ }
6798+ ggml_free (ctx);
6799+ }
6800+ }
6801+ std::set<std::string> covered_ops;
6802+ std::set<std::string> uncovered_ops;
6803+ for (const auto & op : all_ops) {
6804+ if (tested_ops.count (op) > 0 ) {
6805+ covered_ops.insert (op);
6806+ } else {
6807+ uncovered_ops.insert (op);
6808+ }
6809+ }
6810+
6811+ printf (" Operations covered by tests (%zu):\n " , covered_ops.size ());
6812+ for (const auto & op : covered_ops) {
6813+ printf (" ✓ %s\n " , op.c_str ());
6814+ }
6815+ printf (" \n Operations without tests (%zu):\n " , uncovered_ops.size ());
6816+ for (const auto & op : uncovered_ops) {
6817+ printf (" ✗ %s\n " , op.c_str ());
6818+ }
6819+
6820+ printf (" \n Coverage Summary:\n " );
6821+ printf (" Total operations: %zu\n " , all_ops.size ());
6822+ printf (" Tested operations: %zu\n " , covered_ops.size ());
6823+ printf (" Untested operations: %zu\n " , uncovered_ops.size ());
6824+ printf (" Coverage: %.1f%%\n " , (double )covered_ops.size () / all_ops.size () * 100.0 );
6825+ }
6826+
67446827static void usage (char ** argv) {
6745- printf (" Usage: %s [mode] [-o <op,..>] [-b <backend>] [-p <params regex>] [--output <console|sql|csv>]\n " , argv[0 ]);
6828+ printf (" Usage: %s [mode] [-o <op,..>] [-b <backend>] [-p <params regex>] [--output <console|sql|csv>] [--list-ops] [--show-coverage] \n " , argv[0 ]);
67466829 printf (" valid modes:\n " );
67476830 printf (" - test (default, compare with CPU backend for correctness)\n " );
67486831 printf (" - grad (compare gradients from backpropagation with method of finite differences)\n " );
@@ -6751,6 +6834,8 @@ static void usage(char ** argv) {
67516834 printf (" op names for -o are as given by ggml_op_desc() (e.g. ADD, MUL_MAT, etc),\n " );
67526835 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 " );
67536836 printf (" --output specifies output format (default: console, options: console, sql, csv)\n " );
6837+ printf (" --list-ops lists all available GGML operations\n " );
6838+ printf (" --show-coverage shows test coverage\n " );
67546839}
67556840
67566841int main (int argc, char ** argv) {
@@ -6800,6 +6885,12 @@ int main(int argc, char ** argv) {
68006885 usage (argv);
68016886 return 1 ;
68026887 }
6888+ } else if (strcmp (argv[i], " --list-ops" ) == 0 ) {
6889+ list_all_ops ();
6890+ return 0 ;
6891+ } else if (strcmp (argv[i], " --show-coverage" ) == 0 ) {
6892+ show_test_coverage ();
6893+ return 0 ;
68036894 } else {
68046895 usage (argv);
68056896 return 1 ;
0 commit comments