Skip to content

Commit

Permalink
ptx: extract bison based ptx parser
Browse files Browse the repository at this point in the history
  • Loading branch information
romnn committed Apr 10, 2024
1 parent 60b7d66 commit a7d29ca
Show file tree
Hide file tree
Showing 100 changed files with 12,659 additions and 58 deletions.
8 changes: 8 additions & 0 deletions ptx/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@ pb2.5benchmarks.tgz
benchmarks/
cuda-samples-12.4/
cuda-samples-12.4.tar.gz

bison/bindings.rs

bison/src/ptx.lex.h
bison/src/ptx.parser.tab.h

bison/src/ptxinfo.lex.h
bison/src/ptxinfo.parser.tab.h
8 changes: 8 additions & 0 deletions ptx/bison/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ edition = "2021"
publish = false

[dependencies]
clap = { version = "4", features = [ "derive" ] }
color-eyre = "0"

[build-dependencies]
color-eyre = "0"
duct = "0"
bindgen = "0"
cc = { version = "1", features = [] }
21 changes: 21 additions & 0 deletions ptx/bison/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
### PTX reference bson parser

This is the bison and flex based PTX parser of AccelSim.

It has been extracted from AccelSim to allow for quick comparisons.

##### Build
**Note**: Please make sure you have a recent version of bison and flex installed.

```bash
cargo build -p ptxbison

# you can also specify a path to another bison version
BISON_PATH=/usr/local/Cellar/bison/3.8.2/bin/bison cargo build -p ptxbison
```

##### Usage

```bash
# todo
```
237 changes: 237 additions & 0 deletions ptx/bison/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
use color_eyre::eyre;
use std::path::PathBuf;

fn output_path() -> PathBuf {
PathBuf::from(std::env::var("OUT_DIR").unwrap())
.canonicalize()
.unwrap()
}

#[must_use]
fn is_debug() -> bool {
match std::env::var("PROFILE").unwrap().as_str() {
"release" | "bench" => false,
"debug" => true,
other => panic!("unknown profile {other:?}"),
}
}

fn enable_diagnostics_color(build: &mut cc::Build) {
if let "no" | "false" = std::env::var("FORCE_COLOR")
.unwrap_or_default()
.to_lowercase()
.as_str()
{
return;
}
// force colored diagnostics for all terminals
let compiler = build.get_compiler();
if compiler.is_like_clang() || compiler.is_like_gnu() {
build.flag("-fdiagnostics-color=always");
}
}


fn configure_debug_mode(build: &mut cc::Build) {
if is_debug() {
build.opt_level(0).debug(true).flag("-ggdb3");
} else {
build.opt_level(3).debug(true);
}
}

fn generate_bindings() -> eyre::Result<()> {
let builder = bindgen::Builder::default()
.clang_arg("-std=c++14")
// .clang_arg(format!("-I{}", include_dir.display()))
// .clang_args(flags.iter().map(|(k, v)| format!("-D{k}={v}")))
.rustified_enum(".*")
// .derive_partialeq(true)
// .derive_eq(true)
// .derive_partialord(true)
// .derive_ord(true)
// .prepend_enum_name(false)
// .size_t_is_usize(true)
// .generate_comments(true)
// .default_enum_style(bindgen::EnumVariation::Rust {
// non_exhaustive: false,
// })
// .parse_callbacks(Box::new(ParseCallbacks {}))
// .blocklist_type("std::.*")
// .blocklist_type("(::)?std::.*")
// .opaque_type("(::)?std::.*")
// .blocklist_type("mem_fetch")
// .opaque_type("mem_fetch")
// .blocklist_type("trace_shd_warp_t")
// .opaque_type("trace_shd_warp_t")
// for cache bridge
// .allowlist_type("cache_block_state")
// // for mem fetch
// .allowlist_type("mem_access_type")
// .allowlist_type("mem_fetch_status")
// .allowlist_type("mf_type")
// // for addr dec bridge
// .allowlist_type("addrdec_t")
// .allowlist_type("linear_to_raw_address_translation_params")
// // for core bridge
// .allowlist_type("pending_register_writes")
// // for main bridge
// .allowlist_type("accelsim_config")
// .allowlist_type("pipeline_stage_name_t")
// // for stats
// .allowlist_type("cache_request_status")
// .allowlist_type("cache_reservation_fail_reason")
// // for cache config tests
// .allowlist_type("cache_config_params")
// // for trace parser
// .allowlist_type("command_type")
// .allowlist_type("TraceEntry")
// // for config tests
// .allowlist_type("CacheConfig")
// .allowlist_function("parse_cache_config")
.header("src/lib.hpp");

let bindings = builder.generate()?;

bindings.write_to_file(output_path().join("bindings.rs"))?;
bindings.write_to_file("./bindings.rs")?;
Ok(())
}


