using NumSharp;
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Eager;
using Tensorflow.Gradients;
using static Tensorflow.Binding;
namespace Tensorflow
{
public class BaseResourceVariable : DisposableObject, IVariableV1
{
protected string _name;
public virtual string Name => _handle_name;
protected TF_DataType _dtype;
public TF_DataType dtype => _dtype;
protected string _handle_name;
protected string handle_name => _handle_name;
protected string _unique_id;
public string unique_id => _unique_id;
protected bool _in_graph_mode;
protected bool _trainable;
public bool trainable => _trainable;
protected Tensor _initial_value;
public Tensor initial_value => _initial_value;
protected Tensor _parent_op;
public Tensor parent_op => _parent_op;
///
/// Tensor handle
///
protected Tensor handle;
public Tensor Handle => handle;
protected Tensor _graph_element;
public Tensor GraphElement => _graph_element;
protected TensorShape _shape;
public TensorShape shape => _shape;
protected Operation initializer_op;
public Operation Initializer => initializer_op;
public Operation Op => handle.op;
public Graph Graph => handle.graph;
public BaseResourceVariable()
{
}
public BaseResourceVariable(IntPtr handle, IntPtr tensor)
{
_handle = handle;
}
public void __init__(bool trainable = true,
Tensor handle = null,
string name = null,
string unique_id = null,
string handle_name = null)
{
_trainable = trainable;
_handle_name = handle_name + ":0";
_unique_id = unique_id;
this.handle = handle;
_name = name;
// handle_deleter
}
public ITensorOrOperation assign(T value, bool use_locking = false, string name = null, bool read_value = true)
{
var value_tensor = ops.convert_to_tensor(value, dtype: dtype);
var assign_op = gen_resource_variable_ops.assign_variable_op(
handle, value_tensor, name: name);
if (read_value)
return gen_resource_variable_ops.read_variable_op(handle, dtype);
// return _lazy_read(assign_op, value_tensor);
return assign_op;
}
public Tensor value() => _read_variable_op();
protected Tensor _read_variable_op()
{
variable_accessed(this);
var result = gen_resource_variable_ops.read_variable_op(handle, _dtype);
// _maybe_set_handle_data(_dtype, _handle, result);
return result;
}
BaseResourceVariable _lazy_read(Operation op, Tensor value)
{
variable_accessed(this);
return new _UnreadVariable(handle, _dtype, _shape, _in_graph_mode, _unique_id);
}
///
/// Records that `variable` was accessed for the tape and FuncGraph.
///
void variable_accessed(BaseResourceVariable variable)
{
if (variable.trainable)
{
foreach (var tape in tf.GetTapeSet())
tape.VariableAccessed(variable as ResourceVariable);
}
}
///
/// Constructs an op which reads the value of this variable.
///
/// Should be used when there are multiple reads, or when it is desirable to
/// read the value only after some condition is true.
///
///
Tensor read_value()
=> tf_with(ops.name_scope("Read"), delegate
{
var value = _read_variable_op();
return array_ops.identity(value);
});
public ITensorOrOperation assign_add(T delta, bool use_locking = false, string name = null, bool read_value = true)
{
var assign_add_op = gen_resource_variable_ops.assign_add_variable_op(Handle,
ops.convert_to_tensor(delta, dtype: dtype), name: name);
if (read_value)
return gen_resource_variable_ops.read_variable_op(handle, dtype);
// return _lazy_read(assign_add_op);
return assign_add_op;
}
public override string ToString()
{
if (tf.context.executing_eagerly())
return $"tf.Variable: '{Name}' shape={string.Join(",", shape)}, dtype={dtype.as_numpy_name()}, numpy={tensor_util.to_numpy_string(read_value())}";
else
return $"tf.Variable: '{Name}' shape={string.Join(",", shape)}, dtype={dtype.as_numpy_name()}";
}
public NDArray numpy() => read_value().numpy();
protected override void DisposeUnmanagedResources(IntPtr handle)
{
}
public Tensor AsTensor() => _graph_element;
}
}