DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Rcyc-1025 /

Rcyc-1025/dsh-mlir-toolchain

Verified

MLIR toolchain tools for DeepSeek Harness: probe, run, TableGen and parse-check.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@0a46e825

dsh-mlir-toolchain

MLIR toolchain tools for DeepSeek Harness (DSH) — probe, run, TableGen and parse-check MLIR without shell quotes or ENOENT surprises.

English | 简体中文

License: MIT Node

This is a DSH plugin. It turns a toolchain.json (generated by your MLIR build script) into four model-facing tools backed by the host subprocess service:

Tool What it does
mlir_probe Reads toolchain.json, probes every binary in parallel with --version, and reports ok, missing vs. failing tools, version mismatches and the TableGen include directories that would be used
mlir_run Runs mlir-opt, mlir-translate, mlir-tblgen, mlir-runner, mlir-reduce, llc, clang, filecheck, llvm-config or llvm-objdump with an argv array (no shell)
mlir_tblgen -gen-* code generation with automatic mlir/IR/OpBase.td discovery, 35 named kinds, raw flag passthrough and auto-created output directories
mlir_parse_check Parses/verifies MLIR with mlir-opt, optionally running a pass pipeline, and returns structured errors/warnings/notes

Nothing is executed through a shell, no binaries are looked up on PATH, and the plugin has zero runtime dependencies.

Requirements

  • Node.js ^22.19.0 || >=24.0.0
  • DeepSeek Harness >=0.2.1-rc.5 <0.3.0-0
  • LLVM/MLIR binaries. Development and CI checks were done against LLVM 23.1.4, but any recent release that provides mlir-opt, mlir-translate, mlir-tblgen and llc should work.
  • mlir-tblgen additionally needs MLIR's TableGen headers (mlir/IR/OpBase.td) — from a source checkout or an installed mlir/include.

A toolchain.json is recommended. Its shape (extra fields are ignored):

{
  "llvm": {
    "version": "23.1.4",
    "root": "/opt/llvm",
    "mlirRoot": "/opt/llvm-build",
    "tools": {
      "mlirOpt":       { "path": "/opt/llvm-build/bin/mlir-opt",       "version": "23.1.4" },
      "mlirTranslate": { "path": "/opt/llvm-build/bin/mlir-translate", "version": "23.1.4" },
      "mlirTblgen":    { "path": "/opt/llvm-build/bin/mlir-tblgen",    "version": "23.1.4" },
      "llc":           { "path": "/opt/llvm/bin/llc",                  "version": "23.1.4" },
      "mlirRunner":    { "path": "/opt/llvm-build/bin/mlir-runner" },
      "llvmConfig":    { "path": "/opt/llvm/bin/llvm-config" }
    }
  },
  "mlirDev": {
    "include": "/opt/llvm-project/mlir/include",
    "lib": "/opt/llvm-build/lib"
  }
}

Recognised llvm.tools keys: mlirOpt, mlirTranslate, mlirTblgen, mlirRunner, mlirReduce, llc, opt, clang, llvmConfig, llvmObjdump, cmake, ninja, filecheck.

Install

# from the directory that contains this checkout
dsh plugin --profile desktop add ./dsh-mlir-toolchain

The CLI adds the package to the profile's dsh.profile.bundles; the plugin registers itself through its bundled cordis.patch.yml. Server-side plugins hot-reload — the four tools appear immediately. Uninstall with:

dsh plugin --profile desktop remove dsh-mlir-toolchain

If you are trying the plugin inside a sandboxed session (DSH workspace-write), the profile directory may live outside the workspace. Install it from a normal terminal or grant the operation the permission it asks for.

Configuration

Zero configuration works when toolchain.json sits next to the plugin directory (the common mlir-lang/dsh-mlir-toolchain + mlir-lang/toolchain.json layout), inside it, in the session cwd, or in <cwd>/mlir-lang/. Discovery runs once at plugin load and again per call when no path was found — so a session opened in a different directory still picks it up.

Precedence: config.toolchainPath / MLIR_TOOLCHAIN_JSON > auto-discovery.

To point at a specific file (or override individual binaries):

- id: mlir-toolchain
  name: 'dsh-mlir-toolchain'
  config:
    toolchainPath: /opt/llvm/toolchain.json   # optional
    includeDirs:                              # optional: extra -I roots
      - /opt/llvm-project/mlir/include
    timeoutMs: 120000
    maxOutputBytes: 1048576
    logKeep: 100
    # Single-binary overrides (absolute or cwd-relative):
    # mlirOptPath, mlirTranslatePath, mlirTblgenPath, mlirRunnerPath,
    # mlirReducePath, llcPath, optPath, clangPath, filecheckPath,
    # llvmObjdumpPath, llvmConfigPath
Option Default Meaning
toolchainPath auto Absolute path to toolchain.json
includeDirs [] Extra TableGen include roots
timeoutMs 120000 Per-call timeout (clamped to 1s–10min)
maxOutputBytes 1048576 stdout/stderr bytes returned per stream (clamped to 4 KiB–8 MiB)
graceMs 5000 Grace period before a timed-out process is killed
logKeep 100 Keep only the newest N files in .mlir-logs/

Environment variables: MLIR_TOOLCHAIN_JSON (path to toolchain.json), MLIR_INCLUDE_DIR (TableGen include roots, ;/: separated).

Tools

mlir_probe

Probes every tool referenced by the configuration, in parallel.

{ "ok": true, "source": "toolchain.json",
  "llvm": { "version": "23.1.4", "root": "/opt/llvm", "mlirRoot": "/opt/llvm-build" },
  "tools": { "mlir-opt": { "path": "...", "exists": true, "ok": true, "version": "23.1.4" } },
  "missing": [], "failed": [], "optionalMissing": ["filecheck"],
  "versionMismatch": [], "tblgenInclude": { "source": "auto", "dirs": ["..."] } }

missing means the file does not exist; failed means it exists but --version failed. TableGen include directories are reported here so you can spot a broken -I before generating code.

mlir_run

{ "tool": "mlir-opt", "args": ["--pass-pipeline=builtin.module(cse)"],
  "inputText": "module { ... }", "cwd": ".", "timeoutMs": 30000 }

Returns { ok, exitCode, timedOut, durationMs, stdout, stderr, truncated, logPath, hint }. inputText is written to a temporary .mlir file and appended as the last argument; inputPath is resolved against the session cwd. Full output is written to .mlir-logs/ when it exceeds maxOutputBytes, and hint points at the log.

mlir_tblgen

{ "kind": "op-decls", "inputPath": "include/MyOps.td",
  "outputPath": "build/MyOps.h.inc" }
  • kind accepts named kinds (op-decls, op-defs, op-doc, op-interface-decls/defs/docs, dialect-decls/defs/doc, dialect-interface-decls, typedef-decls/defs/doc, attrdef-decls/defs/doc, enum-decls/defs/doc, attr-constraint-decls/defs, type-constraint-decls/defs, rewriters, pass-decls, pass-doc, pass-capi-header, pass-capi-impl, bytecode, directive-decl, llvmir-conversions, enum-from/to-llvmir-conversions, op-from-llvmir-conversions, convertible-llvmir-intrinsics, python-op-bindings, python-enum-bindings, …) or a raw gen:<name> / -gen-<name> flag.
  • includeDirs is optional; omit it and the plugin finds the MLIR include root itself.
  • outputPath is optional (stdout otherwise); parent directories are created automatically.
  • Returns { ok, exitCode, timedOut, outputPath, generatedLines, bytes, includeDirs, includeSource, logPath, hint }.

Include resolution order: tool argument → plugin includeDirs → MLIR_INCLUDE_DIR → automatic candidates. A candidate is used only if it actually contains mlir/IR/OpBase.td and is probed among: mlirDev.include/lib/cmakeDir (and their parents), <llvm.root>/include, <mlirRoot>/include, <mlirRoot>/tools/mlir/include, and llvm-src/*/mlir/include beside either root or one level up. When nothing is found, the hint lists every directory that was searched.

mlir_parse_check

{ "source": "module { func.func @f(%a: i32) -> i32 { return %a : i32 } }",
  "passes": ["cse", "canonicalize"], "maxDiagnostics": 200 }
  • source and path are mutually exclusive (supplying both is an error, nothing is spawned).
  • passes accepts a full pipeline string (builtin.module(cse,canonicalize)) or an array, which is wrapped automatically. It runs through --pass-pipeline=.
  • Returns structured errors, warnings, notes (file, line, col, severity, message), exitCode, passPipeline, logPath. Diagnostics for inline sources use <source> as the file name.
  • allowDiagnostics: true reports ok: true even when diagnostics exist (useful for expected-warning tests).

Design constraints

  • Uses only the host services ctx.subprocess and ctx.tools; no imports from @deepseek-ai/dsh-*, no runtime dependencies.
  • Every command is an argv array — never a shell string.
  • Working directory defaults to the session cwd; relative paths are resolved against it.
  • apply() performs no long blocking work: all probing happens inside mlir_probe (parallel spawns).
  • Failures are returned as data (ok:false + a hint), not thrown — a missing toolchain never prevents the host or the plugin from starting.

Development

npm test        # unit tests (self-contained fixtures) + real integration tests (skipped when no toolchain.json / no spawn permission)
npm run smoke   # real end-to-end check of all four tools
  • Tests must run with --test-isolation=none and an explicit file list: node --test test/ forks worker processes, and forking is denied inside DSH's workspace-write sandbox (spawn EPERM). If you run the suite there, the integration file skips itself.
  • test/fixtures.mjs builds a temporary fake toolchain (bin/*.exe placeholders, llvm-src/.../OpBase.td, toolchain.json), so unit tests never touch your machine's LLVM and never write logs into the repo.
  • test/integration.test.mjs and test/smoke.mjs exercise real binaries; they read MLIR_TOOLCHAIN_JSON (or the same auto-discovery) and skip/report clearly when none is available.

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 0a46e825e76f

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout