extern crate random;
extern crate tensorflow;
use std::error::Error;
use std::result::Result;
use tensorflow::expr::{Compiler, Placeholder};
use tensorflow::Code;
use tensorflow::Graph;
use tensorflow::Session;
use tensorflow::SessionOptions;
use tensorflow::SessionRunArgs;
use tensorflow::Status;
use tensorflow::Tensor;
#[cfg_attr(feature = "examples_system_alloc", global_allocator)]
#[cfg(feature = "examples_system_alloc")]
static ALLOCATOR: std::alloc::System = std::alloc::System;
struct Checker {
success: bool,
epsilon: f32,
}
impl Checker {
fn new(epsilon: f32) -> Self {
Checker {
success: true,
epsilon: epsilon,
}
}
fn check(&mut self, name: &str, expected: f32, actual: f32) {
let success = (expected - actual).abs() < self.epsilon;
println!(
"Checking {}: expected {}, got {}. {}",
name,
expected,
actual,
if success { "Success!" } else { "FAIL" }
);
self.success &= success;
}
fn result(&self) -> Result<(), Box<dyn Error>> {
if self.success {
Ok(())
} else {
Err(Box::new(Status::new_set(
Code::Internal,
"At least one check failed",
)?))
}
}
}
fn main() -> Result<(), Box<dyn Error>> {
let mut g = Graph::new();
let y_node = {
let mut compiler = Compiler::new(&mut g);
let x_expr = <Placeholder<f32>>::new_expr(&vec![2], "x");
compiler.compile(x_expr * 2.0f32 + 1.0f32)?
};
let x_node = g.operation_by_name_required("x")?;
let options = SessionOptions::new();
let session = Session::new(&options, &g)?;
let mut x = <Tensor<f32>>::new(&[2]);
x[0] = 2.0;
x[1] = 3.0;
let mut step = SessionRunArgs::new();
step.add_feed(&x_node, 0, &x);
let output_token = step.request_fetch(&y_node, 0);
session.run(&mut step).unwrap();
let output_tensor = step.fetch::<f32>(output_token)?;
let mut checker = Checker::new(1e-3);
checker.check("output_tensor[0]", 5.0, output_tensor[0]);
checker.check("output_tensor[1]", 7.0, output_tensor[1]);
checker.result()
}