Skip to content

Commit

Permalink
Backend for listing instantiations of primitives (#1860)
Browse files Browse the repository at this point in the history
* First pass for backend to produce json file containing primitive instantiation info

* pretty print the json

* Map from param names to values

* Fix clippy error

* usage message

* Fix doc comments

* Change JSON format for parameter names and values

* Fix formatting error

* Changed naming and fixed unchanged name

* Make parameter collection functional

* Make fixes from PR comments
  • Loading branch information
ayakayorihiro authored and rachitnigam committed Feb 16, 2024
1 parent 1992a46 commit f478b49
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 2 deletions.
3 changes: 3 additions & 0 deletions calyx-backend/src/backend_opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub enum BackendOpt {
Sexp,
Yxi,
Firrtl,
PrimitiveUses,
None,
}

Expand All @@ -30,6 +31,7 @@ fn backends() -> Vec<(&'static str, BackendOpt)> {
("sexp", BackendOpt::Sexp),
("yxi", BackendOpt::Yxi),
("firrtl", BackendOpt::Firrtl),
("primitive-uses", BackendOpt::PrimitiveUses),
("none", BackendOpt::None),
]
}
Expand Down Expand Up @@ -74,6 +76,7 @@ impl ToString for BackendOpt {
Self::Yxi => "yxi",
Self::Calyx => "calyx",
Self::Firrtl => "firrtl",
Self::PrimitiveUses => "primitive-uses",
Self::None => "none",
}
.to_string()
Expand Down
2 changes: 2 additions & 0 deletions calyx-backend/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//! Backends for the Calyx compiler.
mod backend_opt;
mod firrtl;
mod primitive_uses;
mod traits;
mod verilog;
mod yxi;

pub use backend_opt::BackendOpt;
pub use firrtl::FirrtlBackend;
pub use primitive_uses::PrimitiveUsesBackend;
pub use traits::Backend;
pub use verilog::VerilogBackend;
pub use yxi::YxiBackend;
Expand Down
110 changes: 110 additions & 0 deletions calyx-backend/src/primitive_uses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//! Primitive instantiations backend for the Calyx compiler.
//!
//! Transforms an [`ir::Context`](crate::ir::Context) into a JSON file that
//! records the unique primitive instantiations in a program.
//! Usage: -b primitive-inst [-o <OUTPUT_FILE>]
//! Adapted from resources.rs.
use std::{collections::HashSet, io};

use crate::traits::Backend;
use calyx_ir as ir;
use calyx_utils::{CalyxResult, OutputFile};
use serde::{Deserialize, Serialize};

#[derive(Default)]
pub struct PrimitiveUsesBackend;

impl Backend for PrimitiveUsesBackend {
fn name(&self) -> &'static str {
"primitive_uses"
}

/// OK to run this analysis on any Calyx program
fn validate(_ctx: &ir::Context) -> CalyxResult<()> {
Ok(())
}

/// Don't need to take care of this for this pass
fn link_externs(
_ctx: &ir::Context,
_file: &mut OutputFile,
) -> CalyxResult<()> {
Ok(())
}

fn emit(ctx: &ir::Context, file: &mut OutputFile) -> CalyxResult<()> {
let main_comp = ctx.entrypoint();

let mut primitive_set: HashSet<PrimitiveUse> = HashSet::new();

gen_primitive_set(ctx, main_comp, &mut primitive_set);

write_json(primitive_set.clone(), file)?;

Ok(())
}
}

#[derive(PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
struct PrimitiveUse {
name: String,
params: Vec<PrimitiveParam>,
}

#[derive(PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
struct PrimitiveParam {
param_name: String,
param_value: u64,
}

/// Accumulates a set with each primitive with a given set of parameters
/// in the program with entrypoint `main_comp`.
fn gen_primitive_set(
ctx: &ir::Context,
main_comp: &ir::Component,
primitive_set: &mut HashSet<PrimitiveUse>,
) {
for cell in main_comp.cells.iter() {
let cell_ref = cell.borrow();
match &cell_ref.prototype {
ir::CellType::Primitive {
name,
param_binding,
..
} => {
let curr_params = param_binding
.iter()
.map(|(param_name, param_size)| PrimitiveParam {
param_name: param_name.to_string(),
param_value: *param_size,
})
.collect();
let curr_primitive = PrimitiveUse {
name: name.to_string(),
params: curr_params,
};
(*primitive_set).insert(curr_primitive);
}
ir::CellType::Component { name } => {
let component = ctx
.components
.iter()
.find(|comp| comp.name == name)
.unwrap();
gen_primitive_set(ctx, component, primitive_set);
}
_ => (),
}
}
}

/// Write the collected set of primitive instantiations to a JSON file.
fn write_json(
primitive_set: HashSet<PrimitiveUse>,
file: &mut OutputFile,
) -> Result<(), io::Error> {
let created_vec: Vec<PrimitiveUse> = primitive_set.into_iter().collect();
serde_json::to_writer_pretty(file.get_write(), &created_vec)?;
Ok(())
}
8 changes: 6 additions & 2 deletions src/cmdline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use argh::FromArgs;
use calyx_backend::SexpBackend;
use calyx_backend::{
xilinx::{XilinxInterfaceBackend, XilinxXmlBackend},
Backend, BackendOpt, FirrtlBackend, MlirBackend, ResourcesBackend,
VerilogBackend, YxiBackend,
Backend, BackendOpt, FirrtlBackend, MlirBackend, PrimitiveUsesBackend,
ResourcesBackend, VerilogBackend, YxiBackend,
};
use calyx_ir as ir;
use calyx_utils::{CalyxResult, Error, OutputFile};
Expand Down Expand Up @@ -170,6 +170,10 @@ impl Opts {
let backend = FirrtlBackend;
backend.run(context, self.output)
}
BackendOpt::PrimitiveUses => {
let backend = PrimitiveUsesBackend;
backend.run(context, self.output)
}
BackendOpt::Calyx => {
ir::Printer::write_context(
&context,
Expand Down

0 comments on commit f478b49

Please sign in to comment.