infra/cloud-devnet: hcloud (doctl variant) create, builder-VM provision from a git-archive source tarball, systemd units for igneumd --devnet-suffix with a sparse --addpeer mesh and a CPU trickle miner per node, stdlib wRPC client, experiments (latency, partition, hop, collect, observer hookup), README with the command sequence and the Hetzner API prices of 3 Oct 2026. infra/gpu-bench: RunPod image recipes (CUDA 12.8, ROCm), bundle, run.sh (vectors gate, 10-min raw, sweep, inline shortcut ratio, nvcc/NVRTC/OpenCL recompile timings, results row, intake upload), bench-log template. infra/seed-nodes: create-seed (persistent IPv4, firewall), provision on the VM, health check, addPeer from the Mac over grpcurl, seeds.txt; igneum-seed-1 created at 188.245.5.161 (Hetzner cx23, fsn1). docs/plans/cloud-devnet.md and docs/plans/seed-nodes.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
60 lines
3.6 KiB
C
60 lines
3.6 KiB
C
/* Times clBuildProgram of a pack's kernel.cl N times on the first GPU device: the OpenCL half of the hourly-recompile
|
|
* figure (ledger M11). Build options mirror proto-opencl/host.c for the local-memory exchange path
|
|
* (-cl-std=CL1.2 -D IGNEUM_GROUP=32 -D IGNEUM_EXCHANGE=0).
|
|
* cc -std=c99 -O2 -o clbuild-time clbuild-time.c -lOpenCL
|
|
* ./clbuild-time <kernel.cl> [iterations=3] [extra build options]
|
|
* Prints one line per iteration and "median <ms>". */
|
|
#define CL_TARGET_OPENCL_VERSION 120
|
|
#include <CL/cl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
static double ms(void) { struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); return t.tv_sec * 1000.0 + t.tv_nsec / 1e6; }
|
|
static int cmp(const void* a, const void* b) { double x = *(const double*)a, y = *(const double*)b; return (x > y) - (x < y); }
|
|
|
|
int main(int argc, char** argv) {
|
|
if (argc < 2) { fprintf(stderr, "usage: clbuild-time <kernel.cl> [iterations] [extra options]\n"); return 2; }
|
|
int iters = argc > 2 ? atoi(argv[2]) : 3;
|
|
FILE* f = fopen(argv[1], "rb"); if (!f) { perror(argv[1]); return 2; }
|
|
fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET);
|
|
char* src = malloc(n + 1); if (fread(src, 1, n, f) != (size_t)n) { fprintf(stderr, "short read\n"); return 2; } src[n] = 0; fclose(f);
|
|
|
|
cl_uint np = 0; clGetPlatformIDs(0, NULL, &np); if (!np) { fprintf(stderr, "no OpenCL platform\n"); return 2; }
|
|
cl_platform_id* ps = malloc(np * sizeof *ps); clGetPlatformIDs(np, ps, NULL);
|
|
cl_device_id dev = NULL; char name[256] = "?", drv[128] = "?";
|
|
for (cl_uint i = 0; i < np && !dev; ++i) {
|
|
cl_uint nd = 0; if (clGetDeviceIDs(ps[i], CL_DEVICE_TYPE_GPU, 0, NULL, &nd) != CL_SUCCESS || !nd) continue;
|
|
clGetDeviceIDs(ps[i], CL_DEVICE_TYPE_GPU, 1, &dev, NULL);
|
|
}
|
|
if (!dev) { fprintf(stderr, "no OpenCL GPU device\n"); return 2; }
|
|
clGetDeviceInfo(dev, CL_DEVICE_NAME, sizeof name, name, NULL); clGetDeviceInfo(dev, CL_DRIVER_VERSION, sizeof drv, drv, NULL);
|
|
cl_int err; cl_context ctx = clCreateContext(NULL, 1, &dev, NULL, NULL, &err); if (err != CL_SUCCESS) { fprintf(stderr, "clCreateContext %d\n", err); return 2; }
|
|
char opts[1024]; snprintf(opts, sizeof opts, "-cl-std=CL1.2 -D IGNEUM_GROUP=32 -D IGNEUM_EXCHANGE=0 %s", argc > 3 ? argv[3] : "");
|
|
printf("device %s, driver %s, options \"%s\", source %ld bytes\n", name, drv, opts, n);
|
|
|
|
double* times = malloc(iters * sizeof *times);
|
|
for (int i = 0; i < iters; ++i) {
|
|
double t0 = ms();
|
|
const char* s = src; size_t len = (size_t)n;
|
|
cl_program prog = clCreateProgramWithSource(ctx, 1, &s, &len, &err);
|
|
if (err != CL_SUCCESS) { fprintf(stderr, "clCreateProgramWithSource %d\n", err); return 1; }
|
|
err = clBuildProgram(prog, 1, &dev, opts, NULL, NULL);
|
|
double t1 = ms();
|
|
if (err != CL_SUCCESS) {
|
|
size_t ls = 0; clGetProgramBuildInfo(prog, dev, CL_PROGRAM_BUILD_LOG, 0, NULL, &ls);
|
|
char* log = malloc(ls + 1); clGetProgramBuildInfo(prog, dev, CL_PROGRAM_BUILD_LOG, ls, log, NULL); log[ls] = 0;
|
|
fprintf(stderr, "build failed (%d):\n%s\n", err, log); return 1;
|
|
}
|
|
cl_kernel k = clCreateKernel(prog, "igneum_hash", &err);
|
|
if (err != CL_SUCCESS) fprintf(stderr, "igneum_hash not found (%d)\n", err); else clReleaseKernel(k);
|
|
clReleaseProgram(prog);
|
|
times[i] = t1 - t0;
|
|
printf("iteration %d: build %.1f ms\n", i + 1, times[i]);
|
|
}
|
|
qsort(times, iters, sizeof *times, cmp);
|
|
printf("median %.1f ms (clBuildProgram, %d iterations)\n", times[iters / 2], iters);
|
|
clReleaseContext(ctx);
|
|
return 0;
|
|
}
|