Skip to content

Commit

Permalink
feat/computation: add basic design for backend-agnostic computation
Browse files Browse the repository at this point in the history
Pull request: #2
Approved by: MichaelHirn
  • Loading branch information
MichaelHirn authored and homu committed Nov 27, 2015
1 parent f5fd023 commit e43f947
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 29 deletions.
25 changes: 25 additions & 0 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@

use framework::{IFramework, FrameworkError};
use device::IDevice;
use libraries::blas::IBlas;
use frameworks::{Native, OpenCL};
use operation::IOperation;
use std::collections::HashMap;

#[derive(Debug, Clone)]
/// Defines the main and highest struct of Collenchyma.
Expand Down Expand Up @@ -87,6 +91,27 @@ impl<F: IFramework + Clone> Backend<F> {
pub fn device(&self) -> F::D {
self.device.clone()
}

/// Returns the blas binary.
pub fn binary(&self) -> F::B {
self.framework().binary().clone()
}
}

impl IBlas for Backend<OpenCL> {
type B = ::frameworks::opencl::Program;

fn binary(&self) -> Self::B {
self.binary()
}
}

impl IBlas for Backend<Native> {
type B = ::frameworks::native::Binary;

fn binary(&self) -> Self::B {
self.binary()
}
}

#[derive(Debug, Clone)]
Expand Down
14 changes: 5 additions & 9 deletions src/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,9 @@ use std::collections::HashMap;

/// Defines the functionality for turning a library into backend-specific, executable operations.
pub trait IBinary {
/// The Operation representation for this Binary.
type O: IOperation;
/// The Library representation for this Binary.
type L: ILibrary;
/// Returns the unique identifier of the Binary.
fn id(&self) -> isize;
/// Creates a HashMap of available, ready-to-use operations, based on the provided library and
/// tailored for a framework.
fn create_operations() -> HashMap<String, Self::O>;
// Returns the unique identifier of the Binary.
//fn id(&self) -> isize;
// Creates a HashMap of available, ready-to-use operations, based on the provided library and
// tailored for a framework.
//fn create_operations();
}
1 change: 1 addition & 0 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use hardware::IHardware;
use memory::{IMemory, MemoryType};
use operation::IOperation;
use std::hash::{Hash, Hasher};
use frameworks::native::device::Cpu;
use frameworks::opencl::context::Context;
Expand Down
6 changes: 6 additions & 0 deletions src/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

