import itertools import json import os import signal import subprocess import time import fpzip import numpy as np from .cmake import CMake from .config import BasePoint, Config from .logger import Logger from .score import compute_axes_ids, compute_weight_matrices, get_workload_weight from .storage import Storage, get_bench_table_name def first_val(my_dict): values = list(my_dict.values()) first_value = values[0] if not all(value == first_value for value in values): raise ValueError( "All values in the dictionary are not equal. First value: {} All values: {}".format( first_value, values ) ) return first_value class JsonCache: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) cls._instance.bench_cache = {} cls._instance.device_cache = {} return cls._instance def get_jsonlist(self, algname, listname): benchmark_bin = os.path.join(".", "bin", algname + ".base") if not os.path.exists(benchmark_bin): raise Exception(f"Benchmark binary not found: {benchmark_bin}") return subprocess.check_output([benchmark_bin, f"--jsonlist-{listname}"]) def get_bench(self, algname): if algname not in self.bench_cache: result = self.get_jsonlist(algname, "benches") self.bench_cache[algname] = json.loads(result) return self.bench_cache[algname] def get_device(self, algname): if algname not in self.device_cache: result = self.get_jsonlist(algname, "devices") data = json.loads(result) if "devices" not in data: raise Exception( "JSON returned from --jsonlist-devices does not contain 'devices' key" ) devices = data["devices"] if len(devices) != 1: raise Exception( "NVBench doesn't work well with multiple GPUs, use `CUDA_VISIBLE_DEVICES`" ) self.device_cache[algname] = devices[0] return self.device_cache[algname] def json_benches(algname): return JsonCache().get_bench(algname) def create_benches_tables(conn, subbench, bench_axes): with conn: conn.execute(""" CREATE TABLE IF NOT EXISTS subbenches ( algorithm TEXT NOT NULL, bench TEXT NOT NULL, UNIQUE(algorithm, bench) ); """) for algorithm_name in bench_axes: axes = bench_axes[algorithm_name] column_names = ", ".join(['"{}"'.format(name) for name in axes]) columns = ", ".join(['"{}" TEXT'.format(name) for name in axes]) conn.execute( """ INSERT INTO subbenches (algorithm, bench) VALUES (?, ?) ON CONFLICT DO NOTHING; """, (algorithm_name, subbench), ) if axes: columns = ", " + columns column_names = ", " + column_names conn.execute( """ CREATE TABLE IF NOT EXISTS "{0}" ( ctk TEXT NOT NULL, cccl TEXT NOT NULL, gpu TEXT NOT NULL, variant TEXT NOT NULL, elapsed REAL, center REAL, bw REAL, samples BLOB {1} , UNIQUE(ctk, cccl, gpu, variant {2}) ); """.format( get_bench_table_name(subbench, algorithm_name), columns, column_names, ) ) def read_json(filename): with open(filename, "r") as f: file_root = json.load(f) return file_root def extract_filename(summary): summary_data = summary["data"] value_data = next(filter(lambda v: v["name"] == "filename", summary_data)) assert value_data["type"] == "string" return value_data["value"] def extract_size(summary): summary_data = summary["data"] value_data = next(filter(lambda v: v["name"] == "size", summary_data)) assert value_data["type"] == "int64" return int(value_data["value"]) def extract_bw(summary): summary_data = summary["data"] value_data = next(filter(lambda v: v["name"] == "value", summary_data)) assert value_data["type"] == "float64" return float(value_data["value"]) def parse_samples_meta(state): summaries = state["summaries"] if not summaries: return None, None summary = next( filter(lambda s: s["tag"] == "nv/json/bin:nv/cold/sample_times", summaries), None, ) if not summary: return None, None sample_filename = extract_filename(summary) sample_count = extract_size(summary) return sample_count, sample_filename def parse_samples(state): sample_count, samples_filename = parse_samples_meta(state) if not sample_count or not samples_filename: return np.array([], dtype=np.float32) with open(samples_filename, "rb") as f: samples = np.fromfile(f, "