// Step 1965: PerTaskLibrarySelector // // t1: selects nlohmann_json (0.92) over protobuf (0.60) for serialization.json // t2: selects cublas (0.99) over numpy (0.95) for compute.matrix // t3: avoidedLibraries populated correctly (sorted desc) // t4: returns empty selection when no library has score > 0 // t5: single qualified library: no avoided, justification says "only" #include "PerTaskLibrarySelector.h" #include "Sprint286IntegrationSummary.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; } void t1() { T(selects_nlohmann_over_protobuf_for_json); auto ledger = ws::Sprint286IntegrationSummary::buildSeedLedger(); ws::PerTaskLibrarySelector sel; auto r = sel.select("serialization.json", {"nlohmann_json", "protobuf"}, ledger); C(r.hasSelection(), "hasSelection"); C(r.selectedLibrary == "nlohmann_json", "nlohmann_json selected"); C(r.capabilityScore == 0.92f, "score 0.92"); C(!r.justification.empty(), "justification set"); C(r.justification.find("nlohmann_json") != std::string::npos, "justification names winner"); P(); } void t2() { T(selects_cublas_over_numpy_for_compute_matrix); auto ledger = ws::Sprint286IntegrationSummary::buildSeedLedger(); ws::PerTaskLibrarySelector sel; auto r = sel.select("compute.matrix", {"cublas", "numpy"}, ledger); C(r.selectedLibrary == "cublas", "cublas selected"); C(r.capabilityScore == 0.99f, "score 0.99"); C(!r.preferredAPIs.empty(), "preferredAPIs populated"); P(); } void t3() { T(avoided_libraries_sorted_desc); auto ledger = ws::Sprint286IntegrationSummary::buildSeedLedger(); // Add serde_json so there are 3 candidates for serialization.json ledger.set({"serde_json", "serialization.json", 0.98f}); ws::PerTaskLibrarySelector sel; auto r = sel.select("serialization.json", {"nlohmann_json", "protobuf", "serde_json"}, ledger); C(r.selectedLibrary == "serde_json", "serde_json selected (0.98)"); C(r.avoidedLibraries.size() == 2, "2 avoided"); C(r.avoidedLibraries[0].name == "nlohmann_json", "nlohmann first avoided (0.92)"); C(r.avoidedLibraries[0].score > r.avoidedLibraries[1].score, "sorted desc"); C(r.avoidedLibraries[1].name == "protobuf", "protobuf second avoided (0.60)"); P(); } void t4() { T(empty_selection_when_no_score); auto ledger = ws::Sprint286IntegrationSummary::buildSeedLedger(); ws::PerTaskLibrarySelector sel; // "cublas" has no score for "serialization.json" auto r = sel.select("serialization.json", {"cublas"}, ledger); C(!r.hasSelection(), "no selection"); C(r.selectedLibrary.empty(), "empty selectedLibrary"); C(r.justification.find("no library") != std::string::npos, "justification says no library"); P(); } void t5() { T(single_qualified_library_no_avoided); auto ledger = ws::Sprint286IntegrationSummary::buildSeedLedger(); ws::PerTaskLibrarySelector sel; auto r = sel.select("compute.parallel", {"thrust"}, ledger); C(r.selectedLibrary == "thrust", "thrust selected"); C(r.avoidedLibraries.empty(), "no avoided"); C(r.justification.find("only") != std::string::npos, "justification says only"); P(); } int main() { std::cout << "Step 1965: PerTaskLibrarySelector\n"; t1(); t2(); t3(); t4(); t5(); std::cout << "\n" << p << "/" << (p + f) << " passed\n"; return f > 0 ? 1 : 0; }