fn build_ptx_parser() -> eyre::Result<()> {
let out_dir = output_path().join("generated");
std::fs::create_dir(&out_dir).ok();

let lex_input_files = [(PathBuf::from("./src/ptx.l"), out_dir.join("ptx.lex.h"), out_dir.join("ptx.lex.c")), (PathBuf::from("./src/ptxinfo.l"), out_dir.join("ptxinfo.lex.h"), out_dir.join("ptxinfo.lex.c"))];

for (lex_input_file, lex_output_header, lex_output_file) in &lex_input_files {
assert!(lex_input_file.is_file());
let args = [
format!("--header-file={}", lex_output_header.display()),
"-o".to_string(),
lex_output_file.to_string_lossy().to_string(),
lex_input_file.to_string_lossy().to_string(),
];
let flex_binary = std::env::var("FLEX_PATH").unwrap_or("flex".to_string());
let flex_cmd = duct::cmd(flex_binary, &args).unchecked();
let result = flex_cmd.run()?;
// println!("{}", String::from_utf8_lossy(&result.stdout));
// eprintln!("{}", String::from_utf8_lossy(&result.stderr));

if !result.status.success() {
eyre::bail!(
"command {:?} exited with code {:?}",
[&["flex".to_string()], args.as_slice()].concat(),
result.status.code()
);
}
}

let bison_input_files = [(PathBuf::from("./src/ptx.y"), out_dir.join("ptx.parser"), "ptx_"), (PathBuf::from("./src/ptxinfo.y"), out_dir.join("ptxinfo.parser"), "ptxinfo_")];

for (bison_input_file, bison_output_file, prefix) in &bison_input_files {
let args = [
// "-y".to_string(),
format!("--name-prefix={}", prefix),
"-d".to_string(),
bison_input_file.to_string_lossy().to_string(),
format!("--file-prefix={}", bison_output_file.display()),
"-Wno-yacc".to_string(),
];
dbg!(&args);
let bison_binary = std::env::var("BISON_PATH").unwrap_or("bison".to_string());
let bison_cmd = duct::cmd(bison_binary, &args).unchecked();
let result = bison_cmd.run()?;
// println!("{}", String::from_utf8_lossy(&result.stdout));
// eprintln!("{}", String::from_utf8_lossy(&result.stderr));

if !result.status.success() {
eyre::bail!(
"command {:?} exited with code {:?}",
[&["bison".to_string()], args.as_slice()].concat(),
result.status.code()
);
}
}

let source_dir = PathBuf::from("./src/");
// let generated_ptx_lexer = out_dir.join("ptx.lex.c");
// let generated_ptx_parser = out_dir.join("ptx.parser.tab.c");
let generated_files: Vec<_> = lex_input_files.iter()
.map(|(_, _, generated)| generated).cloned()
.chain(bison_input_files.iter()
.map(|(_, generated, _)| generated)
.map(|p| p.with_file_name(
format!("{}.tab.c", p.file_name().unwrap_or_default().to_string_lossy())
))).collect();

dbg!(&generated_files);
// vec![
// generated_ptx_lexer,
// generated_ptx_parser,
// ];
let sources = [generated_files.clone(), vec![
source_dir.join("util.cc"),
source_dir.join("gpgpu.cc"),
source_dir.join("gpgpu_sim.cc"),
source_dir.join("gpgpu_context.cc"),
source_dir.join("ptx_recognizer.cc"),
source_dir.join("ptx_stats.cc"),
source_dir.join("ptx_instruction.cc"),
source_dir.join("ptxinfo_data.cc"),
source_dir.join("symbol_table.cc"),
source_dir.join("function_info.cc"),
source_dir.join("type_info.cc"),
source_dir.join("cuda_sim.cc"),
source_dir.join("checkpoint.cc"),
source_dir.join("memory_space.cc"),
source_dir.join("operand_info.cc"),
source_dir.join("symbol.cc"),
source_dir.join("lib.cc"),
]].concat();
// let sources = vec![
// source_dir.join("memory_space.cc"),
// ];
// assert!(sources.iter().all(|s| s.is_file()));

if std::env::var("DUMP").unwrap_or_default().as_str() == "yes" {
// move to source dir
for (generated_path, file_name) in generated_files.iter().filter_map(|p| match p.file_name() {
Some(file_name) => Some((p, file_name)),
None => None
}) {
let src = generated_path.with_extension("h");
let dest = source_dir.join(file_name).with_extension("h");
println!("cargo:warning=copy {} to {}", src.display(), dest.display());
std::fs::copy(&src, &dest)?;
}
}

let mut build = cc::Build::new();
build
.cpp(true)
.pic(true)
.static_flag(true)
.warnings(false)
.flag("-Wno-everything")
.flag("-std=c++14")
.flag("-mmacosx-version-min=10.15")
.include(source_dir)
.files(sources);

enable_diagnostics_color(&mut build);
configure_debug_mode(&mut build);
build.try_compile("ptxparser")?;

Ok(())
}

