# Makes the synthetic part of the GPU benchmark's corpus (tools/gpu_bench/corpus): screenshot-like # images full of text, for OCR, and two phone-sized photos scaled up from COCO ones. The images are # committed, and corpus.txt pins each one's SHA-256, so every machine benchmarks the same pixels; this # script is kept to show how they were made, not to be rerun (another Pillow or FreeType could draw # them a pixel differently, and then they would no longer match corpus.txt). # # python tools/gpu_bench/make_corpus.py import os, random from PIL import Image, ImageDraw, ImageFont HERE = os.path.dirname(os.path.abspath(__file__)) OUT = os.path.join(HERE, "corpus") FONTS = os.path.join(HERE, "..", "..", "assets", "fonts") WORDS = ("the of and to in is that for it as with was on be by this are from or at have an not but " "which they you were all one their there been has more when will would can if about what " "into some time only other new could these two may first then its such like over also back " "after use our work way well even because any most people where much through before right " "capture library image model search folder window screen label segment vector memory driver " "thread allocator buffer request response latency throughput benchmark kernel tensor batch " "session provider runtime device budget scheduler compiler release version settings export " "import config circuit board resistor capacitor footprint schematic voltage current signal " "amplifier channel sample filter frequency spectrum electrode impedance firmware bootloader").split() def font(name, size): return ImageFont.truetype(os.path.join(FONTS, name), size) def sentence(rng, n): words = [rng.choice(WORDS) for _ in range(n)] words[0] = words[0].capitalize() return " ".join(words) + rng.choice([".", ".", ",", ":", "?"]) def code_line(rng): kind = rng.randrange(6) a, b, c = rng.choice(WORDS), rng.choice(WORDS), rng.choice(WORDS) if kind == 0: return f"{a}_{b} := {c}_{rng.choice(WORDS)}({rng.randrange(1000)}, {a});" if kind == 1: return f"if {a}.{b} > {rng.randrange(64)} {{ {c}({a}); return false; }}" if kind == 2: return f"// {sentence(rng, rng.randrange(4, 12))}" if kind == 3: return f"for {a}: {b}_{c} array_add(*{a}s, it.{c});" if kind == 4: return f"{a}_{b} :: (x: s64, {c}: *{a.capitalize()}) -> bool {{" return f"print(\"% {a} {b}\\n\", {c}.count);" def editor(rng, w, h, dark, mono, size): bg, fg, dim, side = ((30, 30, 30), (212, 212, 212), (110, 110, 110), (37, 37, 38)) if dark else \ ((255, 255, 255), (30, 30, 30), (150, 150, 150), (243, 243, 243)) im = Image.new("RGB", (w, h), bg) d = ImageDraw.Draw(im) ui, code = font("OpenSans-Regular.ttf", 14), font(mono, size) d.rectangle([0, 0, w, 32], fill=side) for i, x in enumerate(range(10, w - 200, 180)): d.text((x, 8), f"{rng.choice(WORDS)}_{rng.choice(WORDS)}.jai", font=ui, fill=fg if i == 0 else dim) d.rectangle([0, 32, 260, h], fill=side) y = 44 while y < h - 30: d.text((16 + 12 * rng.randrange(3), y), f"{rng.choice(WORDS)}_{rng.choice(WORDS)}", font=ui, fill=fg) y += 24 colours = [fg, (86, 156, 214), (206, 145, 120), (106, 153, 85), (197, 134, 192)] if dark else \ [fg, (0, 0, 255), (163, 21, 21), (0, 128, 0), (175, 0, 219)] line, y = rng.randrange(1, 900), 44 while y < h - 30: d.text((272, y), str(line).rjust(4), font=code, fill=dim) if rng.random() > 0.12: d.text((330 + 4 * size // 2 * rng.randrange(4), y), code_line(rng), font=code, fill=rng.choice(colours)) y += int(size * 1.5); line += 1 d.rectangle([0, h - 24, w, h], fill=(0, 122, 204)) d.text((10, h - 21), f"Ln {line}, Col {rng.randrange(80)} UTF-8 CRLF Jai {rng.choice(WORDS)}", font=ui, fill=(255, 255, 255)) return im def document(rng, w, h, size): im = Image.new("RGB", (w, h), (250, 250, 248)) d = ImageDraw.Draw(im) title, body = font("OpenSans-Bold.ttf", size * 2), font("OpenSans-Regular.ttf", size) margin = w // 8 d.text((margin, 40), sentence(rng, 5)[:-1], font=title, fill=(20, 20, 20)) y = 60 + size * 3 while y < h - size * 2: if rng.random() < 0.15: d.text((margin, y), sentence(rng, 4)[:-1], font=font("OpenSans-SemiBold.ttf", int(size * 1.3)), fill=(40, 40, 90)) y += int(size * 2.2); continue for _ in range(rng.randrange(2, 7)): text = sentence(rng, 40) words, current = text.split(), "" for word in words: trial = (current + " " + word).strip() if d.textlength(trial, font=body) > w - 2 * margin: d.text((margin, y), current, font=body, fill=(30, 30, 30)); y += int(size * 1.6); current = word else: current = trial d.text((margin, y), current, font=body, fill=(30, 30, 30)); y += int(size * 1.6) if y > h - size * 2: break y += size return im def spreadsheet(rng, w, h): im = Image.new("RGB", (w, h), (255, 255, 255)) d = ImageDraw.Draw(im) f, bold = font("OpenSans-Regular.ttf", 13), font("OpenSans-SemiBold.ttf", 13) cols = [40] + [rng.choice([90, 110, 140, 180]) for _ in range(30)] d.rectangle([0, 0, w, 60], fill=(33, 115, 70)) d.text((12, 18), f"{rng.choice(WORDS)}_{rng.choice(WORDS)}.xlsx", font=font("OpenSans-SemiBold.ttf", 18), fill=(255, 255, 255)) y, row = 60, 0 while y < h: x = 0 for c, cw in enumerate(cols): if x > w: break d.rectangle([x, y, x + cw, y + 22], outline=(218, 220, 224), fill=(243, 243, 243) if row == 0 or c == 0 else None) if row == 0 and c > 0: text, ft = chr(64 + c) if c <= 26 else "A" + chr(38 + c), bold elif c == 0: text, ft = str(row) if row else "", bold elif row == 1: text, ft = rng.choice(WORDS).capitalize(), bold else: r = rng.random() text = f"{rng.uniform(0, 99999):,.2f}" if r < 0.5 else (str(rng.randrange(10000)) if r < 0.7 else rng.choice(WORDS)) ft = f d.text((x + 4, y + 3), text, font=ft, fill=(20, 20, 20)) x += cw y += 22; row += 1 return im def terminal(rng, w, h, size): im = Image.new("RGB", (w, h), (12, 12, 12)) d = ImageDraw.Draw(im) f = font("FiraCode-Retina.ttf", size) y = 8 while y < h - size: r = rng.random() if r < 0.2: text, colour = f"PS D:\\{rng.choice(WORDS)}\\{rng.choice(WORDS)}> jai first.jai - {rng.choice(WORDS)}", (240, 240, 240) elif r < 0.3: text, colour = f"error: {sentence(rng, 8)}", (240, 80, 80) elif r < 0.4: text, colour = f"[{rng.randrange(24):02}:{rng.randrange(60):02}:{rng.randrange(60):02}] {rng.choice(['INFO', 'WARN', 'DEBUG'])} {sentence(rng, 9)}", (180, 220, 120) else: text, colour = " ".join(f"{rng.randrange(1 << 16):04x}" for _ in range(rng.randrange(4, 18))), (200, 200, 200) d.text((8, y), text, font=f, fill=colour) y += int(size * 1.35) return im def chat(rng, w, h): im = Image.new("RGB", (w, h), (245, 245, 250)) d = ImageDraw.Draw(im) f, name = font("OpenSans-Regular.ttf", 30), font("OpenSans-Bold.ttf", 26) d.rectangle([0, 0, w, 140], fill=(60, 60, 140)) d.text((40, 60), rng.choice(WORDS).capitalize() + " " + rng.choice(WORDS).capitalize(), font=font("OpenSans-SemiBold.ttf", 40), fill=(255, 255, 255)) y = 170 while y < h - 200: mine = rng.random() < 0.5 lines = [sentence(rng, rng.randrange(2, 6)) for _ in range(rng.randrange(1, 4))] width = max(d.textlength(l, font=f) for l in lines) + 40 height = 44 * len(lines) + 56 x = w - width - 40 if mine else 40 d.rounded_rectangle([x, y, x + width, y + height], 24, fill=(90, 120, 230) if mine else (255, 255, 255)) d.text((x + 20, y + 10), f"{rng.randrange(1, 13)}:{rng.randrange(60):02} {'PM' if rng.random() < 0.5 else 'AM'}", font=name, fill=(230, 230, 255) if mine else (120, 120, 120)) for i, l in enumerate(lines): d.text((x + 20, y + 48 + 44 * i), l, font=f, fill=(255, 255, 255) if mine else (20, 20, 20)) y += height + 24 return im def dialog(rng, w, h): im = editor(rng, w, h, True, "JetBrainsMono-Regular.ttf", 14).point(lambda v: v // 2) d = ImageDraw.Draw(im) x0, y0, x1, y1 = w // 2 - 320, h // 2 - 160, w // 2 + 320, h // 2 + 160 d.rectangle([x0, y0, x1, y1], fill=(250, 250, 250), outline=(120, 120, 120)) d.text((x0 + 24, y0 + 20), sentence(rng, 4)[:-1], font=font("OpenSans-SemiBold.ttf", 22), fill=(20, 20, 20)) for i in range(4): d.text((x0 + 24, y0 + 70 + 30 * i), sentence(rng, 9), font=font("OpenSans-Regular.ttf", 17), fill=(40, 40, 40)) for i, label in enumerate(["Cancel", "Don't save", "Save"]): bx = x1 - 130 * (3 - i) - 10 d.rectangle([bx, y1 - 60, bx + 115, y1 - 22], fill=(0, 103, 192) if label == "Save" else (225, 225, 225)) d.text((bx + 20, y1 - 52), label, font=font("OpenSans-Regular.ttf", 17), fill=(255, 255, 255) if label == "Save" else (20, 20, 20)) return im def main(): rng = random.Random(20261017) made = [ ("screen-editor-dark-1080p.png", editor(rng, 1920, 1080, True, "JetBrainsMono-Regular.ttf", 15)), ("screen-editor-light-1080p.png", editor(rng, 1920, 1080, False, "RobotoMono-Regular.ttf", 14)), ("screen-editor-dark-1440p.png", editor(rng, 2560, 1440, True, "FiraCode-Retina.ttf", 16)), ("screen-document-1080p.png", document(rng, 1920, 1080, 18)), ("screen-document-4k.png", document(rng, 3840, 2160, 28)), ("screen-spreadsheet-1080p.png", spreadsheet(rng, 1920, 1080)), ("screen-spreadsheet-1440p.png", spreadsheet(rng, 2560, 1440)), ("screen-terminal-1080p.png", terminal(rng, 1920, 1080, 15)), ("screen-terminal-720p.png", terminal(rng, 1280, 720, 13)), ("screen-chat-phone.png", chat(rng, 1080, 2400)), ("screen-dialog-1080p.png", dialog(rng, 1920, 1080)), ("screen-document-strip.png", document(rng, 1600, 300, 16)), ] for name, im in made: im.save(os.path.join(OUT, name), optimize=False, compress_level=6) # Phone-sized photos: the decoders and resizers see a 12-megapixel image, as from a phone. for source, name in [("coco-000000000139.jpg", "photo-12mp-livingroom.jpg"), ("coco-000000001000.jpg", "photo-12mp-tennis.jpg")]: im = Image.open(os.path.join(OUT, source)).convert("RGB").resize((4032, 3024), Image.LANCZOS) im.save(os.path.join(OUT, name), quality=92) main()