1/* @ajax/cuda-driver-fake: a simulated CUDA device behind @ajax/cuda-driver's
2 * table, so everything above the driver -- contexts, green contexts, module
3 * loads, launch shapes, streams, the mailbox registration, the blink, MPS
4 * workers -- is testable on a machine without a GPU.
5 *
6 * Device memory is host memory (a device pointer is the host address), so a
7 * launched kernel can be a C function that plays the program's node loop on
8 * CPU threads against the real mailbox. A "cubin" is text:
9 * "FAKECUBIN entry=mesh_main regs=40 local=0 maxthreads=1024 shared=0 rt_abi=6"
10 * (any key may be left out). Not thread-safe across tests: install once. */
11#ifndef MESH_CUDA_FAKE_H
12#define MESH_CUDA_FAKE_H
1314#include "mesh/cuda_driver.h"
1516#include <stdbool.h>
17#include <stdint.h>
1819/* Runs one launch: nodes blocks of threads threads, the kernel's parameters
20 * (a mesh program: params[0] -> u64 mailbox device address, params[1] -> u32
21 * slot, copied). Called on a thread of its own; the stream is busy until it returns. */
22typedef void (*mesh_fake_kernel_fn)(const char *entry, uint64_t mailbox, uint32_t slot, uint32_t nodes, uint32_t threads,
23 void *user);
2425typedef struct {
26 const char *name; /* "Fake GB10" */
27 int cc_major, cc_minor; /* 12, 1 */
28 int sms; /* 48 */
29 int blocks_per_sm; /* 24 */
30 int host_atomics; /* 1 */
31 int max_threads; /* 1024 */
32 int regs_per_block; /* 65536 */
33 int max_shared_optin; /* 101376 */
34 int loading_mode; /* CU_MODULE_EAGER_LOADING */
35 int blocks_per_sm_occupancy; /* what cuOccupancyMaxActiveBlocksPerMultiprocessor answers; 0: 16 */
36 mesh_fake_kernel_fn run;
37 void *user;
38} mesh_fake_cuda_cfg;
3940/* What the fake saw. */
41typedef struct {
42 int inits, primary_ctx, green_ctx, green_sms;
43 int modules_loaded, modules_unloaded, modules_live;
44 int streams_created, streams_destroyed;
45 int launches, running;
46 uint32_t last_grid, last_block, last_smem;
47 uint64_t last_mailbox;
48 uint32_t last_slot;
49 int host_registered;
50 int allocs, frees, memsets;
51 size_t stack_limit;
52 int opted_in_smem; /* MAX_DYNAMIC_SHARED_SIZE_BYTES set */
53} mesh_fake_cuda_stats;
5455/* Installs the fake as the driver table (cfg fields left 0 take the defaults above). */
56void mesh_fake_cuda_install(const mesh_fake_cuda_cfg *cfg);
57mesh_fake_cuda_stats mesh_fake_cuda_stats_now(void);
58/* The next call to `call` (e.g. "cuModuleLoadData") returns code, once. */
59void mesh_fake_cuda_fail_next(const char *call, CUresult code);
60/* Waits (at most ms) until no launch is running; false if one still is. */
61bool mesh_fake_cuda_idle(unsigned ms);
6263#endif