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

Various suggestions for changes and improvements. #35

Merged
merged 17 commits into from
Jan 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/codegen.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//! Binary to generate the matmul library

extern crate genfut;
use genfut::{genfut, Opt, Backend};
use genfut::{genfut, Backend, Opt};

fn main() {
genfut(Opt {
name: "matmul".to_string(),
file: std::path::PathBuf::from("matmul.fut"),
author: "Name <[email protected]>".to_string(),
version: "0.1.0".to_string(),
license: "YOLO".to_string(),
license: "MIT".to_string(),
description: "Futhark matrix multiplication example".to_string(),
backend: Backend::SequentialC,
backend: Backend::C,
})
}
1 change: 0 additions & 1 deletion examples/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Example of how to use the built matmul library

use matmul::{Array_i32_2d, Error, FutharkContext};

fn main() -> Result<(), Error> {
Expand Down
5 changes: 2 additions & 3 deletions src/arrays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,8 @@ pub(crate) fn gen_impl_futhark_types(input: &Vec<String>) -> String {
let mut buffer2 = String::new();
writeln!(&mut buffer, "use crate::bindings::*;").expect("Write failed!");
for t in input {
println!("{}", t);
writeln!(&mut buffer, "{}", gen_impl_futhark_type(&t)).expect("Write failed!");
writeln!(&mut buffer2, "{}", gen_specific_type(&t)).expect("Write failed!");
writeln!(&mut buffer, "{}", gen_impl_futhark_type(t)).expect("Write failed!");
writeln!(&mut buffer2, "{}", gen_specific_type(t)).expect("Write failed!");
}
writeln!(&mut buffer, "{}", buffer2).expect("Write failed!");
buffer
Expand Down
25 changes: 11 additions & 14 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::fmt::Write;
use inflector::Inflector;
use regex::Regex;

fn type_translation(input: String) -> String {
fn type_translation(input: &str) -> String {
if input.starts_with("futhark") {
format!("{}", auto_ctor(&input))
auto_ctor(&input)
} else {
let mut buffer = String::new();
if input.starts_with("int8") {
Expand Down Expand Up @@ -66,7 +66,7 @@ pub(crate) fn gen_entry_point(input: &str) -> (String, String, Vec<String>) {
write!(&mut buffer, "(&mut self, ");
for (i, (argtype, argname)) in arg_pairs.iter().enumerate() {
if argname.starts_with("in") {
let argtype_string = type_translation(String::from(argtype.clone()));
let argtype_string = type_translation(argtype.clone());
write!(
&mut buffer,
"{}: {}{}, ",
Expand All @@ -89,11 +89,7 @@ pub(crate) fn gen_entry_point(input: &str) -> (String, String, Vec<String>) {
write!(&mut output_buffer, ", ");
}
output_counter += 1;
write!(
&mut output_buffer,
"{}",
type_translation(String::from(argtype.clone()))
);
write!(&mut output_buffer, "{}", type_translation(argtype.clone()));
}
}
write!(&mut output_buffer, ")>");
Expand Down Expand Up @@ -131,7 +127,7 @@ pub(crate) fn gen_entry_point(input: &str) -> (String, String, Vec<String>) {
&mut buffer2,
"{}: {}, ",
argname,
type_translation(String::from(argtype.clone()))
type_translation(argtype.clone())
);
}
}
Expand All @@ -150,7 +146,7 @@ pub(crate) fn gen_entry_point(input: &str) -> (String, String, Vec<String>) {
&mut buffer2,
"let mut raw_{} = {}::default();",
argname,
type_translation(String::from(argtype.clone()))
type_translation(argtype.clone())
);
}
}
Expand Down Expand Up @@ -183,7 +179,7 @@ return Err(FutharkError::new(ctx).into());}}"
write!(&mut buffer2, "Ok((");
for (i, (argtype, argname)) in arg_pairs.iter().enumerate() {
if argname.starts_with("out") {
if !parse_array_type(argtype).is_some() {
if parse_array_type(argtype).is_none() {
opaque_types.push(argtype.clone());
}
if result_counter > 0 {
Expand All @@ -194,7 +190,7 @@ return Err(FutharkError::new(ctx).into());}}"
writeln!(
&mut buffer2,
"{}::from_ptr(ctx, raw_{})",
auto_ctor(&argtype),
auto_ctor(argtype),
argname
);
} else {
Expand All @@ -219,10 +215,11 @@ fn gen_opaque_type(opaque_type: &str) -> String {
let rust_opaque_type = to_opaque_type_name(opaque_type);
assert!(opaque_type.starts_with("futhark_"),);
let base_type = &opaque_type[8..];
let bindings = format!("bindings::{}", opaque_type);
format!(
include_str!("static/static_opaque_types.rs"),
opaque_type = rust_opaque_type,
futhark_type = format!("bindings::{}", opaque_type),
futhark_type = bindings,
base_type = base_type
)
}
Expand All @@ -235,7 +232,7 @@ pub(crate) fn gen_entry_points(input: &Vec<String>) -> String {
let mut opaque_types = Vec::new();
let mut buffer2 = String::new();
for t in input {
let (a, b, otypes) = gen_entry_point(&t);
let (a, b, otypes) = gen_entry_point(t);
opaque_types.extend(otypes);
writeln!(&mut buffer, "{}", a).expect("Write failed!");
writeln!(&mut buffer2, "{}", b).expect("Write failed!");
Expand Down
132 changes: 20 additions & 112 deletions src/genc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::panic;
use std::fs::create_dir_all;
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::Command;
use std::str::FromStr;
Expand All @@ -8,10 +8,9 @@ use std::str::FromStr;
pub enum Backend {
Cuda,
ISPC,
MulticoreC,
None,
Erk- marked this conversation as resolved.
Show resolved Hide resolved
Multicore,
OpenCL,
SequentialC,
C,
}

impl FromStr for Backend {
Expand All @@ -23,11 +22,10 @@ impl FromStr for Backend {
match s.trim() {
"cuda" => Ok(Backend::Cuda),
"ispc" => Ok(Backend::ISPC),
"multicore_c" => Ok(Backend::MulticoreC),
"none" => Ok(Backend::None),
"multicore" => Ok(Backend::Multicore),
"opencl" => Ok(Backend::OpenCL),
"sequential_c" => Ok(Backend::SequentialC),
_ => Err("Unknown backend, availible backends are: cuda, ispc, multicore_c, none, opencl, sequential_c.".to_owned()),
"c" => Ok(Backend::C),
_ => Err("Unknown backend, availible backends are: cuda, ispc, multicore (written in in c), none, opencl, c (sequential).".to_owned()),
}
}
}
Expand All @@ -37,78 +35,22 @@ impl Backend {
match self {
Backend::Cuda => "cuda",
Backend::ISPC => "ispc",
Backend::MulticoreC => "multicore_c",
Backend::None => "none",
Backend::Multicore => "multicore",
Backend::OpenCL => "opencl",
Backend::SequentialC => "sequential_c",
Backend::C => "c",
}
}
}

pub(crate) fn gen_c(backend: Backend, in_file: &std::path::Path, out_dir: &std::path::Path) {
match backend {
Backend::Cuda => cuda_gen_c(in_file, out_dir),
Backend::ISPC => ispc_gen_c(in_file, out_dir),
Backend::MulticoreC => multicore_gen_c(in_file, out_dir),
Backend::None => { /* Intentionally left empty */ },
Backend::OpenCL => opencl_gen_c(in_file, out_dir),
Backend::SequentialC => seq_gen_c(in_file, out_dir),
}
}

fn seq_gen_c(in_file: &std::path::Path, out_dir: &std::path::Path) {
let out_path = PathBuf::from(out_dir);
let lib_dir = out_path.join("lib");
if let Err(e) = create_dir_all(lib_dir.clone()) {
eprintln!("Error creating {} ({})", lib_dir.display(), e);
std::process::exit(1);
}
let output = Command::new("futhark")
.arg("c")
.arg("--library")
.arg("-o")
.arg(format!(
"{}/lib/a",
out_dir.to_str().expect("[gen_c] out_dir failed!")
))
.arg(in_file)
.output()
.expect("[gen_c] failed to execute process");
io::stdout().write_all(&output.stdout).unwrap();
io::stderr().write_all(&output.stderr).unwrap();
}

fn multicore_gen_c(in_file: &std::path::Path, out_dir: &std::path::Path) {
let out_path = PathBuf::from(out_dir);
let lib_dir = out_path.join("lib");
if let Err(e) = create_dir_all(lib_dir.clone()) {
eprintln!("Error creating {} ({})", lib_dir.display(), e);
std::process::exit(1);
}
let output = Command::new("futhark")
.arg("multicore")
.arg("--library")
.arg("-o")
.arg(format!(
"{}/lib/a",
out_dir.to_str().expect("[gen_c] out_dir failed!")
))
.arg(in_file)
.output()
.expect("[gen_c] failed to execute process");
io::stdout().write_all(&output.stdout).unwrap();
io::stderr().write_all(&output.stderr).unwrap();
}

fn ispc_gen_c(in_file: &std::path::Path, out_dir: &std::path::Path) {
let out_path = PathBuf::from(out_dir);
let lib_dir = out_path.join("lib");
if let Err(e) = create_dir_all(lib_dir.clone()) {
eprintln!("Error creating {} ({})", lib_dir.display(), e);
std::process::exit(1);
}
let output = Command::new("futhark")
.arg("ispc")
.arg(backend.to_feature())
.arg("--library")
.arg("-o")
.arg(format!(
Expand All @@ -118,52 +60,18 @@ fn ispc_gen_c(in_file: &std::path::Path, out_dir: &std::path::Path) {
.arg(in_file)
.output()
.expect("[gen_c] failed to execute process");
io::stdout().write_all(&output.stdout).unwrap();
io::stderr().write_all(&output.stderr).unwrap();
}

fn cuda_gen_c(in_file: &std::path::Path, out_dir: &std::path::Path) {
let out_path = PathBuf::from(out_dir);
let lib_dir = out_path.join("lib");
if let Err(e) = create_dir_all(lib_dir.clone()) {
eprintln!("Error creating {} ({})", lib_dir.display(), e);
std::process::exit(1);
}
let output = Command::new("futhark")
.arg("cuda")
.arg("--library")
.arg("-o")
.arg(format!(
"{}/lib/a",
out_dir.to_str().expect("[gen_c] out_dir failed!")
))
.arg(in_file)
.output()
.expect("failed to execute process");
io::stdout().write_all(&output.stdout).unwrap();
io::stderr().write_all(&output.stderr).unwrap();
}

fn opencl_gen_c(in_file: &std::path::Path, out_dir: &std::path::Path) {
let out_path = PathBuf::from(out_dir);
let lib_dir = out_path.join("lib");
if let Err(e) = create_dir_all(lib_dir.clone()) {
eprintln!("Error creating {} ({})", lib_dir.display(), e);
std::process::exit(1);
if !output.status.success() {
println!(
"Futhark stdout: {}",
String::from_utf8(output.stdout).unwrap()
);
eprintln!(
"Futhark stderr: {}",
String::from_utf8(output.stderr).unwrap()
);
println!("Futhark status: {}", output.status);
panic!("Futhark did not run successfully.")
}
let output = Command::new("futhark")
.arg("opencl")
.arg("--library")
.arg("-o")
.arg(format!(
"{}/lib/a",
out_dir.to_str().expect("[gen_c] out_dir failed!")
))
.arg(in_file)
.output()
.expect("failed to execute process");
io::stdout().write_all(&output.stdout).unwrap();
io::stderr().write_all(&output.stderr).unwrap();
}

pub(crate) fn generate_bindings(header: &std::path::Path, out: &std::path::Path) {
Expand Down
15 changes: 4 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@
//!}
//!
//!```

#![allow(unused_must_use)]
#![allow(unused_variables)]

use clap::Parser;
use std::fs::create_dir_all;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use clap::Parser;

use regex::Regex;

Expand All @@ -46,8 +45,8 @@ mod entry;
mod genc;
use crate::arrays::gen_impl_futhark_types;
use crate::entry::*;
use crate::genc::{gen_c, generate_bindings};
pub use crate::genc::Backend;
use crate::genc::{gen_c, generate_bindings};

#[derive(Parser, Debug)]
#[clap(author, version, about)]
Expand Down Expand Up @@ -81,11 +80,7 @@ pub struct Opt {
pub description: String,

/// Backend
#[clap(
long,
name = "BACKEND",
default_value = "sequential_c",
)]
#[clap(long, name = "BACKEND", default_value = "c")]
pub backend: Backend,
}

Expand All @@ -104,8 +99,6 @@ pub fn genfut(opt: Opt) {
#[cfg(not(feature = "no_futhark"))]
{
let mut futhark_cmd = Command::new("futhark");
futhark_cmd.arg("pkg").arg("sync");
let _ = futhark_cmd.output().expect("failed: futhark pkg sync");

let version_path = PathBuf::from(&out_dir).join("futhark-version.txt");
let mut version_file =
Expand All @@ -119,7 +112,7 @@ pub fn genfut(opt: Opt) {

// Generate C code, Though only headerfiles are needed.
// In general C files are generated when build at the user.
gen_c(opt.backend, &futhark_file, &out_dir);
gen_c(opt.backend, futhark_file, out_dir);

// copy futhark file
if let Err(e) = std::fs::copy(futhark_file, PathBuf::from(out_dir).join("lib/a.fut")) {
Expand Down
Loading