From 5d2722de9290472bb8fbd120d1ec506f7765e209 Mon Sep 17 00:00:00 2001 From: Siho Shin Date: Sat, 27 Jun 2026 08:59:14 +0900 Subject: asdf --- dma/.gitignore | 4 + dma/Makefile | 38 ++ dma/analyze_bw.py | 345 +++++++++++++ dma/analyze_time.py | 332 ++++++++++++ dma/bw_VANILLA.csv | 1348 ++++++++++++++++++++++++++++++++++++++++++++++++ dma/bw_all.CSV | 4 + dma/combine.py | 169 ++++++ dma/doca_dma_host_recv | Bin 0 -> 30544 bytes dma/host_recv.c | 251 +++++++++ dma/run.sh | 219 ++++++++ dma/sum.sh | 22 + dma/times_VANILLA.csv | 1348 ++++++++++++++++++++++++++++++++++++++++++++++++ dma/times_all.CSV | 1348 ++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 5428 insertions(+) create mode 100644 dma/.gitignore create mode 100644 dma/Makefile create mode 100755 dma/analyze_bw.py create mode 100755 dma/analyze_time.py create mode 100644 dma/bw_VANILLA.csv create mode 100644 dma/bw_all.CSV create mode 100755 dma/combine.py create mode 100755 dma/doca_dma_host_recv create mode 100644 dma/host_recv.c create mode 100755 dma/run.sh create mode 100755 dma/sum.sh create mode 100644 dma/times_VANILLA.csv create mode 100644 dma/times_all.CSV (limited to 'dma') diff --git a/dma/.gitignore b/dma/.gitignore new file mode 100644 index 0000000..5d94054 --- /dev/null +++ b/dma/.gitignore @@ -0,0 +1,4 @@ +bins/ +logs/ +summary/ +*.png diff --git a/dma/Makefile b/dma/Makefile new file mode 100644 index 0000000..7400791 --- /dev/null +++ b/dma/Makefile @@ -0,0 +1,38 @@ +CC ?= gcc + +TARGET := doca_dma_host_recv +SRCS := host_recv.c + +CFLAGS += -O2 -g -Wall -Wextra -std=gnu11 +CFLAGS += -Wno-deprecated-declarations +CFLAGS += -DALLOW_EXPERIMENTAL_API + +# Prefer pkg-config from the upgraded DOCA installation. +PKGCONFIG_PKGS := doca-common doca-dma + +PKG_CFLAGS := $(shell pkg-config --cflags $(PKGCONFIG_PKGS) 2>/dev/null) +PKG_LIBS := $(shell pkg-config --libs $(PKGCONFIG_PKGS) 2>/dev/null) + +# Fallback for common DOCA 2.9 host install paths. +ifeq ($(strip $(PKG_CFLAGS)),) +CFLAGS += -I/opt/mellanox/doca/include +else +CFLAGS += $(PKG_CFLAGS) +endif + +ifeq ($(strip $(PKG_LIBS)),) +LDFLAGS += -L/opt/mellanox/doca/lib/x86_64-linux-gnu +LDLIBS += -ldoca_dma -ldoca_common +else +LDLIBS += $(PKG_LIBS) +endif + +LDLIBS += -lpthread -lrt + +all: $(TARGET) + +$(TARGET): $(SRCS) + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(LDLIBS) + +clean: + rm -f $(TARGET) descriptor.bin buffer.json diff --git a/dma/analyze_bw.py b/dma/analyze_bw.py new file mode 100755 index 0000000..e4fab84 --- /dev/null +++ b/dma/analyze_bw.py @@ -0,0 +1,345 @@ +#!/usr/bin/env python3 + +import argparse +import csv +import sys +from collections import defaultdict +from pathlib import Path + +import matplotlib.pyplot as plt +import numpy as np + + +KIBPS_TO_UNIT = { + "KiBps": 1.0, + "MiBps": 1.0 / 1024.0, + "GiBps": 1.0 / (1024.0 * 1024.0), +} + + +UNIT_DISPLAY = { + "KiBps": "KiB/s", + "MiBps": "MiB/s", + "GiBps": "GiB/s", +} + + +def format_bytes(n) -> str: + """ + Format size using the largest readable unit. + + Examples: + 246132K -> 246M + 2097148K -> 2.0G + + Notes: + - CSV normally gives integer bytes. + - This also accepts strings like "246132K" if needed. + - M is shown as rounded whole MB. + - G/T are shown with one decimal place. + """ + if isinstance(n, str): + s = n.strip() + suffix = s[-1].upper() + + if suffix in {"K", "M", "G", "T"}: + value = float(s[:-1]) + # Interpret suffix input as decimal-style units. + scale = { + "K": 1_000, + "M": 1_000_000, + "G": 1_000_000_000, + "T": 1_000_000_000_000, + }[suffix] + n = int(value * scale) + else: + n = int(s) + + n = int(n) + + # Use G/T when the value is large enough. + if n >= 1024 ** 4: + return f"{n / (1024 ** 4):.2f}T" + + if n >= 1024 ** 3: + return f"{n / (1024 ** 3):.2f}G" + + if n >= 1_000_000: + return f"{round(n / 1_000_000)}M" + + if n >= 1_000: + return f"{round(n / 1_000)}K" + + return f"{n}B" + +def experiment_label(path: str) -> str: + name = Path(path).name + + if name.startswith("bw_") and name.endswith(".csv"): + return name[len("bw_") : -len(".csv")] + + if name.startswith("bandwidth_") and name.endswith(".csv"): + return name[len("bandwidth_") : -len(".csv")] + + return Path(path).stem + + +def percentile(values, p: float) -> float: + return float(np.percentile(np.array(values, dtype=float), p)) + + +def read_bw_csv(path: str, unit: str): + grouped = defaultdict(list) + + with open(path, newline="") as f: + reader = csv.DictReader(f) + + if reader.fieldnames is None: + raise ValueError(f"{path}: empty CSV or missing header") + + fieldnames = [name.strip() for name in reader.fieldnames] + if fieldnames != ["bytes", "bw_KiBps"]: + raise ValueError( + f"{path}: expected header 'bytes,bw_KiBps', got: {','.join(fieldnames)}" + ) + + for line_no, row in enumerate(reader, start=2): + try: + nbytes = int(row["bytes"].strip()) + bw_kibps = float(row["bw_KiBps"].strip()) + except Exception as e: + raise ValueError(f"{path}: invalid row at line {line_no}: {row} ({e})") + + grouped[nbytes].append(bw_kibps * KIBPS_TO_UNIT[unit]) + + return grouped + + +def main() -> int: + parser = argparse.ArgumentParser( + description="Create grouped bandwidth bar graph from bw_*.csv files." + ) + parser.add_argument( + "inputs", + nargs="+", + help="Input CSV files with header: bytes,bw_KiBps. Recommended naming: bw_