-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add operator base #2725
add operator base #2725
Conversation
paddle/framework/operator.h
Outdated
explicit Operator(const OpDesc& desc); | ||
virtual ~Operator() {} | ||
|
||
void InitializeAttrs(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we can remove this interface and do initialize in the ctor
paddle/framework/operator.cc
Outdated
namespace paddle { | ||
namespace framework { | ||
|
||
OperatorBase::OperatorBase(const OpDesc &desc): desc_(desc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that OpBase doesn't take whole OpDesc
as the arguments, but only inputs and outputs.
So maybe std::vector<string> input
and std::vector<string> output
is enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, remove construct function
paddle/framework/operator.cc
Outdated
} | ||
|
||
std::string OperatorBase::DebugString() { | ||
return desc_.DebugString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DebugString() is not in OpDesc.
It should be generated in run time.
Like Operator Cosine, from (var_input1, var_input2) to (var_output)
paddle/framework/operator.cc
Outdated
} | ||
} | ||
|
||
std::string OperatorBase::DebugString() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, const
is need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
paddle/framework/operator.cc
Outdated
return desc_.DebugString(); | ||
} | ||
|
||
Variable* OperatorBase::input(Scope *scope, int index) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not be a part of the interface.
Because the invoker of Operator is not need input
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, will put input() into OpRunContext
paddle/framework/operator.h
Outdated
|
||
/// initialize Attributes of this OP from proto message desc.attrs() | ||
/// you should derive this function to init the attr you need in OP. | ||
virtual void InitializeAttributes() = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That interface is not needed, due to @Canpio 's design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, move to CreateOperator
paddle/framework/operator.h
Outdated
Variable* output(Scope* scope, int index); | ||
|
||
protected: | ||
const OpDesc desc_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Op do not store OpDesc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not store OpDesc, it will not change and can use directly when to serialize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.... though i still want to keep it
paddle/framework/operator.h
Outdated
Variable* input(Scope* scope, int index); | ||
Variable* output(Scope* scope, int index); | ||
|
||
protected: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inputs_ and outputs_ are all public.
paddle/framework/CMakeLists.txt
Outdated
@@ -12,3 +12,4 @@ cc_test(op_proto_test SRCS op_proto_test.cc DEPS op_proto protobuf) | |||
|
|||
proto_library(op_desc SRCS op_desc.proto DEPS attr_type) | |||
cc_test(op_desc_test SRCS op_desc_test.cc DEPS op_desc protobuf) | |||
cc_library(operator SRCS operator.cc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need unittest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* device resource such as CUDA stream, cublas handle, etc. from | ||
* OpRunContext. User should construct it before run the Operator. | ||
*/ | ||
class OpRunContext { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that Caffe2 doesn't have OpRunContext
, it seems that we are doing over-engineering here. How about put Scope* scope
in the base class Context
, which has sub-classes CPUContext
and GPUContext
?
paddle/framework/operator.h
Outdated
namespace framework { | ||
|
||
class DeviceContext {}; | ||
class CpuContext : public DeviceContext {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cpu => CPU. It is an acronym.
paddle/framework/operator.h
Outdated
|
||
class DeviceContext {}; | ||
class CpuContext : public DeviceContext {}; | ||
class GpuContext : public DeviceContext {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gpu => GPU
paddle/framework/operator.h
Outdated
DeviceContext* device_context; | ||
}; | ||
|
||
using Attribute = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see three ways of implementing Operator attributes:
std::map<string, boost:variant<...> >
std::map<string, shared_ptr<Variable> >
OperatorDesc
, given thatOperatorBase::OperatorBase
takes aOperatorDesc
and saves it indesc_
.
Which is the simplest one?
It looks to me that the last one is the simplest because the former two introduce a new form, std::map
, of OperatorDesc::attrs_
.
paddle/framework/operator.h
Outdated
/// InferShape infer the size of Variables used by this Operator with | ||
/// information | ||
/// inside scope | ||
virtual void InferShape(const Scope* scope) const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
InferShape should have default implementation?
virtual void InferShape(const Scope* scope) {}
Also, it might change properties of inputs and outputs, so shouldn't be suffixed with const?
paddle/framework/operator.h
Outdated
|
||
std::string DebugString() const; | ||
|
||
public: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should we expose all these fields? I don't seem at any chance the outside world need to access them.
Indeed, even from inside an Operator class, we don't need to access them. Instead, the following methods should use them:
template <typename T> const T& GetAttr(std::string name);
Variable* Input(std::string name) const;
Variable* output(std::string name) const;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
caffe里面是把这几个函数放在了OpBase中,因为caffe的op在new的时候把workspace和context都创建好放在了op里边,所以caffe op的run不需要加什么参数。
我们目前scope和devicecontext都是运行时才能确定,通过组装成一个 OpRunContext 给 Run(OpRunContext* context) ,所以目前的想法是这几个函数都有OpRunContext提供:
这样的话,很自然的,我们就会有OpKernel这个概念了,Operator存储一些非运行时的配置,运行之前组装OpRunContext传给OpKernel的run。
class OpKernel {
void Run(OpRunContext* context) {
auto input0 = context.Input(0);
auto cuda_stream = contex.cuda_stream();
}
}
* device resource such as CUDA stream, cublas handle, etc. from | ||
* OpRunContext. User should construct it before run the Operator. | ||
*/ | ||
class OpRunContext { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpContext
in mxnet, why not call it OpContext
given that their functions are the same? OpRunContext
too long and sounds strange.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
paddle/framework/operator.h
Outdated
|
||
std::string DebugString() const; | ||
|
||
public: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protected
if they need to be accessed easily by subclasses better ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add getter function and set all this to private
* device resource such as CUDA stream, cublas handle, etc. from | ||
* OpRunContext. User should construct it before run the Operator. | ||
*/ | ||
class OpRunContext { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class OpRunContext
-> struct
better ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe OpContext will be more complex later, and will add more interface.
paddle/framework/operator.cc
Outdated
} | ||
for(auto it = attrs.begin(); it != attrs.end(); ++it) { | ||
attrs_[it->first] = it->second; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The declaration of attrs_:
AttributeMap attrs_;
The type is same with attrs, so why not use attrs_ = attrs?
paddle/framework/operator.h
Outdated
|
||
inline const AttributeMap attrs() const { | ||
return attrs_; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
template const T& GetAttr(std::string name);
如wangyi老师所说这样觉得更好些,返回Attribute、AttributeMap对于写Op的人来说也还需要查怎么获取值~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
paddle/framework/operator.h
Outdated
OpDesc desc_; | ||
std::vector<std::string> inputs_; | ||
std::vector<std::string> outputs_; | ||
AttributeMap attrs_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each operator should have a unique name. Is the name saved in attrs_
or desc_
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no uniq name now, maybe we can add one
#include <boost/variant.hpp> | ||
#include <string> | ||
#include <unordered_map> | ||
#include <vector> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above four lines can be removed. They have been included in paddle/framework/attr_checker.h
.
paddle/framework/operator.h
Outdated
virtual void Run(OpContext* context) const = 0; | ||
|
||
private: | ||
OpDesc desc_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is OpDesc
used for some functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to get type of op
inline const OpDesc desc() const { return desc_; }
paddle/framework/operator.h
Outdated
return boost::get<T>(attrs_.at(name)); | ||
} | ||
|
||
inline const std::vector<std::string> inputs() const { return inputs_; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reference.
const std::vector<std::string>&
.
Also, I suggest all private data member of OpBase
should be public. Not to add noising Getter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the inputs_
are owned by an operator itself, better be a protected
if subclasses want to edit, but with a const getter by visitors that just want to read, such as a Net
?
paddle/framework/operator.cc
Outdated
|
||
void OperatorBase::InferShape(Scope* scope) const {} | ||
|
||
const std::string OperatorBase::DebugString() const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why should this be a const
?
the returned string is copied, and free to mutate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const removed
paddle/framework/operator.h
Outdated
|
||
inline const std::vector<std::string> inputs() const { return inputs_; } | ||
|
||
inline const std::vector<std::string> outputs() const { return outputs_; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not need an inline
here? a function defined within a class should be set inline by the compiler automatically.
paddle/framework/operator.h
Outdated
|
||
inline const std::vector<std::string> outputs() const { return outputs_; } | ||
|
||
const std::string DebugString() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
is useless here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
paddle/framework/operator.h
Outdated
void InferShape(Scope* scope) const; | ||
|
||
void Run(std::shared_ptr<Scope> scope, DeviceContext* dev_ctx) { | ||
OpContext* op_ctx = new OpContext(this, scope, dev_ctx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new
here, no need to manage the memory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
paddle/framework/operator.cc
Outdated
namespace paddle { | ||
namespace framework { | ||
|
||
void OperatorBase::InferShape(std::shared_ptr<Scope> scope) const {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const T&
paddle/framework/operator.h
Outdated
Variable* Output(int index) const; | ||
|
||
public: | ||
const OperatorBase* op; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
op
-> op_
;
paddle/framework/operator.h
Outdated
|
||
public: | ||
const OperatorBase* op; | ||
std::shared_ptr<Scope> scope; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scope
-> scope_
paddle/framework/operator.h
Outdated
public: | ||
const OperatorBase* op; | ||
std::shared_ptr<Scope> scope; | ||
DeviceContext* device_context; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
device_context
-> device_context_
;
paddle/framework/operator.h
Outdated
virtual ~OperatorBase() {} | ||
|
||
template <typename T> | ||
inline const T GetAttr(const std::string& name) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useless function. boost::get<T>(attrs_.at(name))
is enough. Even this function is needed, it should belong to AttributeMap
not OperatorBase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, this function should return const T&
if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan to store attrs as variable later, this interface is used for now
paddle/framework/operator.h
Outdated
virtual void InferShape(std::shared_ptr<Scope> scope) const; | ||
|
||
/// Net will call this function to Run an op. | ||
void Run(std::shared_ptr<Scope> scope, DeviceContext* dev_ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const std::shared_ptr&
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
paddle/framework/operator.h
Outdated
|
||
/// when implement an Op, your should implement this function. | ||
/// this function should be moved to OpKernel later | ||
virtual void Run(OpContext* context) const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpContext
--> OpRunContext
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, this function is not in OperatorBase
interface. The OperatorBase
interface should only contains
virtual void Run(const std::shared_ptr<Scope>& scope, DeviceContext* dev_ctx) = 0;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, but now we have no kernel OP, and this interface is used by test now, so I keep it and will move it to op with kernel in the next PR
paddle/framework/operator.h
Outdated
virtual void Run(OpContext* context) const = 0; | ||
|
||
public: | ||
OpDesc desc_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this field needed now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I think we need this field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
No description provided.