1pub(crate) use std::collections::BTreeMap;
2
3mod compiler;
4mod error;
5pub(crate) mod generate;
6pub mod manifest;
7mod package;
8
9pub use compiler::Compiler;
10pub use error::Error;
11pub use generate::{Config, Generate, OCaml, Rust};
12pub use manifest::Manifest;
13pub use package::Package;
14
15#[derive(Debug, serde::Deserialize, PartialEq, Eq, Clone, Copy)]
17pub enum Backend {
18 #[serde(rename = "c")]
22 C,
23
24 #[serde(rename = "cuda")]
28 CUDA,
29
30 #[serde(rename = "opencl")]
34 OpenCL,
35
36 #[serde(rename = "multicore")]
40 Multicore,
41
42 #[serde(rename = "ispc")]
47 ISPC,
48
49 #[serde(rename = "hip")]
53 HIP,
54}
55
56impl Backend {
57 pub fn to_str(&self) -> &'static str {
59 match self {
60 Backend::C => "c",
61 Backend::CUDA => "cuda",
62 Backend::OpenCL => "opencl",
63 Backend::Multicore => "multicore",
64 Backend::ISPC => "ispc",
65 Backend::HIP => "hip",
66 }
67 }
68
69 pub fn from_name(name: &str) -> Option<Backend> {
71 match name.to_ascii_lowercase().as_str() {
72 "c" => Some(Backend::C),
73 "cuda" => Some(Backend::CUDA),
74 "opencl" => Some(Backend::OpenCL),
75 "multicore" => Some(Backend::Multicore),
76 "ispc" => Some(Backend::ISPC),
77 _ => None,
78 }
79 }
80
81 pub fn from_env() -> Option<Backend> {
83 match std::env::var("FUTHARK_BACKEND") {
84 Ok(name) => Backend::from_name(&name),
85 Err(_) => None,
86 }
87 }
88
89 pub fn required_c_libs(&self) -> &'static [&'static str] {
91 match self {
92 Backend::CUDA => &["cuda", "cudart", "nvrtc", "m"],
93 Backend::OpenCL => &["OpenCL", "m"],
94 Backend::Multicore | Backend::ISPC => &["pthread", "m"],
95 Backend::HIP => &["hiprtc", "amdhip64"],
96 _ => &[],
97 }
98 }
99}
100
101#[cfg(feature = "build")]
102pub fn build(
111 backend: Backend,
112 src: impl AsRef<std::path::Path>,
113 dest: impl AsRef<std::path::Path>,
114) {
115 let out = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
116 let dest = std::path::PathBuf::from(&out).join(dest);
117 let lib = Compiler::new(backend, src)
118 .with_output_dir(out)
119 .compile()
120 .expect("Compilation failed");
121
122 let mut config = Config::new(&dest).expect("Unable to configure codegen");
123 let mut gen = config.detect().expect("Invalid output language");
124 gen.generate(&lib, &mut config)
125 .expect("Code generation failed");
126 lib.link();
127}