use hardware::IHardware;
use device::IDevice;
use binary::IBinary;
use frameworks::opencl::Error as OpenCLError;
use std::error;
use std::fmt;
Expand All @@ -30,6 +31,8 @@ pub trait IFramework {
type H: IHardware;
/// The Device representation for this Framework.
type D: IDevice + Clone;
/// The Binary representation for this Framework.
type B: IBinary + Clone;

/// Defines the Framework by a Name.
///
Expand All @@ -48,6 +51,9 @@ pub trait IFramework {
/// Returns the cached and available hardwares.
fn hardwares(&self) -> Vec<Self::H>;

/// Returns the initialized binary.
fn binary(&self) -> Self::B;

/// Initializes a new Device from the provided hardwares.
fn new_device(&self, Vec<Self::H>) -> Result<Self::D, FrameworkError>;
}
Expand Down
24 changes: 24 additions & 0 deletions src/frameworks/native/binary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//! Provides a binary on native CPU.

use binary::IBinary;
use frameworks::native::Function;

#[derive(Debug, Copy, Clone)]
/// Defines a host CPU binary.
pub struct Binary {
id: isize,
/// The initialized Blas Dot Operation.
pub blas_dot: Function,
}

impl Binary {
/// Initializes a native CPU hardware.
pub fn new(id: isize) -> Binary {
Binary {
id: id,
blas_dot: Function::new(1)
}
}
}

impl IBinary for Binary {}
20 changes: 20 additions & 0 deletions src/frameworks/native/function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Provides a operation on native CPU.

use hardware::{IHardware, HardwareType};
use operation::IOperation;
use shared_memory::SharedMemory;

#[derive(Debug, Copy, Clone)]
/// Defines a host CPU operation.
pub struct Function {
id: isize,
}

impl Function {
/// Initializes a native CPU hardware.
pub fn new(id: isize) -> Function {
Function { id: id }
}
}

impl IOperation for Function {}
20 changes: 20 additions & 0 deletions src/frameworks/native/libraries/blas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Provides BLAS for a Native backend.

use frameworks::Native;
use frameworks::native::{Function, Binary};
use binary::IBinary;
use libraries::blas::*;

impl IBlasBinary for Binary {
type Dot = Function;

fn dot(&self) -> Self::Dot {
self.blas_dot
}
}

impl IOperationDot for Function {
fn compute(&self, a: i32) {
println!("{}", format!("NATIVE"))
}
}
3 changes: 3 additions & 0 deletions src/frameworks/native/libraries/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Provides support for various libraries for a Native backend.

mod blas;
19 changes: 17 additions & 2 deletions src/frameworks/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@ use hardware::{HardwareType, IHardware};
use device::IDevice;
use self::hardware::Hardware;
pub use self::device::Cpu;
pub use self::function::Function;
pub use self::binary::Binary;

pub mod device;
pub mod flatbox;
pub mod hardware;
pub mod function;
pub mod libraries;
pub mod binary;

#[derive(Debug, Clone)]
/// Provides the Native framework.
///
/// Native means host CPU only. The setup one relies on by default.
pub struct Native {
hardwares: Vec<Hardware>
hardwares: Vec<Hardware>,
binary: Binary,
}

/// Provides the Native framework trait for explicit Backend behaviour.
Expand All @@ -32,11 +38,16 @@ impl INative for Native {}
impl IFramework for Native {
type H = Hardware;
type D = Cpu;
type B = Binary;

const ID: &'static str = "NATIVE";

fn new() -> Native {
match Native::load_hardwares() {
Ok(hardwares) => Native { hardwares: hardwares },
Ok(hardwares) => Native {
hardwares: hardwares,
binary: Binary::new(1)
},
Err(err) => panic!(err)
}
}
Expand All @@ -54,6 +65,10 @@ impl IFramework for Native {
self.hardwares.clone()
}

fn binary(&self) -> Binary {
self.binary.clone()
}

fn new_device(&self, devices: Vec<Hardware>) -> Result<Cpu, FrameworkError> {
Ok(Cpu::new(devices.to_vec()))
}
Expand Down
8 changes: 2 additions & 6 deletions src/frameworks/opencl/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use frameworks::opencl::OpenCL;
use super::api::types as cl;
use super::api::API;

#[derive(Debug, Clone)]
#[derive(Debug, Copy, Clone)]
/// Defines a OpenCL Kernel.
///
/// A Kernel is OpenCL's version of Collenchyma's [operation][operation].
Expand All @@ -31,8 +31,4 @@ impl Kernel {
}
}

impl IOperation for Kernel {
fn id(&self) -> isize {
self.id
}
}
impl IOperation for Kernel {}
21 changes: 21 additions & 0 deletions src/frameworks/opencl/libraries/blas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! Provides BLAS for a OpenCL backend.

use frameworks::OpenCL;
use frameworks::opencl::Kernel;
use frameworks::opencl::Program;
use binary::IBinary;
use libraries::blas::*;

impl IBlasBinary for Program {
type Dot = Kernel;

fn dot(&self) -> Self::Dot {
self.blas_dot
}
}

impl IOperationDot for Kernel {
fn compute(&self, a: i32) {
println!("{}", format!("OPENCL"))
}
}
3 changes: 3 additions & 0 deletions src/frameworks/opencl/libraries/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Provides support for various libraries for a OpenCL backend.

mod blas;
12 changes: 12 additions & 0 deletions src/frameworks/opencl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub use self::platform::Platform;
pub use self::context::Context;
pub use self::memory::Memory;
pub use self::queue::Queue;
pub use self::kernel::Kernel;
pub use self::program::Program;
pub use self::device::{Device, DeviceInfo};
pub use self::api::{API, Error};
use self::api::types as cl;
Expand All @@ -26,12 +28,16 @@ pub mod platform;
pub mod context;
pub mod memory;
pub mod queue;
pub mod kernel;
pub mod program;
pub mod libraries;
mod api;

#[derive(Debug, Clone)]
/// Provides the OpenCL Framework.
pub struct OpenCL {
hardwares: Vec<Device>,
binary: Program,
}

/// Provides the OpenCL framework trait for explicit Backend behaviour.
Expand All @@ -44,13 +50,15 @@ impl IOpenCL for OpenCL {}
impl IFramework for OpenCL {
type H = Device;
type D = Context;
type B = Program;
const ID: &'static str = "OPENCL";

fn new() -> OpenCL {
match OpenCL::load_hardwares() {
Ok(hardwares) => {
OpenCL {
hardwares: hardwares,
binary: Program::from_isize(1)
}
},
Err(err) => panic!(err)
Expand All @@ -77,6 +85,10 @@ impl IFramework for OpenCL {
self.hardwares.clone()
}

fn binary(&self) -> Self::B {
self.binary.clone()
}

/// Creates a new OpenCL context over one or many devices ready for computation.
///
/// Contexts are used by the OpenCL runtime for managing objects such as command-queues,
Expand Down
42 changes: 42 additions & 0 deletions src/frameworks/opencl/program.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//! Provides a Rust wrapper around OpenCL's Program.

use binary::IBinary;
use frameworks::opencl::{OpenCL, Kernel};
use super::api::types as cl;
use super::api::API;

#[derive(Debug, Copy, Clone)]
/// Defines a OpenCL Program.
///
/// A Program is OpenCL's version of Collenchyma's [binary][binary].
/// [binary]: ../../binary/index.html
pub struct Program {
id: isize,
/// The initialized BLAS dot Operation.
pub blas_dot: Kernel
}

impl Program {
/// Initializes a new OpenCL device.
pub fn from_isize(id: isize) -> Program {
Program {
id: id,
blas_dot: Kernel::from_isize(1)
}
}

/// Initializes a new OpenCL device from its C type.
pub fn from_c(id: cl::kernel_id) -> Program {
unsafe { Program {
id: id as isize,
blas_dot: Kernel::from_isize(1)
} }
}

/// Returns the id as its C type.
pub fn id_c(&self) -> cl::kernel_id {
self.id as cl::kernel_id
}
}

impl IBinary for Program {}
Loading

0 comments on commit e43f947

Please sign in to comment.