fn main() -> eyre::Result<()> {
println!("cargo:rerun-if-changed=./build.rs");
println!("cargo:rerun-if-changed=./src");

build_ptx_parser()?;
generate_bindings()?;
Ok(())
}
17 changes: 17 additions & 0 deletions ptx/bison/src/address.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <bitset>

typedef unsigned long long new_addr_type;
typedef unsigned long long address_type;
typedef unsigned long long addr_t;
typedef address_type mem_addr_t;

const unsigned MAX_WARP_SIZE = 32;
typedef std::bitset<MAX_WARP_SIZE> active_mask_t;

const unsigned MAX_MEMORY_ACCESS_SIZE = 128;
typedef std::bitset<MAX_MEMORY_ACCESS_SIZE> mem_access_byte_mask_t;
const unsigned SECTOR_CHUNCK_SIZE = 4; // four sectors
const unsigned SECTOR_SIZE = 32; // sector is 32 bytes width
typedef std::bitset<SECTOR_CHUNCK_SIZE> mem_access_sector_mask_t;
45 changes: 45 additions & 0 deletions ptx/bison/src/basic_block.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <set>

class ptx_instruction;

extern const char *g_opcode_string[];

struct basic_block_t {
basic_block_t(unsigned ID, ptx_instruction *begin, ptx_instruction *end,
bool entry, bool ex) {
bb_id = ID;
ptx_begin = begin;
ptx_end = end;
is_entry = entry;
is_exit = ex;
immediatepostdominator_id = -1;
immediatedominator_id = -1;
}

ptx_instruction *ptx_begin;
ptx_instruction *ptx_end;
// indices of other basic blocks in m_basic_blocks array
std::set<int> predecessor_ids;
std::set<int> successor_ids;
std::set<int> postdominator_ids;
std::set<int> dominator_ids;
std::set<int> Tmp_ids;
int immediatepostdominator_id;
int immediatedominator_id;
bool is_entry;
bool is_exit;
unsigned bb_id;

// if this basic block dom B
bool dom(const basic_block_t *B) {
return (B->dominator_ids.find(this->bb_id) != B->dominator_ids.end());
}

// if this basic block pdom B
bool pdom(const basic_block_t *B) {
return (B->postdominator_ids.find(this->bb_id) !=
B->postdominator_ids.end());
}
};
24 changes: 0 additions & 24 deletions ptx/bison/src/build.rs

This file was deleted.

Loading

0 comments on commit a7d29ca

Please sign in to comment.