// Step 1971: LibrarySymbolAdvisor // // t1: advise returns symbols sorted by functionName // t2: advise returns empty for unknown pair // t3: topSymbol returns first alphabetically // t4: multiple symbols correctly ordered // t5: advisee scoped to exact (library, domain) pair #include "LibrarySymbolAdvisor.h" #include "LibrarySymbolCatalog.h" #include namespace ws = whetstone; static int p = 0, f = 0; #define T(n) { std::cout << " " << #n << "... "; } #define P() { std::cout << "PASS\n"; ++p; } #define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } #define C(c, m) if (!(c)) { F(m); return; } static ws::LibrarySymbolCatalog makeCatalog() { ws::LibrarySymbolCatalog cat; cat.add({"cublas", "cublasSgemm", "sig_s", "compute.matrix", "", {}}); cat.add({"cublas", "cublasDgemm", "sig_d", "compute.matrix", "", {}}); cat.add({"nlohmann_json", "json::parse", "sig_p", "serialization.json", "", {}}); cat.add({"nlohmann_json", "json::dump", "sig_du","serialization.json", "", {}}); return cat; } void t1() { T(advise_sorted_by_functionName); auto cat = makeCatalog(); ws::LibrarySymbolAdvisor adv; auto syms = adv.advise("cublas", "compute.matrix", cat); C(syms.size() == 2, "2 cublas symbols"); // cublasDgemm < cublasSgemm alphabetically C(syms[0].functionName == "cublasDgemm", "Dgemm first (D < S)"); C(syms[1].functionName == "cublasSgemm", "Sgemm second"); P(); } void t2() { T(advise_empty_for_unknown_pair); auto cat = makeCatalog(); ws::LibrarySymbolAdvisor adv; auto syms = adv.advise("unknown_lib", "compute.matrix", cat); C(syms.empty(), "empty for unknown library"); auto syms2 = adv.advise("cublas", "serialization.json", cat); C(syms2.empty(), "empty for domain cublas has no symbols in"); P(); } void t3() { T(topSymbol_returns_first_alphabetically); auto cat = makeCatalog(); ws::LibrarySymbolAdvisor adv; auto top = adv.topSymbol("nlohmann_json", "serialization.json", cat); C(top.has_value(), "has top symbol"); // json::dump < json::parse alphabetically C(top->functionName == "json::dump", "json::dump is top (d < p)"); auto none = adv.topSymbol("missing", "missing", cat); C(!none.has_value(), "nullopt for missing pair"); P(); } void t4() { T(nlohmann_symbols_correct_order); auto cat = makeCatalog(); ws::LibrarySymbolAdvisor adv; auto syms = adv.advise("nlohmann_json", "serialization.json", cat); C(syms.size() == 2, "2 nlohmann symbols"); C(syms[0].functionName == "json::dump", "dump first (d < p)"); C(syms[1].functionName == "json::parse", "parse second"); // Both symbols in serialization.json (parse IS present) bool hasParse = false; for (const auto& s : syms) if (s.functionName == "json::parse") hasParse = true; C(hasParse, "json::parse present in results"); P(); } void t5() { T(advise_scoped_to_exact_pair); auto cat = makeCatalog(); ws::LibrarySymbolAdvisor adv; // cublas symbols only in compute.matrix, not compute.parallel auto par = adv.advise("cublas", "compute.parallel", cat); C(par.empty(), "no cublas/compute.parallel symbols"); // nlohmann symbols only in serialization.json, not serialization.binary auto bin = adv.advise("nlohmann_json", "serialization.binary", cat); C(bin.empty(), "no nlohmann/serialization.binary symbols"); P(); } int main() { std::cout << "Step 1971: LibrarySymbolAdvisor\n"; t1(); t2(); t3(); t4(); t5(); std::cout << "\n" << p << "/" << (p + f) << " passed\n"; return f > 0 ? 1 : 0; }