Quazim0t0's picture
Old-hardware training through emulated GPU logic
309b968 verified
Raw
History Blame Contribute Delete
1.94 kB
"""Per-node agent (CLI: `daisychain-agent`). Serves health/resources/status so
the dashboard can scan this machine. Pure stdlib."""
import json
import os
import socket
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
try:
from daisychain.cluster import survey_node
except Exception:
def survey_node(cpu_fraction=0.9):
cores = int(os.environ.get("DAISY_CORES", os.cpu_count() or 1))
return {"host": socket.gethostname(), "cores": cores,
"threads": max(1, int(cores * cpu_fraction)),
"ram_gb": None, "device": "cpu", "gpu": None, "capacity": cores}
RANK = int(os.environ.get("RANK", "0"))
STATUS_FILE = os.environ.get("DAISY_STATUS_FILE", "status.json")
PORT = int(os.environ.get("DAISY_AGENT_PORT", "8900"))
def _status():
try:
with open(STATUS_FILE) as f:
return json.load(f)
except Exception:
return {}
class Handler(BaseHTTPRequestHandler):
def _send(self, obj, code=200):
body = json.dumps(obj).encode()
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def do_GET(self):
if self.path.startswith("/health"):
self._send({"ok": True, "rank": RANK, "host": socket.gethostname()})
elif self.path.startswith("/resources"):
r = survey_node(); r["rank"] = RANK; self._send(r)
elif self.path.startswith("/status"):
self._send(_status())
else:
self._send({"error": "not found"}, 404)
def log_message(self, *a):
pass
def main():
print(f"[agent] rank {RANK} on :{PORT}", flush=True)
ThreadingHTTPServer(("0.0.0.0", PORT), Handler).serve_forever()
if __name__ == "__main__":
main()