1#ifndef CAFFE2_CORE_OPERATOR_GRADIENT_H_
2#define CAFFE2_CORE_OPERATOR_GRADIENT_H_
23 return (dense_.size() != 0);
26 return (indices_.size() != 0 || values_.size() != 0);
29 return (!IsDense() && !IsSparse());
42 const vector<OperatorDef>&
ops,
43 const vector<GradientWrapper>& v)
44 : ops_(
ops), g_input_(v) {}
50 const OperatorDef& def,
51 const vector<GradientWrapper>& g_output)
52 :
def_(def), g_output_(g_output), g_input_(def.input_size()){};
69 "(GradientMaker) Operator def did not pass schema checking: ",
87 vector<OperatorDef> new_defs = GetGradientDefs();
88 for (
auto& opdef : new_defs) {
89 opdef.set_is_gradient_op(
true);
94 const OperatorDef&
Def()
const {
109 string I(
const int i) {
111 return def_.input(i);
113 string O(
const int i) {
115 return def_.output(i);
117 string GI(
const int i) {
119 !g_input_.at(i).IsSparse(),
122 " already set to sparse.");
123 g_input_.at(i).dense_ = GradientName(
def_.input(i));
124 return GradientName(
def_.input(i));
128 !g_input_.at(i).IsDense(),
131 " already set to dense.");
132 g_input_.at(i).indices_ = GradientSliceIndices(
def_.input(i));
133 return GradientSliceIndices(
def_.input(i));
137 !g_input_.at(i).IsDense(),
140 " already set to dense.");
141 g_input_.at(i).values_ = GradientSliceValues(
def_.input(i));
142 return GradientSliceValues(
def_.input(i));
144 string GO(
const int i) {
146 g_output_.at(i).IsDense(),
147 "Gradient of output ",
149 (g_output_.at(i).IsSparse() ?
" is sparse (expected dense)."
150 :
" is not provided!"));
151 return g_output_.at(i).dense_;
155 g_output_.at(i).IsSparse(),
156 "Gradient of output ",
158 (g_output_.at(i).IsDense() ?
" is dense (expected sparse)."
159 :
" is not provided!"));
160 return g_output_.at(i).indices_;
164 g_output_.at(i).IsSparse(),
165 "Gradient of output ",
167 (g_output_.at(i).IsDense() ?
" is dense (expected sparse)."
168 :
" is not provided!"));
169 return g_output_.at(i).values_;
172 return g_output_.at(i);
178 !g_input_.at(i).IsSparse(),
181 " already set to sparse.");
182 g_input_.at(i).dense_ =
name;
186 !g_input_.at(i).IsDense(),
189 " already set to dense.");
190 g_input_.at(i).indices_ =
indices;
191 g_input_.at(i).values_ =
values;
198 template <
class...
Args>
210 for (
auto&
out :
op.output()) {
211 if (IsGradientBlob(
out)) {
222 return name +
"_grad";
226 return name.length() > 5 &&
name.find(
"_grad") ==
name.length() - 5;
231 return name.substr(0,
name.length() - 5);
235 return name +
"_grad_indices";
239 return name +
"_grad_values";
262 return vector<OperatorDef>();
275 CAFFE_THROW(
"One should not call gradient for operator ",
def_.type(),
".");
292 " should have a gradient but is not implemented yet.");
300 const vector<GradientWrapper>&);
302#ifdef CAFFE2_NO_GRADIENT_OPS
304#define REGISTER_GRADIENT(name, ...)
305#define REGISTER_GRADIENT_STR(str_name, ...)
309#define REGISTER_GRADIENT(name, ...) \
310 C10_REGISTER_CLASS(GradientRegistry, name, __VA_ARGS__)
311#define REGISTER_GRADIENT_STR(str_name, ...) \
312 C10_REGISTER_TYPED_CLASS(GradientRegistry, str_name, __VA_ARGS__)
317#define NO_GRADIENT(name) REGISTER_GRADIENT(name, NoGradient)
322#define SHOULD_NOT_DO_GRADIENT(name) \
323 REGISTER_GRADIENT(name, ThrowInTheTowelIfGradientIsCalled)
325#define GRADIENT_NOT_IMPLEMENTED_YET(name) \
326 REGISTER_GRADIENT(name, GradientNotImplementedYet)
332 const OperatorDef& def,
333 const vector<GradientWrapper>& g_output);
Args({2<< 5}) -> Args({2<< 8}) ->Args({2<< 12}) ->Args({2<< 14})
#define CAFFE_NOT_IMPLEMENTED
const OperatorDef & Def() const
virtual GradientOpsMeta Get()
Returns the gradient ops meta.
void SetSparse(const int i, const string &indices, const string &values)
const vector< GradientWrapper > & g_output_
const GradientWrapper & GradOut(int i)
virtual bool CopyEngine() const
vector< GradientWrapper > g_input_
virtual bool CopyArguments() const
virtual bool CopyDeviceOption() const
static bool IsGradientBlob(const string &name)
GradientMakerBase(const OperatorDef &def, const vector< GradientWrapper > &g_output)
void SetDense(const int i, const string &name)
virtual ~GradientMakerBase()
static vector< OperatorDef > SingleGradientDef(const Args &... args)
a helper function to allow one to create one single operator def, which is usually the case for many ...
static string GradientNameToParam(const string &name)
static string GradientName(const string &name)
static string GradientSliceIndices(const string &name)
virtual vector< OperatorDef > GetGradientDefs()
static string GradientSliceValues(const string &name)
static CaffeMap< string, string > MatchGradsToParams(const OperatorDef &op)
Returns map that returns the parameters that the gradients are for.
virtual void VerifyOp() const
A helper class to indicate that the operator does not need gradient computation.
vector< OperatorDef > GetGradientDefs() override
static const OpSchema * Schema(const string &key)
Copyright (c) 2016-present, Facebook, Inc.
C10_EXPORT string ProtoDebugString(const Message &proto)
C10_DECLARE_REGISTRY(BlobDeserializerRegistry, BlobDeserializerBase)
core.CreateOperator("Slice",["X"],["Y"], starts=(0, 1), ends=(-1, 3)) workspace.FeedBlob("X", np.array()) print("X:", workspace.FetchBlob("X")) workspace.RunOperatorOnce(op) print("Y:", workspace.FetchBlob("Y")) ``` **Result **``` X:Y:```</details >) DOC") .Input(0, "X", "(*Tensor *):tensor to extract slices from") .Input( 1, "starts", "(*Tensor`< int >` *):1D tensor of start-indices for each dimension of data(dimensions following the sliced one might be omitted)") .Input( 2, "ends", "(*Tensor`< int >` *):1D tensor of end-indices for each dimension of data(dimensions following the sliced one might be omitted)") .Arg("starts", "(*Tuple(int) *):list of starting indices") .Arg("ends", "(*Tuple(int) *):list of ending indices") .TensorInferenceFunction([](const OperatorDef& def, const vector<TensorShape>& in) { if (in.size() > 1) { return vector<TensorShape>() op
for each weights are accessed by indices[0..L-1]
const ArgumentHelper args(def)
bucketize it based on the boundary values and then do one hot encoding The lengths specifies the number of boundary values for each column The final number of buckets is this number plus This would also be the expanded feature size boundaries specifies all the boundary values Note that each bucket is right inclusive That given boundary values[b1, b2, b3]
std::map< Key, Value > CaffeMap
OperatorDef CreateOperatorDef(const string &type, const string &name, const IterableInputs &inputs, const IterableOutputs &outputs, const IterableArgs &args, const DeviceOption &device_option=DeviceOption(), const string &engine="")
GradientOpsMeta GetGradientForOp(const OperatorDef &def, const vector< GradientWrapper > &g_output)
Gets the GradientOpsMeta for the given operator def.
CAFFE_ENFORCE(dims.front() >=0, "Dimension ids must be non-negative.")
Module caffe2.python.schema.
A helper class to indicate that the gradient mechanism is not ready.
GradientOpsMeta Get() override
Returns the gradient ops meta.
A helper class to indicate that the operator should have no gradient.
GradientOpsMeta Get() override
Returns the gradient ops meta.