/* Unit tests for the host-side rules of host.c that need no device (5 October 2026): the duplicate-platform fold * (markDuplicates, driverNumber). host.c is included with its main renamed. Build and run: ./test-host.sh */ #define main host_main #include "host.c" #undef main static int failures = 0; #define CHECK(cond, what) do { if (!(cond)) { printf("FAIL: %s (line %d)\n", what, __LINE__); ++failures; } else printf("ok: %s\n", what); } while (0) static DeviceInfo dev(const char* platform, const char* version, const char* name, const char* vendor, const char* driver, cl_ulong mem, cl_uint cus) { DeviceInfo d; memset(&d, 0, sizeof(d)); strncpy(d.platformName, platform, 255); strncpy(d.platformVersion, version, 255); strncpy(d.name, name, 255); strncpy(d.vendor, vendor, 255); strncpy(d.driver, driver, 255); d.globalMem = mem; d.computeUnits = cus; d.type = CL_DEVICE_TYPE_GPU; d.dupOf = -1; return d; } int main(void) { const char* AMD = "AMD Accelerated Parallel Processing"; const char* V_NEW = "OpenCL 2.1 AMD-APP (3683.0)", *V_OLD = "OpenCL 2.1 AMD-APP (3652.0)", *V_OLDER = "OpenCL 2.1 AMD-APP (3600.0)"; const char* AMDV = "Advanced Micro Devices, Inc."; CHECK(driverNumber("3683.0 (PAL,LC)") == 3683.0, "driverNumber reads the AMD string"); CHECK(driverNumber("617.14") > 617.1 && driverNumber("617.14") < 617.2, "driverNumber reads the NVIDIA string"); CHECK(driverNumber("") == 0.0, "driverNumber of an empty string is 0"); { /* PC 1 on 5 October 2026: the new platform first, the old one second, NVIDIA last */ DeviceInfo l[5]; l[0] = dev(AMD, V_NEW, "gfx1036", AMDV, "3683.0 (PAL,LC)", 59589ull << 20, 1); l[1] = dev(AMD, V_NEW, "gfx1201", AMDV, "3683.0 (PAL,LC)", 16304ull << 20, 32); l[2] = dev(AMD, V_OLD, "gfx1036", AMDV, "3652.0 (PAL,LC)", 59589ull << 20, 1); l[3] = dev(AMD, V_OLD, "gfx1201", AMDV, "3652.0 (PAL,LC)", 16304ull << 20, 32); l[4] = dev("NVIDIA CUDA", "OpenCL 3.0 CUDA 13.4.96", "NVIDIA GeForce RTX 5090", "NVIDIA Corporation", "617.14", 32579ull << 20, 170); CHECK(markDuplicates(l, 5) == 2, "PC 1: two duplicates marked"); CHECK(l[0].dupOf == -1 && l[1].dupOf == -1 && l[4].dupOf == -1, "PC 1: the new platform's cards and the NVIDIA card stay"); CHECK(l[2].dupOf == 0 && l[3].dupOf == 1, "PC 1: the old platform's entries point at the new ones"); } { /* the old platform enumerated first: the newer entry must still be the one kept */ DeviceInfo l[2]; l[0] = dev(AMD, V_OLD, "gfx1201", AMDV, "3652.0 (PAL,LC)", 16304ull << 20, 32); l[1] = dev(AMD, V_NEW, "gfx1201", AMDV, "3683.0 (PAL,LC)", 16304ull << 20, 32); CHECK(markDuplicates(l, 2) == 1, "old first: one duplicate"); CHECK(l[0].dupOf == 1 && l[1].dupOf == -1, "old first: the older entry is the duplicate"); } { /* two real cards of one model on ONE platform: never folded */ DeviceInfo l[2]; l[0] = dev(AMD, V_NEW, "gfx1201", AMDV, "3683.0 (PAL,LC)", 16304ull << 20, 32); l[1] = dev(AMD, V_NEW, "gfx1201", AMDV, "3683.0 (PAL,LC)", 16304ull << 20, 32); CHECK(markDuplicates(l, 2) == 0 && l[0].dupOf == -1 && l[1].dupOf == -1, "two identical cards on one platform stay two cards"); } { /* three registrations of one card: one stays */ DeviceInfo l[3]; l[0] = dev(AMD, V_OLD, "gfx1201", AMDV, "3652.0 (PAL,LC)", 16304ull << 20, 32); l[1] = dev(AMD, V_OLDER, "gfx1201", AMDV, "3600.0 (PAL,LC)", 16304ull << 20, 32); l[2] = dev(AMD, V_NEW, "gfx1201", AMDV, "3683.0 (PAL,LC)", 16304ull << 20, 32); CHECK(markDuplicates(l, 3) == 2, "three platforms: two duplicates"); CHECK(l[2].dupOf == -1 && l[0].dupOf == 2 && l[1].dupOf == 2, "three platforms: the newest stays and both duplicates point at it"); } { /* a different card with the same name but other memory (an 8 GB and a 16 GB model) on two platforms: not folded */ DeviceInfo l[2]; l[0] = dev(AMD, V_NEW, "gfx1201", AMDV, "3683.0 (PAL,LC)", 16304ull << 20, 32); l[1] = dev(AMD, V_OLD, "gfx1201", AMDV, "3652.0 (PAL,LC)", 8000ull << 20, 32); CHECK(markDuplicates(l, 2) == 0, "different memory sizes are different cards"); } printf("%s: %d failure(s)\n", failures ? "FAIL" : "PASS", failures); return failures ? 1 : 0; }