Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validator #19

Open
kvark opened this issue Aug 2, 2017 · 3 comments
Open

Validator #19

kvark opened this issue Aug 2, 2017 · 3 comments

Comments

@kvark
Copy link
Member

kvark commented Aug 2, 2017

We need a validator for SPIR-V code

@caitp
Copy link

caitp commented Aug 19, 2018

I had a few ideas for this. The premise of these ideas is, the validator would be built as a part of the rspirv library (Possibly behind a feature), and the package would also include an application which consumes the validator API (providing nearly the same experience as SPIRV-Tools' validator).

Being in a library could allow a developer to add additional scrutiny before allowing Vulkan or GL APIs to run their module --- Diagnostic messages could be localized, or possibly easier to understand than errors produced by their graphics or compute API --- But the primary use would still be the validator application.

What do you think?

In addition to the above premise, there are a few areas where I'm a bit unsure of how I want this API to look/to be consumed. These are mostly cosmetic, but a few have significant effects on how the library would need to be developed.

API entrypoints (and their use)

  • Consume binary from start to finish, similar to SPIRV-Tools. This grants the opportunity to perform additional checks on the layout of a module that the rspirv::mr::Loader does not do, and do a better job of recording debug information for diagnostic messages..The main downside is, this would duplicate some of the work Loader is already doing. If a program wanted to do anything with a Module other than validation, it would be necessary to consume the binary again.
pub fn validate_bytes<T: AsRef<[u8]>>(binary: T) -> Result<()>;
pub fn validate_words<T: AsRef<[u32]>>(binary: T) -> Result<()>;
  • Consume an already decoded mr::Module, and assume that the module is in a valid layout. This is simpler, but could fail to report that the Module has an invalid Layout, in some cases (the Loader doesn't appear to reject all per-spec invalid forms, and does appear to reject OpLine/OpNoLine outside of a BasicBlock --- does not reject if a Phi's instruction's block operands are valid, etc). It's also possible that diagnostics could be reported out of order, and it may be difficult to produce good diagnostic messages using the debug opcodes.
pub fn validate_module(module: &mr::Module) -> Result<()>;
  • Making internal ValidationState structure public, and the validation entrypoints become methods of
    that class (Optionally, still have top-level entrtypoints which construct a ValidationState without
    returning it.
pub struct ValidationState {
    // ...
}

impl ValidationState {
    pub fn new(module: &mr::Module) -> ValidationState {
        // ...
    }
    pub fn validate() -> Result<()> {
        // ...
    }

    // ...
}

Error reporting:

  • Single diagnostic message reported via Result()
  • Diagnostics passed to caller through delegation, similar to binary::Consumer (e.g. DiagnosticConsumer)
trait DiagnosticConsumer {
    fn message(severity: Severity, message: Message) -> Action;

    // Or, if building diagnostic messages is the responsibility of the API consumer:
    fn message(severity: Severity, message: Message, line: Option(mr::Instruction) -> Action;
}

Optionally relaxing checks or imposing strict limits, as in SPIRV-Tools:

-pub fn validate_module(module: &mr::Module) -> Result<()>;
+pub fn validate_module(module: &mr::Module, options: Options) -> Result<()>;

Where Options is:

pub struct Options {
    // Same universal limits options as SPIRV-Tools' validator

    // Same lint-relaxing options as SPIRV-Tools' Validator
}

impl Default for Options {
    pub fn default() -> Options {
        Options {
            // Universal limits default to their per-spec values

            // Relaxing options default to false
        }
    }
}

Are Options fields publicly visible? Is Options constructed with a Builder? If so, is it OptionsBuilder or ValidatorBuilder, or what have you? If the API can consume both binary and fully constructed mr::Modules (in which case, we likely have a Builder API), do Options deserve a Builder as well?

@Danielmelody
Copy link

It is 2021, any efforts remained?

@grovesNL
Copy link
Contributor

grovesNL commented Jan 6, 2021

@Danielmelody not in rspirv, but it's pretty easy to use spirv-val from Rust now, which is able to validate SPIR-V. spirv-tools-rs contains bindings for spirv-val and some of the other tools from SPIR-V Tools.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants