/usr/local/lib64/python3.6/site-packages/torch/include/caffe2/core
NameSizeModeActions
allocator.h1360644editdlrm
blob.h41680644editdlrm
blob_serialization.h107910644editdlrm
blob_serializer_base.h39050644editdlrm
blob_stats.h11270644editdlrm
common.h43290644editdlrm
common_cudnn.h98930644editdlrm
common_gpu.h214140644editdlrm
common_omp.h1560644editdlrm
context.h61740644editdlrm
context_base.h43820644editdlrm
context_gpu.h110140644editdlrm
cudnn_wrappers.h69560644editdlrm
db.h93520644editdlrm
distributions_stubs.h21610644editdlrm
event.h124200644editdlrm
event_cpu.h11920644editdlrm
export_c10_op_to_caffe2.h94870644editdlrm
export_caffe2_op_to_c10.h111010644editdlrm
flags.h740644editdlrm
graph.h52580644editdlrm
init.h64960644editdlrm
logging.h750644editdlrm
macros.h34260644editdlrm
memonger.h8170644editdlrm
module.h24730644editdlrm
net.h46340644editdlrm
net_async_base.h73970644editdlrm
net_async_scheduling.h9930644editdlrm
net_async_task.h8330644editdlrm
net_async_task_future.h19250644editdlrm
net_async_task_graph.h22530644editdlrm
net_async_tracing.h50930644editdlrm
net_dag_utils.h21460644editdlrm
net_parallel.h21440644editdlrm
net_simple.h26060644editdlrm
net_simple_refcount.h20970644editdlrm
numa.h720644editdlrm
observer.h38090644editdlrm
operator.h588720644editdlrm
operator_gradient.h102220644editdlrm
operator_schema.h184770644editdlrm
plan_executor.h2190644editdlrm
prof_dag_counters.h27510644editdlrm
qtensor.h66150644editdlrm
qtensor_serialization.h26240644editdlrm
scope_guard.h46750644editdlrm
static_tracepoint.h3980644editdlrm
static_tracepoint_elfx86.h55550644editdlrm
stats.h103650644editdlrm
storage.h7330644editdlrm
tensor.h186680644editdlrm
tensor_impl.h3510644editdlrm
tensor_int8.h4500644editdlrm
test_utils.h62850644editdlrm
timer.h12180644editdlrm
transform.h57410644editdlrm
types.h22480644editdlrm
workspace.h113050644editdlrm
Edit: /usr/local/lib64/python3.6/site-packages/torch/include/caffe2/core/operator_gradient.h (10222B)
#ifndef CAFFE2_CORE_OPERATOR_GRADIENT_H_ #define CAFFE2_CORE_OPERATOR_GRADIENT_H_ #include "c10/util/Registry.h" #include "caffe2/core/operator_schema.h" #include "caffe2/proto/caffe2_pb.h" #include "caffe2/utils/proto_utils.h" namespace caffe2 { /* @brief A struct that abstracts on top of dense and sparse blobs. * * For a dense blob, its gradient name should be written into dense_, and for * a sparse blob, its gradient name should be written into indice_ for * the sparse indices and value_ for the values. */ struct TORCH_API GradientWrapper { string dense_; string indices_; string values_; inline bool IsDense() const { return (dense_.size() != 0); } inline bool IsSparse() const { return (indices_.size() != 0 || values_.size() != 0); } inline bool IsEmpty() const { return (!IsDense() && !IsSparse()); } }; /** * A struct that holds the gradient operators and related gradient maps. */ struct TORCH_API GradientOpsMeta { vector ops_; vector g_input_; GradientOpsMeta() {} GradientOpsMeta( const vector& ops, const vector& v) : ops_(ops), g_input_(v) {} }; class TORCH_API GradientMakerBase { public: GradientMakerBase( const OperatorDef& def, const vector& g_output) : def_(def), g_output_(g_output), g_input_(def.input_size()){}; virtual ~GradientMakerBase() {} virtual bool CopyDeviceOption() const { return true; } virtual bool CopyEngine() const { return true; } virtual bool CopyArguments() const { return true; } virtual void VerifyOp() const { auto* schema = OpSchemaRegistry::Schema(def_.type()); if (schema) { CAFFE_ENFORCE( schema->Verify(def_), "(GradientMaker) Operator def did not pass schema checking: ", ProtoDebugString(def_)); } } /** * @brief Returns the gradient ops meta. * * If your gradient op generator only use standard input and output * manipulations, you can simply implement GetGradientDefs() that * returns vector. In that, you can call GI, GI_V and GI_I * that will automatically create the gradient registration for you. * * If you need to do custom gradient name registration, overload this * function directly. */ virtual GradientOpsMeta Get() { VerifyOp(); vector new_defs = GetGradientDefs(); for (auto& opdef : new_defs) { opdef.set_is_gradient_op(true); } return GradientOpsMeta(new_defs, g_input_); }; const OperatorDef& Def() const { return def_; } protected: virtual vector GetGradientDefs() { CAFFE_NOT_IMPLEMENTED; } // Helper functions to return names for the gradient computation. // I(idx), O(idx): return the input and output names. // GO(idx): return the name of the gradient for output idx. // GI(idx), GI_I(idx), GI_V(idx): return the name of the gradient for // input idx, and also registers that name into the gradient // registry to be returned. string I(const int i) { CAFFE_ENFORCE((i >= 0) && (i < def_.input().size())); return def_.input(i); } string O(const int i) { CAFFE_ENFORCE((i >= 0) && (i < def_.output().size())); return def_.output(i); } string GI(const int i) { CAFFE_ENFORCE( !g_input_.at(i).IsSparse(), "Input ", def_.input(i), " already set to sparse."); g_input_.at(i).dense_ = GradientName(def_.input(i)); return GradientName(def_.input(i)); } string GI_I(const int i) { CAFFE_ENFORCE( !g_input_.at(i).IsDense(), "Input ", def_.input(i), " already set to dense."); g_input_.at(i).indices_ = GradientSliceIndices(def_.input(i)); return GradientSliceIndices(def_.input(i)); } string GI_V(const int i) { CAFFE_ENFORCE( !g_input_.at(i).IsDense(), "Input ", def_.input(i), " already set to dense."); g_input_.at(i).values_ = GradientSliceValues(def_.input(i)); return GradientSliceValues(def_.input(i)); } string GO(const int i) { CAFFE_ENFORCE( g_output_.at(i).IsDense(), "Gradient of output ", def_.output(i), (g_output_.at(i).IsSparse() ? " is sparse (expected dense)." : " is not provided!")); return g_output_.at(i).dense_; } string GO_I(const int i) { CAFFE_ENFORCE( g_output_.at(i).IsSparse(), "Gradient of output ", def_.output(i), (g_output_.at(i).IsDense() ? " is dense (expected sparse)." : " is not provided!")); return g_output_.at(i).indices_; } string GO_V(const int i) { CAFFE_ENFORCE( g_output_.at(i).IsSparse(), "Gradient of output ", def_.output(i), (g_output_.at(i).IsDense() ? " is dense (expected sparse)." : " is not provided!")); return g_output_.at(i).values_; } const GradientWrapper& GradOut(int i) { return g_output_.at(i); } // Function to add a gradient pair to map. void SetDense(const int i, const string& name) { CAFFE_ENFORCE( !g_input_.at(i).IsSparse(), "Input ", def_.input(i), " already set to sparse."); g_input_.at(i).dense_ = name; } void SetSparse(const int i, const string& indices, const string& values) { CAFFE_ENFORCE( !g_input_.at(i).IsDense(), "Input ", def_.input(i), " already set to dense."); g_input_.at(i).indices_ = indices; g_input_.at(i).values_ = values; } /** * @brief a helper function to allow one to create one single operator * def, which is usually the case for many simple operators. */ template inline static vector SingleGradientDef(const Args&... args) { return vector{CreateOperatorDef(args...)}; } public: /** * Returns map that returns the parameters that the gradients are for. */ static CaffeMap MatchGradsToParams(const OperatorDef& op) { // NOTE: how to go beyond string-matching? CaffeMap m; for (auto& out : op.output()) { if (IsGradientBlob(out)) { m[out] = out.substr(0, out.length() - 5); } } return m; } private: // Utility functions for gradient name computation. We don't expose them // in order to discourage the use of such names explicitly. static string GradientName(const string& name) { return name + "_grad"; } static bool IsGradientBlob(const string& name) { return name.length() > 5 && name.find("_grad") == name.length() - 5; } static string GradientNameToParam(const string& name) { CHECK(IsGradientBlob(name)); return name.substr(0, name.length() - 5); } static string GradientSliceIndices(const string& name) { return name + "_grad_indices"; } static string GradientSliceValues(const string& name) { return name + "_grad_values"; } protected: // We make the member variables protected in case someone wants to write // a fully custom Get() function. const OperatorDef& def_; const vector& g_output_; vector g_input_; }; /** * @brief A helper class to indicate that the operator does not need gradient * computation. * * Use the macro NO_GRADIENT to register operators that do not have gradients. * Note that this is different fron SHOULD_NOT_DO_GRADIENT: the latter means * that the gradient computation should not flow through it at all, and throws * an error if it is called. */ class TORCH_API NoGradient : public GradientMakerBase { using GradientMakerBase::GradientMakerBase; vector GetGradientDefs() override { return vector(); } }; /** * @brief A helper class to indicate that the operator should have no gradient. * * This is used when the operator definition is designed to not have a gradient. * Calling a gradient on this operator def will cause Caffe2 to quit. */ struct ThrowInTheTowelIfGradientIsCalled : public GradientMakerBase { using GradientMakerBase::GradientMakerBase; GradientOpsMeta Get() override { CAFFE_THROW("One should not call gradient for operator ", def_.type(), "."); } }; /** * @brief A helper class to indicate that the gradient mechanism is not ready. * * This should only be used sparsely when the gradient does exist, but we have * not implemented it yet and are using this as a lazy excuse. Eventually, a * gradient operator should be implemented. */ struct GradientNotImplementedYet : public GradientMakerBase { using GradientMakerBase::GradientMakerBase; GradientOpsMeta Get() override { CAFFE_THROW( "Operator ", def_.type(), " should have a gradient but is not implemented yet."); } }; C10_DECLARE_REGISTRY( GradientRegistry, GradientMakerBase, const OperatorDef&, const vector&); #ifdef CAFFE2_NO_GRADIENT_OPS #define REGISTER_GRADIENT(name, ...) /* No gradients. */ #define REGISTER_GRADIENT_STR(str_name, ...) /* No gradients. */ #else #define REGISTER_GRADIENT(name, ...) \ C10_REGISTER_CLASS(GradientRegistry, name, __VA_ARGS__) #define REGISTER_GRADIENT_STR(str_name, ...) \ C10_REGISTER_TYPED_CLASS(GradientRegistry, str_name, __VA_ARGS__) #endif // NO_GRADIENT means that the operator does not need any gradient computation. #define NO_GRADIENT(name) REGISTER_GRADIENT(name, NoGradient) // SHOULD_NOT_DO_GRADIENT means that the operator is not designed to have // gradient operators. If you attempt to call the gradient, a log fatal will // occur. #define SHOULD_NOT_DO_GRADIENT(name) \ REGISTER_GRADIENT(name, ThrowInTheTowelIfGradientIsCalled) #define GRADIENT_NOT_IMPLEMENTED_YET(name) \ REGISTER_GRADIENT(name, GradientNotImplementedYet) /** * @brief Gets the GradientOpsMeta for the given operator def. */ TORCH_API GradientOpsMeta GetGradientForOp( const OperatorDef& def, const vector& g_output); } // namespace caffe2 #endif // CAFFE2_CORE_OPERATOR_GRADIENT_H_