1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use crate::AnyTensor;
use crate::Operation;
use crate::Result;
use crate::Scope;
use crate::Tensor;
use crate::TensorType;
use tensorflow_internal_macros::define_op;

/// Creates a constant.
///
/// The value can be anything convertible to a tensor, so possibilities include:
///
/// ```
/// # use std::error::Error;
/// # use tensorflow::Scope;
/// # use tensorflow::Tensor;
/// # use tensorflow::ops::constant;
/// # let mut scope = Scope::new_root_scope();
/// let a = constant(1.0f32, &mut scope)?;
/// let b = constant(&[1.0f32, 2.0][..], &mut scope)?;
/// let c = constant(Tensor::new(&[2, 2]).with_values(&[0f32, 1.0, 2.0, 3.0])?, &mut scope)?;
/// # Ok::<(), Box<dyn Error>>(())
/// ```
///
/// Note that e.g. `&[1, 2][..]` is used instead of `&[1, 2]`.  This forces the
/// compiler to treat the value as a slice rather than a reference to a
/// fixed-size array.  This is necessary because `Into<Tensor>` is implemented
/// for slices but not arrays, and the compiler doesn't automatically fall back
/// to treating the array reference as a slice.
pub fn constant<T: TensorType, TT: Into<Tensor<T>>>(
    value: TT,
    scope: &mut Scope,
) -> Result<Operation> {
    let name = scope.get_unique_name_for_op("Const");
    let mut graph = scope.graph_mut();
    let mut c = graph.new_operation("Const", &name)?;
    c.set_attr_tensor("value", value.into())?;
    c.set_attr_type("dtype", T::data_type())?;
    c.finish()
}

pub(crate) fn any_constant(value: &dyn AnyTensor, scope: &mut Scope) -> Result<Operation> {
    let name = scope.get_unique_name_for_op("Const");
    let mut graph = scope.graph_mut();
    let mut c = graph.new_operation("Const", &name)?;
    c.set_attr_any_tensor("value", value)?;
    c.set_attr_type("dtype", value.data_type())?;
    c.finish()
}

define_op!(multiply, Multiply, "Mul", "Use mul instead.", args { a, b });

define_op!(subtract, Subtract, "Sub", "Use sub instead.", args { a, b });