Start emitting ptx module from compilation

This commit is contained in:
Andrzej Janik 2020-04-03 01:23:11 +02:00
commit b8129aab20
6 changed files with 132 additions and 81 deletions

View file

@ -9,6 +9,7 @@ edition = "2018"
[dependencies] [dependencies]
lalrpop-util = "0.18.1" lalrpop-util = "0.18.1"
regex = "1" regex = "1"
rspirv = "0.6"
[build-dependencies.lalrpop] [build-dependencies.lalrpop]
version = "0.18.1" version = "0.18.1"

View file

@ -3,4 +3,16 @@ I'm convinced nobody actually uses parser generators in Rust:
* pest can't do parse actions, you have to convert your parse tree to ast manually * pest can't do parse actions, you have to convert your parse tree to ast manually
* lalrpop can't do comments * lalrpop can't do comments
* and the day I wrote the line above it can * and the day I wrote the line above it can
* antlr4rust is untried and requires java to build * reports parsing errors as byte offsets
* if you want to skip parsing one of the alternatives functional design gets quite awkward
* antlr4rust is untried and requires java to build
* no library supports island grammars
What to emit?
* SPIR-V
* Better library support, easier to emit
* Can by optimized by IGC
* Can't do some things (not sure what exactly yet)
* But we can work around things with inline VISA
* VISA
* Quicker compilation

View file

@ -1,18 +1,39 @@
pub struct Module<'a> {
pub struct Module { pub version: (u8, u8),
version: (u8, u8), pub functions: Vec<Function<'a>>
target: Target
} }
pub struct Target { pub struct Function<'a> {
arch: String, pub kernel: bool,
texturing: TexturingMode, pub name: &'a str,
debug: bool, pub args: Vec<Argument>,
f64_to_f32: bool pub body: Vec<Statement<'a>>,
} }
pub enum TexturingMode { pub struct Argument {
Unspecified,
Unified, }
Independent
pub enum Statement<'a> {
Label(&'a str),
Variable(Variable),
Instruction(Instruction)
}
pub struct Variable {
}
pub enum Instruction {
Ld,
Mov,
Mul,
Add,
Setp,
Not,
Bra,
Cvt,
Shl,
At,
Ret
} }

View file

@ -1,9 +1,11 @@
#[macro_use] #[macro_use]
extern crate lalrpop_util; extern crate lalrpop_util;
lalrpop_mod!(pub ptx); lalrpop_mod!(ptx);
mod test; mod test;
mod spirv;
pub mod ast; pub mod ast;
pub use ast::Module as Module; pub use ast::Module as Module;
pub use spirv::translate as to_spirv;

View file

