dawn/node: Allow picking of the adapter by name

Add the "--adapter" flag to run-cts as a helper for setting this.

Make "--verbose" print the picked adapter.

Rename "dawn-backend" flag to just "backend" - this is already specific to the "gpu provider" (dawn).

Change-Id: Idc8d0eb3ccf5fa23325c06f0f9520aa9b528d9dd
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/116295
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2023-01-10 19:15:42 +00:00 committed by Dawn LUCI CQ
parent c6236de7c2
commit c9c937cc3e
3 changed files with 117 additions and 51 deletions

View File

@ -69,7 +69,8 @@ VK_ICD_FILENAMES=<swiftshader-cmake-build>/Linux/vk_swiftshader_icd.json ./src/t
```
The `--flag` parameter must be passed in multiple times, once for each flag begin set. Here are some common arguments:
* `dawn-backend=<null|webgpu|d3d11|d3d12|metal|vulkan|opengl|opengles>`
* `backend=<null|webgpu|d3d11|d3d12|metal|vulkan|opengl|opengles>`
* `adapter=<name-of-adapter>` - specifies the adapter to use. May be a substring of the full adapter name. Pass an invalid adapter name and `--verbose` to see all possible adapters.
* `dlldir=<path>` - used to add an extra DLL search path on Windows, primarily to load the right d3dcompiler_47.dll
* `enable-dawn-features=<features>` - enable [Dawn toggles](https://dawn.googlesource.com/dawn/+/refs/heads/main/src/dawn/native/Toggles.cpp), e.g. `dump_shaders`
* `disable-dawn-features=<features>` - disable [Dawn toggles](https://dawn.googlesource.com/dawn/+/refs/heads/main/src/dawn/native/Toggles.cpp)

View File

@ -52,6 +52,41 @@ void SetDllDir(const char* dir) {
#endif
}
struct BackendInfo {
const char* const name;
const char* const alias; // may be nullptr
wgpu::BackendType const backend;
};
constexpr BackendInfo kBackends[] = {
{"null", nullptr, wgpu::BackendType::Null}, //
{"webgpu", nullptr, wgpu::BackendType::WebGPU}, //
{"d3d11", nullptr, wgpu::BackendType::D3D11}, //
{"d3d12", "d3d", wgpu::BackendType::D3D12}, //
{"metal", nullptr, wgpu::BackendType::Metal}, //
{"vulkan", "vk", wgpu::BackendType::Vulkan}, //
{"opengl", "gl", wgpu::BackendType::OpenGL}, //
{"opengles", "gles", wgpu::BackendType::OpenGLES}, //
};
std::optional<wgpu::BackendType> ParseBackend(std::string_view name) {
for (auto& info : kBackends) {
if (info.name == name || (info.alias && info.alias == name)) {
return info.backend;
}
}
return std::nullopt;
}
const char* BackendName(wgpu::BackendType backend) {
for (auto& info : kBackends) {
if (info.backend == backend) {
return info.name;
}
}
return "<unknown>";
}
} // namespace
namespace wgpu::binding {
@ -99,69 +134,93 @@ interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>> GPU::re
#error "Unsupported platform"
#endif
auto targetBackendType = defaultBackendType;
// Check for backend override from env var / flag
std::string forceBackend;
// Check for override from env var
if (std::string envVar = GetEnvVar("DAWNNODE_BACKEND"); !envVar.empty()) {
if (auto f = flags_.Get("backend")) {
forceBackend = *f;
} else if (std::string envVar = GetEnvVar("DAWNNODE_BACKEND"); !envVar.empty()) {
forceBackend = envVar;
}
// Check for override from flag
if (auto f = flags_.Get("dawn-backend")) {
forceBackend = *f;
// Check for specific adapter name
std::string adapterName;
if (auto f = flags_.Get("adapter")) {
adapterName = *f;
}
std::transform(forceBackend.begin(), forceBackend.end(), forceBackend.begin(),
[](char c) { return std::tolower(c); });
// Default to first adapter if a backend is not specified
size_t adapterIndex = 0;
auto targetBackendType = defaultBackendType;
if (!forceBackend.empty()) {
if (forceBackend == "null") {
targetBackendType = wgpu::BackendType::Null;
} else if (forceBackend == "webgpu") {
targetBackendType = wgpu::BackendType::WebGPU;
} else if (forceBackend == "d3d11") {
targetBackendType = wgpu::BackendType::D3D11;
} else if (forceBackend == "d3d12" || forceBackend == "d3d") {
targetBackendType = wgpu::BackendType::D3D12;
} else if (forceBackend == "metal") {
targetBackendType = wgpu::BackendType::Metal;
} else if (forceBackend == "vulkan" || forceBackend == "vk") {
targetBackendType = wgpu::BackendType::Vulkan;
} else if (forceBackend == "opengl" || forceBackend == "gl") {
targetBackendType = wgpu::BackendType::OpenGL;
} else if (forceBackend == "opengles" || forceBackend == "gles") {
targetBackendType = wgpu::BackendType::OpenGLES;
if (auto parsed = ParseBackend(forceBackend)) {
targetBackendType = parsed.value();
} else {
promise.Reject("unknown backend '" + forceBackend + "'");
std::stringstream msg;
msg << "unrecognised backend '" + forceBackend + "'" << std::endl
<< "Possible backends: ";
for (auto& info : kBackends) {
if (&info != &kBackends[0]) {
msg << ", ";
}
msg << "'" << info.name << "'";
}
promise.Reject(msg.str());
return promise;
}
}
bool found = false;
for (size_t i = 0; i < adapters.size(); ++i) {
dawn::native::Adapter* adapter = nullptr;
for (auto& a : adapters) {
wgpu::AdapterProperties props;
adapters[i].GetProperties(&props);
if (props.backendType == targetBackendType) {
adapterIndex = i;
found = true;
break;
a.GetProperties(&props);
if (props.backendType != targetBackendType) {
continue;
}
if (!adapterName.empty() && props.name &&
std::string(props.name).find(adapterName) == std::string::npos) {
continue;
}
adapter = &a;
break;
}
if (!found) {
if (!forceBackend.empty()) {
promise.Reject("backend '" + forceBackend + "' not found");
if (!adapter) {
std::stringstream msg;
if (!forceBackend.empty() || adapterName.empty()) {
msg << "no adapter ";
if (!forceBackend.empty()) {
msg << "with backend '" << forceBackend << "'";
if (!adapterName.empty()) {
msg << " and name '" << adapterName << "'";
}
} else {
msg << " with name '" << adapterName << "'";
}
msg << " found";
} else {
promise.Reject("no suitable backends found");
msg << "no suitable backends found";
}
msg << std::endl << "Available adapters:";
for (auto& a : adapters) {
wgpu::AdapterProperties props;
a.GetProperties(&props);
msg << std::endl
<< " * backend: '" << BackendName(props.backendType) << "', name: '" << props.name
<< "'";
}
promise.Reject(msg.str());
return promise;
}
auto adapter = GPUAdapter::Create<GPUAdapter>(env, adapters[adapterIndex], flags_);
promise.Resolve(std::optional<interop::Interface<interop::GPUAdapter>>(adapter));
if (flags_.Get("verbose")) {
wgpu::AdapterProperties props;
adapter->GetProperties(&props);
printf("using GPU adapter: %s\n", props.name);
}
auto gpuAdapter = GPUAdapter::Create<GPUAdapter>(env, *adapter, flags_);
promise.Resolve(std::optional<interop::Interface<interop::GPUAdapter>>(gpuAdapter));
return promise;
}

View File

@ -131,8 +131,8 @@ func run() error {
unrollConstEvalLoopsDefault := runtime.GOOS != "windows"
var dawnNode, cts, node, npx, resultsPath, expectationsPath, logFilename, backend, coverageFile string
var printStdout, verbose, isolated, build, dumpShaders, unrollConstEvalLoops, genCoverage bool
var dawnNode, cts, node, npx, resultsPath, expectationsPath, logFilename, backend, adapterName, coverageFile string
var verbose, isolated, build, dumpShaders, unrollConstEvalLoops, genCoverage bool
var numRunners int
var flags dawnNodeFlags
flag.StringVar(&dawnNode, "dawn-node", "", "path to dawn.node module")
@ -141,7 +141,6 @@ func run() error {
flag.StringVar(&npx, "npx", "", "path to npx executable")
flag.StringVar(&resultsPath, "output", "", "path to write test results file")
flag.StringVar(&expectationsPath, "expect", "", "path to expectations file")
flag.BoolVar(&printStdout, "print-stdout", false, "print the stdout and stderr from each test runner server")
flag.BoolVar(&verbose, "verbose", false, "print extra information while testing")
flag.BoolVar(&build, "build", true, "attempt to build the CTS before running")
flag.BoolVar(&isolated, "isolate", false, "run each test in an isolated process")
@ -151,6 +150,7 @@ func run() error {
flag.Var(&flags, "flag", "flag to pass to dawn-node as flag=value. multiple flags must be passed in individually")
flag.StringVar(&backend, "backend", backendDefault, "backend to use: default|null|webgpu|d3d11|d3d12|metal|vulkan|opengl|opengles."+
" set to 'vulkan' if VK_ICD_FILENAMES environment variable is set, 'default' otherwise")
flag.StringVar(&adapterName, "adapter", "", "name (or substring) of the GPU adapter to use")
flag.BoolVar(&dumpShaders, "dump-shaders", false, "dump WGSL shaders. Enables --verbose")
flag.BoolVar(&unrollConstEvalLoops, "unroll-const-eval-loops", unrollConstEvalLoopsDefault, "unroll loops in const-eval tests")
flag.BoolVar(&genCoverage, "coverage", false, "displays coverage data. Enables --isolated")
@ -209,10 +209,13 @@ func run() error {
}
}
// Forward the backend to use, if specified.
// Forward the backend and adapter to use, if specified.
if backend != "default" {
fmt.Fprintln(stdout, "Forcing backend to", backend)
flags = append(flags, fmt.Sprint("dawn-backend=", backend))
flags.Set("backend=" + backend)
}
if adapterName != "" {
flags.Set("adapter=" + adapterName)
}
// While running the CTS, always allow unsafe APIs so they can be tested.
@ -233,7 +236,6 @@ func run() error {
r := runner{
numRunners: numRunners,
printStdout: printStdout,
verbose: verbose,
node: node,
npx: npx,
@ -416,7 +418,6 @@ func (c *cache) save(path string) error {
type runner struct {
numRunners int
printStdout bool
verbose bool
node string
npx string
@ -657,7 +658,9 @@ func (r *runner) runServer(ctx context.Context, id int, caseIndices <-chan int,
args = append(args, "--colors")
}
if r.verbose {
args = append(args, "--verbose")
args = append(args,
"--verbose",
"--gpu-provider-flag", "verbose=1")
}
if r.unrollConstEvalLoops {
args = append(args, "--unroll-const-eval-loops")
@ -669,7 +672,7 @@ func (r *runner) runServer(ctx context.Context, id int, caseIndices <-chan int,
cmd := exec.CommandContext(ctx, r.node, args...)
writer := io.Writer(testCaseLog)
if r.printStdout {
if r.verbose {
pw := &prefixWriter{
prefix: fmt.Sprintf("[%d] ", id),
writer: r.stdout,
@ -1065,9 +1068,12 @@ func (r *runner) runTestcase(ctx context.Context, query string, profraw string)
"placeholder-arg",
// Actual arguments begin here
"--gpu-provider", r.dawnNode,
"--verbose",
"--verbose", // always required to emit test pass results
"--quiet",
}
if r.verbose {
args = append(args, "--gpu-provider-flag", "verbose=1")
}
if r.colors {
args = append(args, "--colors")
}