@ -1,5 +1,6 @@
use std::str::FromStr; use std::str::FromStr;
use super::ast; use crate::ast;
use std::convert::identity;
grammar; grammar;
@ -15,15 +16,21 @@ match {
_ _
} }
pub Module: () = { pub Module: Option<ast::Module<'input>> = {
Version <v:Version> Target <f:Directive*> => v.map(|v| ast::Module { version: v, functions: f.into_iter().filter_map(identity).collect::<Vec<_>>() })
Target
Directive*
}; };
Version = { Version: Option<(u8, u8)> = {
".version" VersionNumber ".version" <v:VersionNumber> => {
}; let dot = v.find('.').unwrap();
let major = v[..dot].parse::<u8>();
major.ok().and_then(|major| {
v[dot+1..].parse::<u8>().ok().map(|minor| {
(major, minor)
})
})
}
}
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#ptx-module-directives-target // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#ptx-module-directives-target
Target = { Target = {
@ -38,19 +45,19 @@ TargetSpecifier = {
"map_f64_to_f32" "map_f64_to_f32"
}; };
Directive : () = { Directive: Option<ast::Function<'input>> = {
AddressSize, AddressSize => None,
Function, <f:Function> => Some(f),
File, File => None,
Section Section => None
}; };
AddressSize = { AddressSize = {
".address_size" Num ".address_size" Num
}; };
Function: (bool, &'input str) = { Function: ast::Function<'input> = {
LinkingDirective* <is:IsKernel> <id:ID> "(" Comma<FunctionInput> ")" FunctionBody => (is, id) LinkingDirective* <kernel:IsKernel> <name:ID> "(" <args:Comma<FunctionInput>> ")" <body:FunctionBody> => ast::Function {<>}
}; };
LinkingDirective = { LinkingDirective = {
@ -64,12 +71,12 @@ IsKernel: bool = {
".func" => false ".func" => false
}; };
FunctionInput = { FunctionInput: ast::Argument = {
".param" Type ID ".param" Type ID => ast::Argument {}
}; };
FunctionBody = { FunctionBody: Vec<ast::Statement<'input>> = {
"{" Statement* "}" "{" <s:Statement*> "}" => { s.into_iter().filter_map(identity).collect() }
}; };
StateSpaceSpecifier = { StateSpaceSpecifier = {
@ -95,14 +102,14 @@ BaseType = {
".f32", ".f64" ".f32", ".f64"
}; };
Statement: () = { Statement: Option<ast::Statement<'input>> = {
Label, <l:Label> => Some(ast::Statement::Label(l)),
DebugDirective, DebugDirective => None,
Variable ";", <v:Variable> ";" => Some(ast::Statement::Variable(v)),
Instruction ";" <i:Instruction> ";" => Some(ast::Statement::Instruction(i))
}; };
DebugDirective = { DebugDirective: () = {
DebugLocation DebugLocation
}; };
@ -111,12 +118,12 @@ DebugLocation = {
".loc" Num Num Num ".loc" Num Num Num
}; };
Label = { Label: &'input str = {
ID ":" <id:ID> ":" => id
}; };
Variable = { Variable: ast::Variable = {
StateSpaceSpecifier Type VariableName StateSpaceSpecifier Type VariableName => ast::Variable {}
}; };
VariableName = { VariableName = {
@ -124,7 +131,7 @@ VariableName = {
ParametrizedID ParametrizedID
}; };
Instruction: () = { Instruction = {
InstLd, InstLd,
InstMov, InstMov,
InstMul, InstMul,
@ -139,8 +146,8 @@ Instruction: () = {
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-ld // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-ld
InstLd = { InstLd: ast::Instruction = {
"ld" LdQualifier? LdStateSpace? LdCacheOperator? Vector? BaseType ID "," "[" ID "]" "ld" LdQualifier? LdStateSpace? LdCacheOperator? Vector? BaseType ID "," "[" ID "]" => ast::Instruction::Ld
}; };
LdQualifier: () = { LdQualifier: () = {
@ -171,8 +178,8 @@ LdCacheOperator = {
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov
InstMov = { InstMov: ast::Instruction = {
"mov" MovType ID "," Operand "mov" MovType ID "," Operand => ast::Instruction::Mov
}; };
MovType = { MovType = {
@ -186,12 +193,12 @@ MovType = {
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-mul // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-mul
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-mul // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-mul
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-mul // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-mul
InstMul: () = { InstMul: ast::Instruction = {
"mul" MulIntControl? IntType ID "," Operand "," Operand, "mul" MulIntControl? IntType ID "," Operand "," Operand => ast::Instruction::Mul,
"mul" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand, "mul" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand => ast::Instruction::Mul,
"mul" RoundingMode? ".f64" ID "," Operand "," Operand, "mul" RoundingMode? ".f64" ID "," Operand "," Operand => ast::Instruction::Mul,
"mul" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand, "mul" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand => ast::Instruction::Mul,
"mul" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand, "mul" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand => ast::Instruction::Mul,
}; };
MulIntControl = { MulIntControl = {
@ -211,19 +218,19 @@ IntType = {
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-add // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-add
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-add // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-add
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-add // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-add
InstAdd: () = { InstAdd: ast::Instruction = {
"add" IntType ID "," Operand "," Operand, "add" IntType ID "," Operand "," Operand => ast::Instruction::Add,
"add" ".sat" ".s32" ID "," Operand "," Operand, "add" ".sat" ".s32" ID "," Operand "," Operand => ast::Instruction::Add,
"add" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand, "add" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand => ast::Instruction::Add,
"add" RoundingMode? ".f64" ID "," Operand "," Operand, "add" RoundingMode? ".f64" ID "," Operand "," Operand => ast::Instruction::Add,
"add" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand, "add" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand => ast::Instruction::Add,
"add" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand, "add" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand => ast::Instruction::Add,
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-setp // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-setp
InstSetp: () = { InstSetp: ast::Instruction = {
"setp" SetpCmpOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand, "setp" SetpCmpOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand => ast::Instruction::Setp,
"setp" SetpCmpOp SetpBoolOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand "," "!"? ID "setp" SetpCmpOp SetpBoolOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand "," "!"? ID => ast::Instruction::Setp
}; };
SetpCmpOp = { SetpCmpOp = {
@ -243,8 +250,8 @@ SetpType = {
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-not // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-not
InstNot: () = { InstNot: ast::Instruction = {
"not" NotType ID "," Operand "not" NotType ID "," Operand => ast::Instruction::Not
}; };
NotType = { NotType = {
@ -252,18 +259,18 @@ NotType = {
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-at // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-at
InstAt = { InstAt: ast::Instruction = {
"@" "!"? ID "@" "!"? ID => ast::Instruction::At
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra
InstBra = { InstBra: ast::Instruction = {
InstAt? "bra" ".uni"? ID InstAt? "bra" ".uni"? ID => ast::Instruction::Bra
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvt // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvt
InstCvt = { InstCvt: ast::Instruction = {
"cvt" CvtRnd? ".ftz"? ".sat"? CvtType CvtType ID "," Operand "cvt" CvtRnd? ".ftz"? ".sat"? CvtType CvtType ID "," Operand => ast::Instruction::Cvt
}; };
CvtRnd = { CvtRnd = {
@ -286,8 +293,8 @@ CvtType = {
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shl // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shl
InstShl = { InstShl: ast::Instruction = {
"shl" ShlType ID "," Operand "," Operand "shl" ShlType ID "," Operand "," Operand => ast::Instruction::Shl
}; };
ShlType = { ShlType = {
@ -295,8 +302,8 @@ ShlType = {
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-st // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-st
InstSt = { InstSt: ast::Instruction = {
"st" LdQualifier? StStateSpace? StCacheOperator? Vector? BaseType "[" ID "]" "," Operand "st" LdQualifier? StStateSpace? StCacheOperator? Vector? BaseType "[" ID "]" "," Operand => ast::Instruction::Shl
}; };
StStateSpace = { StStateSpace = {
@ -314,8 +321,8 @@ StCacheOperator = {
}; };
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-ret // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-ret
InstRet: () = { InstRet: ast::Instruction = {
"ret" ".uni"? "ret" ".uni"? => ast::Instruction::Ret
}; };
Operand: () = { Operand: () = {
@ -384,7 +391,6 @@ Comma<T>: Vec<T> = {
String = r#""[^"]*""#; String = r#""[^"]*""#;
VersionNumber = r"[0-9]+\.[0-9]+"; VersionNumber = r"[0-9]+\.[0-9]+";
//Num: i128 = <s:r"[?:0x][0-9]+"> => i128::from_str(s).unwrap();
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#identifiers // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#identifiers
ID: &'input str = <s:r"[a-zA-Z][a-zA-Z0-9_$]*|[_$%][a-zA-Z0-9_$]+"> => s; ID: &'input str = <s:r"[a-zA-Z][a-zA-Z0-9_$]*|[_$%][a-zA-Z0-9_$]+"> => s;
DotID: &'input str = <s:r"\.[a-zA-Z][a-zA-Z0-9_$]*"> => s; DotID: &'input str = <s:r"\.[a-zA-Z][a-zA-Z0-9_$]*"> => s;

9
ptx/src/spirv.rs Normal file
View file

@ -0,0 +1,9 @@
use super::ast;
pub struct TranslateError {
}
pub fn translate(ast: ast::Module) -> Result<Vec<u32>, TranslateError> {
Ok(vec!())
}