Commit f47e53cf by Ting PAN

Refactor Fundamental Ops

1 parent 1d551431
Showing with 1556 additions and 1094 deletions
......@@ -52,9 +52,9 @@ using Set = std::unordered_set<Value> ;
/*
* Define the Kernel version.
*
* | Major(2) | Minor(2) | Patch(07) |
* | Major(2) | Minor(2) | Patch(08) |
*/
#define DRAGON_VERSION 2207
#define DRAGON_VERSION 2208
/*
* Define the default random seed.
......
......@@ -23,7 +23,7 @@ class GraphBase {
vector<string> parents;
vector<string> childs;
int op_idx = -1;
string op_type;
OperatorDef op_def;
};
GraphBase(
......
......@@ -27,7 +27,7 @@ class Workspace {
typedef Map<string, unique_ptr<OperatorBase> > OperatorMap;
typedef Map<string, unique_ptr<GraphBase> > GraphMap;
typedef Map<string, TensorFiller> FillerMap;
typedef Map<string, string> RenameMap;
typedef Map<string, string> ProxyMap;
Workspace(const string& name) : name_(name) { InitWorkspace(); }
......@@ -56,9 +56,9 @@ class Workspace {
inline Workspace* MoveWorkspace(Workspace* ws) {
CHECK(ws) << "The given Workspace is invalid.";
if (workspace_map_.count(ws->name()))
return workspace_map_[ws->name()];
return workspace_map_[ws->name()] = ws;
if (ws_map_.count(ws->name()))
return ws_map_[ws->name()];
return ws_map_[ws->name()] = ws;
}
inline void ClearWorkspace() {
......@@ -70,8 +70,8 @@ class Workspace {
/******************** Tensor ********************/
inline string GetTensorName(const string& name) {
if (rename_map_.count(name) > 0) {
return rename_map_[name];
if (proxy_map_.count(name) > 0) {
return proxy_map_[name];
} else { return name; }
}
......@@ -84,7 +84,7 @@ class Workspace {
return tensor_map_[query].get();
if (use_remote) {
// search remote workspace
for (auto& it : workspace_map_) {
for (auto& it : ws_map_) {
if (it.second->HasTensor(query))
return it.second->GetTensor(query);
}
......@@ -129,7 +129,7 @@ class Workspace {
for (auto& it : tensor_map_)
names.push_back(it.first);
// serach remote workspace
for (auto& it : workspace_map_) {
for (auto& it : ws_map_) {
vector<string> sub_names = it.second->GetTensors();
names.insert(names.end(),
sub_names.begin(), sub_names.end());
......@@ -147,7 +147,7 @@ class Workspace {
if (!use_remote) return result;
// search remote workspace
for (auto& it : workspace_map_)
for (auto& it : ws_map_)
result |= it.second->HasFiller(name);
return result;
}
......@@ -167,7 +167,7 @@ class Workspace {
return &filler_map_[name];
// search remote workspace
for (auto& it : workspace_map_) {
for (auto& it : ws_map_) {
if (it.second->HasFiller(name))
return it.second->GetFiller(name);
}
......@@ -274,20 +274,23 @@ class Workspace {
/******************** Utility ********************/
inline void CreateRename(
const string& old_tensor,
const string& new_tensor) {
rename_map_[old_tensor] = new_tensor;
inline bool SetProxy(
const string& key,
const string& proxy) {
if (proxy_map_.count(key))
return proxy_map_[key] == proxy;
proxy_map_[key] = proxy;
return true;
}
private:
string name_;
WorkspaceMap workspace_map_;
WorkspaceMap ws_map_;
TensorMap tensor_map_;
OperatorMap op_map_;
GraphMap graph_map_;
FillerMap filler_map_;
RenameMap rename_map_;
ProxyMap proxy_map_;
};
} // namespace dragon
......
// ------------------------------------------------------------
// Copyright (c) 2017-present, SeetaTech, Co.,Ltd.
//
// Licensed under the BSD 2-Clause License.
// You should have received a copy of the BSD 2-Clause License
// along with the software. If not, See,
//
// <https://opensource.org/licenses/BSD-2-Clause>
//
// ------------------------------------------------------------
#ifndef DRAGON_OPERATORS_ARITHMETIC_ADD_OP_H_
#define DRAGON_OPERATORS_ARITHMETIC_ADD_OP_H_
#include "core/operator.h"
namespace dragon {
template <class Context>
class AddOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(AddOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class AddGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(AddGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RAddOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RAddOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RAddGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RAddGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
} // namespace dragon
#endif // DRAGON_OPERATORS_ARITHMETIC_ADD_OP_H_
\ No newline at end of file
......@@ -80,17 +80,17 @@ class CuDNNAffineOpBase : public Operator<Context> {
}
template <typename T>
void ResetDesc() {
void ResetDesc(const Tensor& X) {
// determine the range of affine
start_axis = axis;
if (start_axis < 0) start_axis += (int)Input(0).ndim();
if (num_axes == -1) num_axes = (int)Input(0).ndim() - start_axis;
if (start_axis < 0) start_axis += (int)X.ndim();
if (num_axes == -1) num_axes = (int)X.ndim() - start_axis;
else if (num_axes == 0) num_axes = 1;
end_axis = start_axis + num_axes;
CHECK_LT(start_axis, (int)Input(0).ndim());
CHECK_LE(start_axis + num_axes, (int)Input(0).ndim());
CHECK_LT(start_axis, (int)X.ndim());
CHECK_LE(start_axis + num_axes, (int)X.ndim());
// determine the input desc
vector<TIndex> input_dims = Input(0).dims();
vector<TIndex> input_dims = X.dims();
// cudnn requires ndimensions range from [4, 5]
if (input_dims.size() < 4) input_dims.resize(4, 1);
else if (input_dims.size() > 5)
......@@ -98,7 +98,8 @@ class CuDNNAffineOpBase : public Operator<Context> {
cudnnSetTensorDesc<T>(&input_desc, input_dims);
// determine the scale desc
vector<TIndex> param_dims(input_dims.size(), 1);
for (int i = start_axis; i < end_axis; i++) param_dims[i] = input_dims[i];
for (int i = start_axis; i < end_axis; i++)
param_dims[i] = input_dims[i];
cudnnSetTensorDesc<T>(&param_desc, param_dims);
}
......
// ------------------------------------------------------------
// Copyright (c) 2017-present, SeetaTech, Co.,Ltd.
//
// Licensed under the BSD 2-Clause License.
// You should have received a copy of the BSD 2-Clause License
// along with the software. If not, See,
//
// <https://opensource.org/licenses/BSD-2-Clause>
//
// ------------------------------------------------------------
#ifndef DRAGON_OPERATORS_ARITHMETIC_DIV_OP_H_
#define DRAGON_OPERATORS_ARITHMETIC_DIV_OP_H_
#include "core/operator.h"
namespace dragon {
template <class Context>
class DivOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(DivOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class DivGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(DivGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RDivOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RDivOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RDivGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RDivGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
} // namepsace dragon
#endif // DRAGON_OPERATORS_ARITHMETIC_DIV_OP_H_
\ No newline at end of file
// ------------------------------------------------------------
// Copyright (c) 2017-present, SeetaTech, Co.,Ltd.
//
// Licensed under the BSD 2-Clause License.
// You should have received a copy of the BSD 2-Clause License
// along with the software. If not, See,
//
// <https://opensource.org/licenses/BSD-2-Clause>
//
// ------------------------------------------------------------
#ifndef DRAGON_OPERATORS_ARITHMETIC_FUNDAMENTAL_OP_H_
#define DRAGON_OPERATORS_ARITHMETIC_FUNDAMENTAL_OP_H_
#include "core/operator.h"
namespace dragon {
/*********************************************
* *
* Add *
* *
**********************************************/
template <class Context>
class AddOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(AddOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class AddGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(AddGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
protected:
Tensor *X1, *X2;
};
/*********************************************
* *
* RAdd *
* *
**********************************************/
template <class Context>
class RAddOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RAddOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RAddGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RAddGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
/*********************************************
* *
* Sub *
* *
**********************************************/
template <class Context>
class SubOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(SubOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class SubGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(SubGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
/*********************************************
* *
* RSub *
* *
**********************************************/
template <class Context>
class RSubOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RSubOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RSubGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RSubGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
/*********************************************
* *
* Mul *
* *
**********************************************/
template <class Context>
class MulOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(MulOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class MulGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(MulGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
/*********************************************
* *
* RMul *
* *
**********************************************/
template <class Context>
class RMulOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RMulOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RMulGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RMulGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
/*********************************************
* *
* Div *
* *
**********************************************/
template <class Context>
class DivOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(DivOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class DivGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(DivGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
/*********************************************
* *
* RDiv *
* *
**********************************************/
template <class Context>
class RDivOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RDivOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RDivGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RDivGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
#define DeclareX1X2 \
ws()->CreateTensor( \
"/mnt/" + anchor() + "/fundamental/X1") \
->ReshapeLike(Input(0)); \
ws()->CreateTensor( \
"/mnt/" + anchor() + "/fundamental/X2") \
->ReshapeLike(Input(1))
#define DefineX1X2 \
Tensor* X1 = ws()->GetTensor( \
"/mnt/" + anchor() + "/fundamental/X1"); \
Tensor* X2 = ws()->GetTensor( \
"/mnt/" + anchor() + "/fundamental/X2")
#define RunByX1X2(dtype) \
DefineX1X2; \
if (X1->dims() == X2->dims()) { \
EltwiseRunWithType<dtype>(); \
} else if (X1->dim(0) == X2->dim(0) && \
X2->count(1) == 1) { \
BroadcastRunWithType<dtype>(2); \
} else if (X1->dim(-1) == X2->dim(-1) && \
X2->count(0, X2->axis(-1)) == 1) { \
BroadcastRunWithType<dtype>(1); \
} else if (X2->ndim() == 1 && X2->dim(0) == 1) { \
BroadcastRunWithType<dtype>(0); \
} else { \
LOG(FATAL) << "Could not broadcast with shapes " \
<< X1->DimString() << " " \
<< X2->DimString(); \
}
#define RRunByX1X2(dtype) \
DefineX1X2; \
if (X1->dims() == X2->dims()) { \
EltwiseRunWithType<dtype>(); \
} else if (X1->dim(0) == X2->dim(0) && \
X1->count(1) == 1) { \
BroadcastRunWithType<dtype>(2); \
} else if (X1->dim(-1) == X2->dim(-1) && \
X1->count(0, X1->axis(-1)) == 1) { \
BroadcastRunWithType<dtype>(1); \
} else if (X1->ndim() == 1 && X1->dim(0) == 1) { \
BroadcastRunWithType<dtype>(0); \
} else { \
LOG(FATAL) << "Could not broadcast with shapes " \
<< X1->DimString() << " " \
<< X2->DimString(); \
}
} // namespace dragon
#endif // DRAGON_OPERATORS_ARITHMETIC_FUNDAMENTAL_OP_H_
\ No newline at end of file
// ------------------------------------------------------------
// Copyright (c) 2017-present, SeetaTech, Co.,Ltd.
//
// Licensed under the BSD 2-Clause License.
// You should have received a copy of the BSD 2-Clause License
// along with the software. If not, See,
//
// <https://opensource.org/licenses/BSD-2-Clause>
//
// ------------------------------------------------------------
#ifndef DRAGON_OPERATORS_ARITHMETIC_MUL_OP_H_
#define DRAGON_OPERATORS_ARITHMETIC_MUL_OP_H_
#include "core/operator.h"
namespace dragon {
template <class Context>
class MulOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(MulOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class MulGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(MulGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RMulOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RMulOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RMulGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RMulGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
} // namespace dragon
#endif // DRAGON_OPERATORS_ARITHMETIC_MUL_OP_H_
\ No newline at end of file
// ------------------------------------------------------------
// Copyright (c) 2017-present, SeetaTech, Co.,Ltd.
//
// Licensed under the BSD 2-Clause License.
// You should have received a copy of the BSD 2-Clause License
// along with the software. If not, See,
//
// <https://opensource.org/licenses/BSD-2-Clause>
//
// ------------------------------------------------------------
#ifndef DRAGON_OPERATORS_ARITHMETIC_SUB_OP_H_
#define DRAGON_OPERATORS_ARITHMETIC_SUB_OP_H_
#include "core/operator.h"
namespace dragon {
template <class Context>
class SubOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(SubOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class SubGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(SubGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RSubOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RSubOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
template <class Context>
class RSubGradientOp final : public Operator<Context> {
public:
USE_SIMPLE_CTOR_DTOR(RSubGradientOp);
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void EltwiseRunWithType();
template <typename T> void BroadcastRunWithType(int type);
};
} // namespace dragon
#endif // DRAGON_OPERATORS_ARITHMETIC_SUB_OP_H_
\ No newline at end of file
......@@ -17,9 +17,12 @@
namespace dragon {
template <class Context>
class SigmoidCrossEntropyOp final : public Operator<Context> {
class SigmoidCrossEntropyOp
final : public Operator<Context> {
public:
SigmoidCrossEntropyOp(const OperatorDef& def, Workspace* ws)
SigmoidCrossEntropyOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
normalization(OperatorBase::Arg<string>(
"normalization", "VALID")) {}
......@@ -29,14 +32,17 @@ class SigmoidCrossEntropyOp final : public Operator<Context> {
template <typename T> void RunWithType();
protected:
Tensor valid, losses;
Tensor losses, flags;
string normalization;
};
template <class Context>
class SigmoidCrossEntropyGradientOp final : public Operator<Context> {
class SigmoidCrossEntropyGradientOp
final : public Operator<Context> {
public:
SigmoidCrossEntropyGradientOp(const OperatorDef& def, Workspace* ws)
SigmoidCrossEntropyGradientOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
normalization(OperatorBase::Arg<string>(
"normalization", "VALID")) {}
......@@ -46,7 +52,7 @@ class SigmoidCrossEntropyGradientOp final : public Operator<Context> {
template <typename T> void RunWithType();
protected:
Tensor valid;
Tensor flags;
string normalization;
};
......
// ------------------------------------------------------------
// Copyright (c) 2017-present, SeetaTech, Co.,Ltd.
//
// Licensed under the BSD 2-Clause License.
// You should have received a copy of the BSD 2-Clause License
// along with the software. If not, See,
//
// <https://opensource.org/licenses/BSD-2-Clause>
//
// -------------------------------------------------------------
#ifndef DRAGON_OPERATORS_LOSS_SIGMOID_FOCAL_LOSS_OP_H_
#define DRAGON_OPERATORS_LOSS_SIGMOID_FOCAL_LOSS_OP_H_
#include "core/operator.h"
namespace dragon {
template <class Context>
class SigmoidFocalLossOp
final : public Operator<Context> {
public:
SigmoidFocalLossOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
"normalization", "VALID")),
alpha(OperatorBase::Arg<float>("alpha", 0.25f)),
gamma(OperatorBase::Arg<float>("gamma", 2.f)),
neg_id(OperatorBase::Arg<int>("neg_id", 0)) {
pos_alpha = alpha;
neg_alpha = 1.f - alpha;
}
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void RunWithType();
protected:
float alpha, gamma, pos_alpha, neg_alpha;
TIndex axis, neg_id, outer_dim, axis_dim, inner_dim;
Tensor losses, flags;
string normalization;
};
template <class Context>
class SigmoidFocalLossGradientOp
final : public Operator<Context> {
public:
SigmoidFocalLossGradientOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
"normalization", "VALID")),
alpha(OperatorBase::Arg<float>("alpha", 0.25f)),
gamma(OperatorBase::Arg<float>("gamma", 2.f)),
neg_id(OperatorBase::Arg<int>("neg_id", 0)) {
pos_alpha = alpha;
neg_alpha = 1.f - alpha;
}
USE_OPERATOR_FUNCTIONS;
void RunOnDevice() override;
template <typename T> void RunWithType();
protected:
float alpha, gamma, pos_alpha, neg_alpha;
TIndex axis, neg_id, outer_dim, axis_dim, inner_dim;
Tensor flags;
string normalization;
};
} // namespace dragon
#endif // DRAGON_OPERATORS_LOSS_SIGMOID_FOCAL_LOSS_OP_H_
\ No newline at end of file
......@@ -17,9 +17,12 @@
namespace dragon {
template <class Context>
class SoftmaxCrossEntropyOp final : public Operator<Context> {
class SoftmaxCrossEntropyOp
final : public Operator<Context> {
public:
SoftmaxCrossEntropyOp(const OperatorDef& def, Workspace* ws)
SoftmaxCrossEntropyOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
......@@ -39,9 +42,12 @@ class SoftmaxCrossEntropyOp final : public Operator<Context> {
};
template <class Context>
class SoftmaxCrossEntropyGradientOp final : public Operator<Context> {
class SoftmaxCrossEntropyGradientOp
final : public Operator<Context> {
public:
SoftmaxCrossEntropyGradientOp(const OperatorDef& def, Workspace* ws)
SoftmaxCrossEntropyGradientOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
......
......@@ -9,18 +9,20 @@
//
// -------------------------------------------------------------
#ifndef DRAGON_OPERATORS_LOSS_SPARSE_SOFTMAX_FOCAL_LOSS_OP_H_
#define DRAGON_OPERATORS_LOSS_SPARSE_SOFTMAX_FOCAL_LOSS_OP_H_
#ifndef DRAGON_OPERATORS_LOSS_SOFTMAX_FOCAL_LOSS_OP_H_
#define DRAGON_OPERATORS_LOSS_SOFTMAX_FOCAL_LOSS_OP_H_
#include "operators/loss/sparse_softmax_cross_entropy_op.h"
namespace dragon {
template <class Context>
class SparseSoftmaxFocalLossOp final
: public SparseSoftmaxCrossEntropyOp<Context> {
class SoftmaxFocalLossOp
final : public SparseSoftmaxCrossEntropyOp<Context> {
public:
SparseSoftmaxFocalLossOp(const OperatorDef& def, Workspace* ws)
SoftmaxFocalLossOp(
const OperatorDef& def,
Workspace* ws)
: SparseSoftmaxCrossEntropyOp<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
......@@ -44,10 +46,12 @@ class SparseSoftmaxFocalLossOp final
};
template <class Context>
class SparseSoftmaxFocalLossGradientOp final
: public SparseSoftmaxCrossEntropyGradientOp<Context> {
class SoftmaxFocalLossGradientOp
final : public SparseSoftmaxCrossEntropyGradientOp<Context> {
public:
SparseSoftmaxFocalLossGradientOp(const OperatorDef& def, Workspace* ws)
SoftmaxFocalLossGradientOp(
const OperatorDef& def,
Workspace* ws)
: SparseSoftmaxCrossEntropyGradientOp<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
......@@ -72,4 +76,4 @@ class SparseSoftmaxFocalLossGradientOp final
} // namespace dragon
#endif // DRAGON_OPERATORS_LOSS_SPARSE_SOFTMAX_FOCAL_LOSS_OP_H_
\ No newline at end of file
#endif // DRAGON_OPERATORS_LOSS_SOFTMAX_FOCAL_LOSS_OP_H_
\ No newline at end of file
......@@ -19,7 +19,9 @@ namespace dragon {
template <class Context>
class SparseSoftmaxCrossEntropyOp : public Operator<Context> {
public:
SparseSoftmaxCrossEntropyOp(const OperatorDef& def, Workspace* ws)
SparseSoftmaxCrossEntropyOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
......@@ -47,9 +49,12 @@ class SparseSoftmaxCrossEntropyOp : public Operator<Context> {
};
template <class Context>
class SparseSoftmaxCrossEntropyGradientOp : public Operator<Context> {
class SparseSoftmaxCrossEntropyGradientOp
: public Operator<Context> {
public:
SparseSoftmaxCrossEntropyGradientOp(const OperatorDef& def, Workspace* ws)
SparseSoftmaxCrossEntropyGradientOp(
const OperatorDef& def,
Workspace* ws)
: Operator<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 1)),
normalization(OperatorBase::Arg<string>(
......
......@@ -29,6 +29,7 @@ class RunOp : public Operator<Context> {
void RunOnDevice() override;
protected:
string CallMethodHelper(const string& method);
PyObject* self, *inputs, *outputs;
string module, op, param_str;
};
......
......@@ -52,7 +52,7 @@ class InstanceNormGradientOp final : public Operator<Context> {
USE_OPERATOR_FUNCTIONS;
void Setup();
void RunOnDevice() override;
template <typename T> void RunWithType();
......
......@@ -23,7 +23,7 @@ class L2NormOp final : public Operator<Context> {
: Operator<Context>(def, ws),
axis(OperatorBase::Arg<int>("axis", 0)),
num_axes(OperatorBase::Arg<int>("num_axes", -1)),
eps(OperatorBase::Arg<float>("eps", 1e-5f)),
eps(OperatorBase::Arg<float>("eps", 1e-3f)),
mode(OperatorBase::Arg<string>("mode", "SUM")) {}
USE_OPERATOR_FUNCTIONS;
......
......@@ -247,18 +247,52 @@ void AbsGrad(
template <typename T, class Context>
void SigmoidCrossEntropy(
const int count,
const T* x,
const T* target,
T* loss,
T* valid);
const T* logits,
const T* targets,
T* losses,
T* flags,
Context* ctx);
template <typename T, class Context>
void SigmoidCrossEntropyGrad(
const int count,
const T* x,
const T* target,
T* dx,
T* valid);
const T* logits,
const T* targets,
T* dlogits,
T* flags,
Context* ctx);
/******************** loss.sigmoid_focal_loss ********************/
template <typename T, class Context>
void SigmoidFocalLoss(
const int outer_dim,
const int axis_dim,
const int inner_dim,
const float pos_alpha,
const float neg_alpha,
const float gamma,
const int neg_id,
const float* logits,
const float* targets,
float* losses,
float* flags,
Context* ctx);
template <typename T, class Context>
void SigmoidFocalLossGradient(
const int outer_dim,
const int axis_dim,
const int inner_dim,
const float pos_alpha,
const float neg_alpha,
const float gamma,
const int neg_id,
const float* logits,
const float* targets,
float* dlogits,
float* flags,
Context* ctx);
/******************** loss.smooth_l1_loss ********************/
......@@ -285,38 +319,10 @@ void SoftmaxCrossEntropy(
const T* target,
T* loss);
/******************** loss.sparse_softmax_cross_entropy ********************/
template <typename Tx, typename Ty, class Context>
void SparseSoftmaxCrossEntropy(
const int outer_dim,
const int axis_dim,
const int inner_dim,
const Tx* prob,
const Ty* labels,
const int* ignores,
const int num_ignores,
Tx* losses,
Tx* flags,
Context* ctx);
template <typename Tx, typename Ty, class Context>
void SparseSoftmaxCrossEntropyGrad(
const int outer_dim,
const int axis_dim,
const int inner_dim,
const Tx* prob,
const Ty* labels,
const int* ignores,
const int num_ignores,
Tx* dx,
Tx* flags,
Context* ctx);
/******************** loss.sparse_softmax_focal_loss ********************/
/******************** loss.softmax_focal_loss ********************/
template <typename T, class Context>
void SparseSoftmaxFocalLoss(
void SoftmaxFocalLoss(
const int outer_dim,
const int axis_dim,
const int inner_dim,
......@@ -329,11 +335,11 @@ void SparseSoftmaxFocalLoss(
const int* ignores,
const int num_ignores,
T* losses,
T* flags ,
T* flags,
Context* ctx);
template <typename T, class Context>
void SparseSoftmaxFocalLossGrad(
void SoftmaxFocalLossGrad(
const int outer_dim,
const int axis_dim,
const int inner_dim,
......@@ -349,6 +355,34 @@ void SparseSoftmaxFocalLossGrad(
T* flags,
Context* ctx);
/******************** loss.sparse_softmax_cross_entropy ********************/
template <typename Tx, typename Ty, class Context>
void SparseSoftmaxCrossEntropy(
const int outer_dim,
const int axis_dim,
const int inner_dim,
const Tx* prob,
const Ty* labels,
const int* ignores,
const int num_ignores,
Tx* losses,
Tx* flags,
Context* ctx);
template <typename Tx, typename Ty, class Context>
void SparseSoftmaxCrossEntropyGrad(
const int outer_dim,
const int axis_dim,
const int inner_dim,
const Tx* prob,
const Ty* labels,
const int* ignores,
const int num_ignores,
Tx* dx,
Tx* flags,
Context* ctx);
/******************** misc.astype ********************/
template <typename Ta, typename Tb, class Context>
......
......@@ -69,7 +69,7 @@ inline PyObject* RenameTensorCC(PyObject* self, PyObject* args) {
PyErr_SetString(PyExc_ValueError, err_msg.c_str());
return nullptr;
}
ws()->CreateRename(ori_name, tar_name);
ws()->SetProxy(ori_name, tar_name);
Py_RETURN_TRUE;
}
......
......@@ -947,6 +947,7 @@ class Tensor(object):
Examples
--------
>>> import dragon as dg
>>> a = Tensor().Variable()
>>> b = Tensor().Variable()
>>> c = Tensor.CreateOperator(inputs=[a, b], op_type='Add', nout=1)
......@@ -956,12 +957,10 @@ class Tensor(object):
>>> c = Tensor().Variable()
>>> c = Tensor.CreateOperator(inputs=[a, b], op_type='Add', existing_outputs=c)
>>> import dragon.core.workspace as ws
>>> import dragon.vm.theano as theano
>>> dynamic_shape = Tensor().Variable()
>>> ws.FeedTensor(dynamic_shape, [1, 2, 3, 4])
>>> a = ops.Fill(shape=dynamic_shape, value=5.0)
>>> print theano.function(outputs=a)
>>> dg.workspace.FeedTensor(dynamic_shape, [1, 2, 3, 4])
>>> a = dg.Fill(shape=dynamic_shape, value=5.0)
>>> print dg.function(outputs=a)
>>> [[ 5. 5. 5.]
[ 5. 5. 5.]]
......
......@@ -450,7 +450,7 @@ def FetchTensor(tensor):
return FetchTensorCC(_stringify_tensor(tensor))
def FeedTensor(tensor, ndarray, force_cpu=False, dtype=None):
def FeedTensor(tensor, array, force_cpu=False, dtype=None):
"""Feed the values to the given tensor.
Parameters
......@@ -461,8 +461,8 @@ def FeedTensor(tensor, ndarray, force_cpu=False, dtype=None):
The values to feed.
force_cpu : boolean
Whether force to feed to cpu context.
dtype : np.dtype or None
The data type. If ``None``, np.float32 will be used instead.
dtype : str
The data type. If ``None``, ``float32`` will be used instead.
Returns
-------
......@@ -470,14 +470,14 @@ def FeedTensor(tensor, ndarray, force_cpu=False, dtype=None):
Examples
--------
>>> import dragon.core.workspace as ws
>>> a = Tensor().Variable()
>>> ws.FeedTensor(a, 1)
>>> a_value = ws.FetchTensor(a)
>>> import dragon as dg
>>> a = dg.Tensor().Variable()
>>> dg.workspace.FeedTensor(a, 1)
>>> a_value = dg.workspace.FetchTensor(a)
>>> a_value, a_value.dtype
>>> [ 1.], float32
>>> ws.FeedTensor(a, [[1, 2, 3]], dtype=np.float16)
>>> dg.workspace.FeedTensor(a, [[1, 2, 3]], dtype='float16')
>>> a_value = a.get_value()
>>> a_value, a_value.dtype
>>> [[ 1. 2. 3.]], float16
......@@ -504,24 +504,24 @@ def FeedTensor(tensor, ndarray, force_cpu=False, dtype=None):
elif option['device'] == 'CPU':
dev = utils.MakeDeviceOption(0, 0)
if not isinstance(ndarray, np.ndarray):
if not isinstance(ndarray, list):
ndarray = [ndarray]
auto_dtype = np.float32 if dtype is None else dtype
if not isinstance(array, np.ndarray):
if not isinstance(array, list):
array = [array]
auto_data_type = np.float32 if dtype is None else dtype
else:
auto_dtype = ndarray.dtype if dtype is None else dtype
auto_data_type = array.dtype if dtype is None else dtype
if hasattr(tensor, 'dtype') and tensor.dtype is not None:
if tensor.dtype not in _DATA_TYPES:
raise TypeError('Unsupported data types: {}.'.format(tensor.dtype))
preset_dtype = _DATA_TYPES[tensor.dtype]
preset_data_type = _DATA_TYPES[tensor.dtype]
if dtype is not None:
if dtype != preset_dtype:
if dtype != preset_data_type:
raise TypeError('The preset data type is {}, but force to {}.'.
format(preset_dtype, dtype))
auto_dtype = preset_dtype
ndarray = np.array(ndarray, dtype=auto_dtype, copy=False)
FeedTensorCC(name, ndarray, _stringify_proto(dev))
format(preset_data_type, dtype))
auto_data_type = preset_data_type
nd_array = np.array(array, dtype=auto_data_type, copy=False)
FeedTensorCC(name, nd_array, _stringify_proto(dev))
stages = {
......@@ -729,7 +729,10 @@ def ExportMetaGraph(meta_graph):
logger.info('Export meta graph into: {}'.format(filepath))
def Snapshot(tensors, filename, prefix='', suffix='.bin', format='default'):
def Snapshot(
tensors, filename,
prefix='', suffix='.bin',
format='default'):
"""Snapshot tensors into a binary file.
Parameters
......@@ -751,42 +754,42 @@ def Snapshot(tensors, filename, prefix='', suffix='.bin', format='default'):
Notes
-----
The full filepath will be: ``prefix`` + ``filename`` + ``suffix``.
The full file path will be: ``prefix`` + ``filename`` + ``suffix``.
Available formats: ['default', 'caffe'].
"""
from dragon.config import logger
filepath = prefix + filename + suffix
file_path = prefix + filename + suffix
if mpi.Is_Init():
if not mpi.AllowSnapshot(): return
filepath = filepath + '.rank.{}'.format(mpi.Rank())
file_path = file_path + '.rank.{}'.format(mpi.Rank())
dir = os.path.split(filepath)[0]
dir = os.path.split(file_path)[0]
if len(dir) > 0 and not os.path.exists(dir): os.makedirs(dir)
if format == 'default':
content = {}
state_dict = {}
for tensor in tensors:
content[tensor.name] = FetchTensor(tensor)
with open(filepath, 'wb') as f:
cPickle.dump(content, f, cPickle.HIGHEST_PROTOCOL)
logger.info('Snapshot Model@: ' + filepath)
state_dict[tensor.name] = FetchTensor(tensor)
with open(file_path, 'wb') as f:
cPickle.dump(state_dict, f, cPickle.HIGHEST_PROTOCOL)
logger.info('Snapshot Model@: ' + file_path)
logger.info('Model Format: cPickle')
elif format is 'caffe':
names = [tensor.name for tensor in tensors]
SnapshotCC(filepath, names, 1)
SnapshotCC(file_path, names, 1)
else: raise TypeError('Unknown binary format: {}'.format(format))
def Restore(filepath, format='default'):
def Restore(binary_file, format='default'):
"""Restore tensors from a binary file.
Parameters
----------
filepath : str
binary_file : str
The path of binary file.
format : str
The format of this binary file.
......@@ -801,25 +804,27 @@ def Restore(filepath, format='default'):
"""
from dragon.config import logger
assert os.path.exists(filepath), 'model of path({}) does not exist.'.format(filepath)
assert os.path.exists(binary_file), \
'Binary file({}) does not exist.'.format(binary_file)
if format == 'default':
try:
content = cPickle.load(open(filepath, 'rb'))
state_dict = cPickle.load(open(binary_file, 'rb'))
except UnicodeDecodeError:
content = cPickle.load(open(filepath, 'rb'), encoding='iso-8859-1')
logger.info('Restore From Model@: ' + filepath)
state_dict = cPickle.load(open(binary_file, 'rb'), encoding='iso-8859-1')
logger.info('Restore From Model@: ' + binary_file)
logger.info('Model Format: cPickle')
for key, ndarray in content.items():
if not HasTensor(key):
logger.info('[Warning]: Tensor({}) of model does not exist in any Graphs, skip.'.format(key))
for k, v in state_dict.items():
if not HasTensor(k):
logger.info('[Warning]: Tensor({}) does not exist in any Graphs, skip.'.format(k))
else:
logger.info('[Info]: Tensor({}) restored.'.format(key))
FeedTensor(key, ndarray)
FeedTensor(k, v)
logger.info('[Info]: Tensor({}) is restored.'.format(k))
elif format == 'caffe':
# TODO(PhyscalX): caffemodel can't save the tensor name
# TODO(PhyscalX): caffe models can't save the tensor name
# TODO(PhyscalX): we simply use layer_name + @paramX
RestoreCC(filepath, 1)
RestoreCC(binary_file, 1)
else:
raise TypeError('Unknown binary format: {}'.format(format))
\ No newline at end of file
......@@ -63,13 +63,12 @@ def Drop(op_func, *args, **kwargs):
Examples
--------
>>> from dragon.core.tensor import Tensor
>>> import dragon.ops as ops
>>> import dragon as dg
>>> import dragon.memonger as opt
>>> data = Tensor().Variable()
>>> conv_1 = ops.Conv2d(data, num_output=8)
>>> conv_1_bn = opt.Drop(ops.BatchNorm, [conv_1, Tensor().Variable(), Tensor.Variable()])
>>> conv_1_relu = opt.Drop(ops.Relu, conv_1_bn)
>>> data = dg.Tensor().Variable()
>>> conv_1 = dg.Conv2d(data, num_output=8)
>>> conv_1_bn = opt.Drop(dg.BatchNorm, [conv_1, dg.Tensor().Variable(), dg.Tensor.Variable()])
>>> conv_1_relu = opt.Drop(dg.Relu, conv_1_bn)
"""
kwargs['mirror_stage'] = True
......
......@@ -217,8 +217,53 @@ def L2Loss(inputs, normalization='BATCH_SIZE', **kwargs):
return output
def SparseSoftmaxFocalLoss(inputs, axis=1, normalization='VALID', ignore_labels=(),
alpha=0.25, gamma=2.0, neg_id=0, **kwargs):
def SigmoidFocalLoss(inputs, axis=1, normalization='VALID',
alpha=0.25, gamma=2.0, neg_id=0, **kwargs):
"""SoftmaxFocalLoss with sparse labels. `[Lin et.al, 2017] <https://arxiv.org/abs/1708.02002>`_.
Parameters
----------
inputs : list of Tensor
The inputs, represent [input, sparse_labels].
axis : int
The axis of softmax function.
normalization : str
The normalization, ``UNIT``, ``FULL``, ``VALID``, ``BATCH_SIZE`` or ``NONE``.
alpha : float
The scale factor on the rare class. Default is ``0.25``.
gamma : float
The exponential decay factor on the easy examples. Default is ``2.0``.
neg_id : int
The negative id. Default is ``0``.
Returns
-------
Tensor
The loss.
Notes
-----
Set the normalization to ``UNIT`` will return unreduced losses.
"""
CheckInputs(inputs, 2)
arguments = ParseArguments(locals())
output = Tensor.CreateOperator(nout=1, op_type='SigmoidFocalLoss', **arguments)
if inputs[0].shape is not None:
if normalization != 'UNIT': output.shape = [1]
elif all(dim is not None for dim in inputs[0].shape):
outer_dim = int(np.prod(inputs[0].shape[0 : axis]))
inner_dim = int(np.prod(inputs[0].shape[axis + 1 :]))
output.shape = [outer_dim * inner_dim]
else: output.shape = [None]
return output
def SoftmaxFocalLoss(inputs, axis=1, normalization='VALID', ignore_labels=(),
alpha=0.25, gamma=2.0, neg_id=0, **kwargs):
"""SoftmaxFocalLoss with sparse labels. `[Lin et.al, 2017] <https://arxiv.org/abs/1708.02002>`_.
Parameters
......@@ -251,7 +296,7 @@ def SparseSoftmaxFocalLoss(inputs, axis=1, normalization='VALID', ignore_labels=
CheckInputs(inputs, 2)
arguments = ParseArguments(locals())
output = Tensor.CreateOperator(nout=1, op_type='SparseSoftmaxFocalLoss', **arguments)
output = Tensor.CreateOperator(nout=1, op_type='SoftmaxFocalLoss', **arguments)
if inputs[0].shape is not None:
if normalization != 'UNIT': output.shape = [1]
......
......@@ -76,7 +76,8 @@ SoftmaxCrossEntropy = loss.SoftmaxCrossEntropy
SmoothL1Loss = loss.SmoothL1Loss
L1Loss = loss.L1Loss
L2Loss = loss.L2Loss
SparseSoftmaxFocalLoss = loss.SparseSoftmaxFocalLoss
SigmoidFocalLoss = loss.SigmoidFocalLoss
SoftmaxFocalLoss = loss.SoftmaxFocalLoss
CTCLoss = loss.CTCLoss
# arithmetic
......
......@@ -14,7 +14,7 @@ from __future__ import division
from __future__ import print_function
version = '0.2.2'
full_version = '0.2.2.7'
full_version = '0.2.2.8'
release = False
if not release:
......
......@@ -34,6 +34,7 @@ from .loss import SoftmaxWithLossLayer, \
SigmoidCrossEntropyLossLayer, \
L2LossLayer, \
SmoothL1LossLayer, \
SigmoidWithFocalLossLayer, \
SoftmaxWithFocalLossLayer
from .mpi import MPIBroadcastLayer,\
......
......@@ -138,6 +138,48 @@ class SmoothL1LossLayer(Layer):
return loss
class SigmoidWithFocalLossLayer(Layer):
"""The implementation of ``SigmoidWithFocalLossLayer``.
Parameters
----------
axis : int
The axis of softmax. Refer `SoftmaxParameter.axis`_.
alpha : float
The scale on the rare class. Refer `FocalLossParameter.alpha`_.
gamma : float
The exponential decay. Refer `FocalLossParameter.gamma`_.
neg_id : int
The negative id. Refer `FocalLossParameter.neg_id`_.
normalization : NormalizationMode
The normalization. Refer `LossParameter.normalization`_.
normalize : boolean
Whether to normalize. Refer `LossParameter.normalize`_.
"""
def __init__(self, LayerParameter):
super(SigmoidWithFocalLossLayer, self).__init__(LayerParameter)
param = LayerParameter.loss_param
softmax_param = LayerParameter.softmax_param
focal_loss_param = LayerParameter.focal_loss_param
norm_mode = {0: 'FULL', 1: 'VALID', 2: 'BATCH_SIZE', 3: 'NONE', 4: 'UNIT'}
normalization = 'VALID'
if param.HasField('normalize'):
if not param.normalize: normalization = 'BATCH_SIZE'
else: normalization = norm_mode[param.normalization]
self._param = {'axis': softmax_param.axis,
'normalization': normalization,
'alpha': float(focal_loss_param.alpha),
'gamma': float(focal_loss_param.gamma),
'neg_id': focal_loss_param.neg_id}
def Setup(self, bottom):
super(SigmoidWithFocalLossLayer, self).Setup(bottom)
loss = ops.SigmoidFocalLoss(bottom, **self._param)
if self._loss_weight is not None: loss *= self._loss_weight
return loss
class SoftmaxWithFocalLossLayer(Layer):
"""The implementation of ``SoftmaxWithFocalLossLayer``.
......@@ -176,6 +218,6 @@ class SoftmaxWithFocalLossLayer(Layer):
def Setup(self, bottom):
super(SoftmaxWithFocalLossLayer, self).Setup(bottom)
loss = ops.SparseSoftmaxFocalLoss(bottom, **self._param)
loss = ops.SoftmaxFocalLoss(bottom, **self._param)
if self._loss_weight is not None: loss *= self._loss_weight
return loss
\ No newline at end of file
......@@ -34,12 +34,12 @@ class Net(object):
especially when extending the modern architectures of `ConvNets`.
"""
def __init__(self, *args):
"""Construct a Net by the ``prototxt`` file.
"""Construct a Net by the ``proto_txt`` file.
Parameters
----------
prototxt : str
The path of ``.prototxt`` file.
proto_txt : str
The path of ``.proto_txt`` file.
model : str
(Optional) The path of the ``.caffemodel`` file.
phase : str
......@@ -58,22 +58,22 @@ class Net(object):
References
----------
`NetInit(prototxt, phase)`_ - Construct a Net.
`NetInit(proto_txt, phase)`_ - Construct a Net.
`NetInitLoad(prototxt, model, phase)`_ - Construct a Net and load the model.
`NetInitLoad(proto_txt, model, phase)`_ - Construct a Net and load the model.
"""
if len(args) == 2:
self.NetInit(args[0], args[1])
else: self.NetInitLoad(args[0], args[1], args[2])
def NetInit(self, prototxt, phase='TRAIN'):
"""Construct a Net by the ``prototxt`` file.
def NetInit(self, proto_txt, phase='TRAIN'):
"""Construct a Net by the ``proto_txt`` file.
Parameters
----------
prototxt : str
The path of ``.prototxt`` file.
proto_txt : str
The path of ``proto_txt`` file.
phase : str
The phase, ``TRAIN`` or ``TEST``.
......@@ -88,11 +88,11 @@ class Net(object):
"""
self._net = pb.NetParameter()
Parse(open(prototxt,'r').read(), self._net)
Parse(open(proto_txt,'r').read(), self._net)
self._phase = phase
self._layers = []
if not hasattr(self, '_blobs'): self._blobs = {}
self._params = {};
self._params = {}
self._swap_tensors = {}
self._inputs_to_tensors = {}
self._costs = []; self._wrts = []
......@@ -115,13 +115,13 @@ class Net(object):
if not self.FilterLayer(layer): continue
self.CheckBackward(layer)
def NetInitLoad(self, prototxt, model, phase='TRAIN'):
"""Construct a Net by the ``prototxt`` file.
def NetInitLoad(self, proto_txt, model, phase='TRAIN'):
"""Construct a Net by the ``proto_txt`` file.
Parameters
----------
prototxt : str
The path of ``.prototxt`` file.
proto_txt : str
The path of ``proto_txt`` file.
model : str
(Optional) The path of the ``.caffemodel`` file.
phase : str
......@@ -137,7 +137,7 @@ class Net(object):
The implementation of `Net_Init_Load(_caffe.cpp, L137)`_.
"""
self.NetInit(prototxt, phase)
self.NetInit(proto_txt, phase)
self._model = model # lazy-loading model
def FilterLayer(self, LayerParameter):
......@@ -518,7 +518,7 @@ class Net(object):
Examples
--------
>>> import dragon.core.workspace as ws
>>> ws.Snapshot(net.store_params(), filename='xxx', suffix='.caffeomdel')
>>> ws.Snapshot(self.store_params(), filename='xxx', suffix='.caffeomdel')
"""
params = []
......@@ -577,8 +577,8 @@ class Net(object):
--------
>>> import dragon.ops as ops
>>> data, label = ops.LMDBData()
>>> net.replace(net.blobs['data'].data, data)
>>> net.replace(net.blobs['label'].data, label)
>>> self.replace(self.blobs['data'].data, data)
>>> self.replace(self.blobs['label'].data, label)
"""
self._swap_tensors[A] = B
......@@ -590,7 +590,7 @@ class PartialNet(Net):
Examples
--------
>>> from dragon.core.tensor import Tensor
>>> net = PartialNet('xxx.prototxt', 'TEST', **{'blob_name': Tensor().Variable()})
>>> net = PartialNet('xxx.proto_txt', 'TEST', **{'blob_name': Tensor().Variable()})
"""
def __init__(self, *args, **kwargs):
......
......@@ -1456,7 +1456,7 @@ message NormalizeParameter {
// Whether or not scale parameters are shared across channels.
optional bool channel_shared = 3 [default = true];
// Epsilon for not dividing by zero while normalizing variance
optional float eps = 4 [default = 1e-10];
optional float eps = 4 [default = 1e-3];
}
message ParallelParameter {
......
......@@ -42,7 +42,7 @@ find_modules()
setup(name = 'dragon',
version='0.2.2.7',
version='0.2.2.8',
description = 'Dragon: A Computation Graph Virtual Machine Based Deep Learning Framework',
url='https://github.com/seetaresearch/Dragon',
author='Ting Pan',
......
......@@ -56,10 +56,14 @@ void Graph::ForwardShareDyeing(string u, string ancestor) {
if (renamed_.count(u)) return;
renamed_[u] = ancestor;
if (dag_[u].childs.size() == 1) {
string op_type = dag_[dag_[u].childs[0]].op_type;
auto* schema = OpSchemaRegistry::Schema(op_type);
auto& v = dag_[u].childs[0];
auto& op_def = dag_[v].op_def;
auto* schema = OpSchemaRegistry::Schema(op_def.type());
if (schema->AllowInplace())
ForwardShareDyeing(dag_[u].childs[0], ancestor);
for (int i = 0; i < op_def.input_size(); i++)
if (op_def.input(i) == u &&
schema->CheckInplace(i, 0))
ForwardShareDyeing(v, ancestor);
}
}
......@@ -95,7 +99,7 @@ void Graph::BackwardPruneDyeing(string v) {
GraphDef Graph::Prune(const GraphDef& meta_graph) {
dag_.clear(); colored_.clear();
// build Graph
// build DAG
for (int i = 0; i < meta_graph.op_size(); i++) {
const OperatorDef& op = meta_graph.op(i);
for (auto& v : op.output()) {
......@@ -108,7 +112,7 @@ GraphDef Graph::Prune(const GraphDef& meta_graph) {
dag_[u].childs.push_back(v);
dag_[v].op_idx = i;
}
dag_[v].op_type = op.type();
dag_[v].op_def = op;
}
}
......@@ -150,7 +154,7 @@ GraphDef Graph::Prune(const GraphDef& meta_graph) {
// check if having feeded tensors
for (auto& tensor : ws()->GetTensors()) outputs.insert(tensor);
// note that we use map to keep topo-order
map<int, OperatorDef> ops_final;
map<int, OperatorDef> final_sequence;
for (auto it : selected_op_indices) {
OperatorDef op_def;
......@@ -167,19 +171,56 @@ GraphDef Graph::Prune(const GraphDef& meta_graph) {
if (!colored_[output]) *op_def.mutable_output(i) = "ignore";
else outputs.insert(op_def.output(i));
}
ops_final[it].CopyFrom(op_def);
// handle handcraft cases
if (op_def.type() == "AffineGradient") {
// trigger in-place if not solving dAlpha
if (op_def.output(1) == "ignore")
*op_def.mutable_input(0) = "ignore";
} else if (op_def.type() == "MulGradient" ||
op_def.type() == "RMulGradient") {
if (op_def.output(0) == "ignore")
*op_def.mutable_input(1) = "ignore";
if (op_def.output(1) == "ignore")
*op_def.mutable_input(0) = "ignore";
} else if (op_def.type() == "DivGradient" ||
op_def.type() == "RDivGradient") {
// dX2 requires both X1 and X2
if (op_def.output(1) == "ignore") {
*op_def.mutable_input(0) = "ignore";
if (op_def.output(0) == "ignore")
*op_def.mutable_input(1) = "ignore";
}
}
// push into the final sequence
final_sequence[it].CopyFrom(op_def);
}
// build the pruned graph
GraphDef pruned_graph;
pruned_graph.CopyFrom(meta_graph);
pruned_graph.clear_op();
for (auto it : ops_final) pruned_graph.add_op()->CopyFrom(it.second);
return pruned_graph;
// done!
GraphDef g;
g.CopyFrom(meta_graph); g.clear_op();
for (auto it : final_sequence)
g.add_op()->CopyFrom(it.second);
return g;
}
GraphDef Graph::Share(const GraphDef& optimized_graph) {
renamed_.clear();
dag_.clear(); renamed_.clear();
// build DAG
for (int i = 0; i < optimized_graph.op_size(); i++) {
const OperatorDef& op = optimized_graph.op(i);
for (auto& v : op.output()) {
vector<string> sp_u;
if (!op.input_size()) sp_u.resize(op.output_size(), "");
else sp_u.assign(op.input().begin(), op.input().end());
for (auto& u : sp_u) {
if (u == "ignore") continue;
dag_[v].parents.push_back(u);
dag_[u].childs.push_back(v);
dag_[v].op_idx = i;
}
dag_[v].op_def = op;
}
}
// forward dyeing to search available tensors that be shared
for (int i = 0; i < optimized_graph.op_size(); i++) {
......@@ -188,28 +229,27 @@ GraphDef Graph::Share(const GraphDef& optimized_graph) {
for (auto& v : op.output()) ForwardShareDyeing(v, v);
}
GraphDef shared_graph;
shared_graph.CopyFrom(optimized_graph);
GraphDef g; g.CopyFrom(optimized_graph);
// rename to create in-place
for (int i = 0; i < optimized_graph.op_size(); i++) {
const OperatorDef& op = optimized_graph.op(i);
for (int j = 0; j < op.input_size(); j++) {
if (renamed_.count(op.input(j))) {
*shared_graph.mutable_op(i)->
mutable_input(j) = renamed_[op.input(j)];
ws()->CreateRename(op.input(j), renamed_[op.input(j)]);
}
if (renamed_.count(op.input(j)) &&
ws()->SetProxy(op.input(j), renamed_[op.input(j)]))
*g.mutable_op(i)->mutable_input(j)
= renamed_[op.input(j)];
}
for (int j = 0; j < op.output_size(); j++) {
if (renamed_.count(op.output(j))) {
*shared_graph.mutable_op(i)->
mutable_output(j) = renamed_[op.output(j)];
ws()->CreateRename(op.output(j), renamed_[op.output(j)]);
}
if (renamed_.count(op.output(j)) &&
ws()->SetProxy(op.output(j), renamed_[op.output(j)]))
*g.mutable_op(i)->mutable_output(j)
= renamed_[op.output(j)];
}
}
return shared_graph;
// done!
return g;
}
void Graph::ShareGrads(GraphDef& optimized_graph) {
......
#include "operators/activation/dropout_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/activation/dropout_op.h"
#ifdef WITH_CUDNN
......
#include "operators/activation/dropout_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/activation/dropout_op.h"
namespace dragon {
......
#include "operators/activation/elu_op.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "operators/activation/elu_op.h"
namespace dragon {
......
#include "operators/activation/prelu_op.h"
#include "core/workspace.h"
#include "utils/filler.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "operators/activation/prelu_op.h"
namespace dragon {
......
#include "operators/activation/relu_op.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "operators/activation/relu_op.h"
namespace dragon {
......
#include "operators/activation/selu_op.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "operators/activation/selu_op.h"
namespace dragon {
......
#include "operators/activation/sigmoid_op.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "operators/activation/sigmoid_op.h"
namespace dragon {
......
#include "operators/activation/softmax_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "operators/activation/softmax_op.h"
namespace dragon {
......
#include "operators/activation/tanh_op.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "operators/activation/tanh_op.h"
namespace dragon {
......
#include "operators/arithmetic/add_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/fundamental_op.h"
namespace dragon {
template <class Context> template <typename T>
void AddOp<Context>::EltwiseRunWithType() {
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
math::Add<T, Context>(Output(0)->count(), X1data, X2data, Ydata);
auto* x1 = Input(0).template data<T, Context>();
auto* x2 = Input(1).template data<T, Context>();
auto* y = Output(0)->template mutable_data<T, Context>();
math::Add<T, Context>(Output(0)->count(), x1, x2, y);
}
template <class Context> template <typename T>
void AddOp<Context>::BroadcastRunWithType(int type) {
TIndex outer_dim, inner_dim;
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
auto* x1 = Input(0).template data<T, Context>();
auto* x2 = Input(1).template data<T, Context>();
auto* y = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Input(0).count(), Ydata, X1data);
Output(0)->count(), y, x1);
if (type == 0 || type == 1) {
if (type == 0) {
......@@ -34,158 +34,127 @@ void AddOp<Context>::BroadcastRunWithType(int type) {
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
1.0, multiplier, X2data,
1.0, Ydata, &ctx());
}
else if (type == 2) {
1.0, multiplier, x2,
1.0, y, &ctx());
} else if (type == 2) {
outer_dim = Input(0).dim(0);
inner_dim = Input(0).count(1);
DECLARE_MULTIPLIER(multiplier, inner_dim);
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
1.0, X2data, multiplier,
1.0, Ydata, &ctx());
1.0, x2, multiplier,
1.0, y, &ctx());
}
}
template <class Context>
void AddOp<Context>::RunOnDevice() {
DeclareX1X2;
Output(0)->ReshapeLike(Input(0));
if (XIsType(Input(0), float)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(1).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(1).count(0, Input(1).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(1).ndim() == 1 && Input(1).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
RunByX1X2(float);
} else if (XIsType(Input(0), float16)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float16>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(1).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(1).count(0, Input(1).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(1).ndim() == 1 && Input(1).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
RunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(0),
{ "float32", "float16" });
}
}
DEPLOY_CPU(Add);
#ifdef WITH_CUDA
DEPLOY_CUDA(Add);
#endif
OPERATOR_SCHEMA(Add).NumInputs(2).NumOutputs(1).Inplace({ { 0, 0 }, { 1, 0 } });
OPERATOR_SCHEMA(Add)
.NumInputs(2).NumOutputs(1)
.Inplace({ { 0, 0 } });
template <class Context> template <typename T>
void AddGradientOp<Context>::EltwiseRunWithType() {
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
auto* dx2 = Output(1)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(1)->count(), dX2data, dYdata);
Output(1)->count(), dx2, dy);
}
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(0)->count(), dX1data, dYdata);
Output(0)->count(), dx1, dy);
}
}
template <class Context> template <typename T>
void AddGradientOp<Context>::BroadcastRunWithType(int type) {
DefineX1X2;
TIndex outer_dim, inner_dim;
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
auto* dx2 = Output(1)->template mutable_data<T, Context>();
if (type == 0 || type == 1) {
if (type == 0) {
outer_dim = Input(-1).count();
outer_dim = X1->count();
inner_dim = 1;
} else {
outer_dim = Input(-1).count(0, Input(-1).axis(-1));
inner_dim = Input(-1).dim(-1);
outer_dim = X1->count(0, X1->axis(-1));
inner_dim = X1->dim(-1);
}
DECLARE_MULTIPLIER(multiplier, outer_dim);
math::Gemv<T, Context>(
CblasTrans, outer_dim, inner_dim,
1.0, dYdata, multiplier,
0.0, dX2data, &ctx());
}
else if (type == 2) {
outer_dim = Input(-1).dim(0);
inner_dim = Input(-1).count(1);
1.0, dy, multiplier,
0.0, dx2, &ctx());
} else if (type == 2) {
outer_dim = X1->dim(0);
inner_dim = X1->count(1);
DECLARE_MULTIPLIER(multiplier, inner_dim);
math::Gemv<T, Context>(
CblasNoTrans, outer_dim, inner_dim,
1.0, dYdata, multiplier,
0.0, dX2data, &ctx());
1.0, dy, multiplier,
0.0, dx2, &ctx());
}
}
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(0)->count(), dX1data, dYdata);
X1->count(), dx1, dy);
}
}
template <class Context>
void AddGradientOp<Context>::RunOnDevice() {
Output(0)->ReshapeLike(Input(-1));
Output(1)->ReshapeLike(Input(0));
if (XIsType(Input(0), float)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else if (XIsType(Input(0), float16)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float16>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
DefineX1X2;
Output(0)->ReshapeLike(*X1);
Output(1)->ReshapeLike(*X2);
if (XIsType(Input(-1), float)) {
RunByX1X2(float);
} else if (XIsType(Input(-1), float16)) {
RunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(-1),
{ "float32", "float16" });
}
}
DEPLOY_CPU(AddGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(AddGradient);
#endif
OPERATOR_SCHEMA(AddGradient).NumInputs(2).NumOutputs(2).Inplace({ { 1, 0 } });
OPERATOR_SCHEMA(AddGradient).NumInputs(1).NumOutputs(2);
class GetAddGradient : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetAddGradient);
vector<OperatorDef> MakeDefs() override {
return SingleDef(def.type() + "Gradient", "",
vector<string> {I(1), GO(0)},
vector<string> {GO(0)},
vector<string> {GI(0), GI(1)});
}
};
......
#include "operators/arithmetic/affine_op.h"
#include "core/workspace.h"
#include "utils/filler.h"
#include "utils/op_kernel.h"
#include "operators/arithmetic/affine_op.h"
namespace dragon {
......@@ -50,7 +50,7 @@ DEPLOY_CPU(Affine);
#ifdef WITH_CUDA
DEPLOY_CUDA(Affine);
#endif
OPERATOR_SCHEMA(Affine).NumInputs(2, 3).NumOutputs(1);
OPERATOR_SCHEMA(Affine).NumInputs(2, 3).NumOutputs(1).Inplace({ { 0, 0 } });
template <class Context> template <typename T>
void AffineGradientOp<Context>::BiasRunWithType() {
......@@ -71,12 +71,12 @@ void AffineGradientOp<Context>::BiasRunWithType() {
template <class Context> template <typename T>
void AffineGradientOp<Context>::ScaleRunWithType() {
Output(0)->ReshapeLike(Input(0));
Output(0)->ReshapeLike(Input(-1));
Output(1)->ReshapeLike(Input(1));
DECLARE_MULTIPLIER(multiplier, sum_dim);
sum_result.Reshape({ outer_dim * scale_dim });
bool is_eltwise = (Input(0).count() == Input(1).count());
bool is_eltwise = (Input(-1).count() == Input(1).count());
auto* dYdata = Input(-1).template data<T, Context>();
auto* Xdata = Input(0).template data<T, Context>();
auto* dScale = Output(1)->template mutable_data<T, Context>();
......@@ -123,7 +123,7 @@ void AffineGradientOp<Context>::ScaleRunWithType() {
template <class Context> template <typename T>
void AffineGradientOp<Context>::RunWithType() {
Output(0)->ReshapeLike(Input(0));
Output(0)->ReshapeLike(Input(-1));
auto* dYdata = Input(-1).template data<T, Context>();
auto* Adata = Input(1).template data<T, Context>();
......@@ -137,25 +137,25 @@ void AffineGradientOp<Context>::RunWithType() {
template <class Context>
void AffineGradientOp<Context>::RunOnDevice() {
start_axis = axis;
if (start_axis < 0) start_axis += (int)Input(0).ndim();
if (num_axes == -1) num_axes = (int)Input(0).ndim() - start_axis;
if (start_axis < 0) start_axis += (int)Input(-1).ndim();
if (num_axes == -1) num_axes = (int)Input(-1).ndim() - start_axis;
else if (num_axes == 0) num_axes = 1;
CHECK_LT(start_axis, (int)Input(0).ndim());
CHECK_LE(start_axis + num_axes, (int)Input(0).ndim());
CHECK_LT(start_axis, (int)Input(-1).ndim());
CHECK_LE(start_axis + num_axes, (int)Input(-1).ndim());
outer_dim = Input(0).count(0, start_axis);
inner_dim = Input(0).count(start_axis + num_axes);
outer_dim = Input(-1).count(0, start_axis);
inner_dim = Input(-1).count(start_axis + num_axes);
scale_dim = Input(1).count();
sum_dim = std::max(outer_dim, inner_dim);
dim = scale_dim * inner_dim;
if (XIsType(Input(0), float)) {
if (XIsType(Input(-1), float)) {
if (Output(2)->name() != "ignore") BiasRunWithType<float>();
if (Output(1)->name() != "ignore") ScaleRunWithType<float>();
if (Output(0)->name() != "ignore") RunWithType<float>();
if (Output(0)->name() != "ignore") RunWithType<float>();
} else {
LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
LOG(FATAL) << DTypeHelper(Input(-1), { "float32" });
}
}
......
#include "operators/arithmetic/clip_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "core/workspace.h"
#include "operators/arithmetic/clip_op.h"
namespace dragon {
......
#ifdef WITH_CUDNN
#include "operators/arithmetic/affine_op.h"
#include "core/workspace.h"
#include "utils/filler.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/affine_op.h"
namespace dragon {
template <class Context> template <typename T>
void CuDNNAffineOp<Context>::RunWithType() {
this->template ResetDesc<T>();
this->template ResetDesc<T>(Input(0));
const auto& dim_start = Input(0).dims().begin() + start_axis;
const auto& dim_end = dim_start + num_axes;
vector<TIndex> param_dims(dim_start, dim_end);
......@@ -56,13 +56,13 @@ DEPLOY_CUDNN(Affine);
template <class Context> template <typename T>
void CuDNNAffineGradientOp<Context>::RunWithType() {
this->template ResetDesc<T>();
outer_dim = Input(0).count(0, start_axis);
inner_dim = Input(0).count(start_axis + num_axes);
this->template ResetDesc<T>(Input(-1));
outer_dim = Input(-1).count(0, start_axis);
inner_dim = Input(-1).count(start_axis + num_axes);
scale_dim = Input(1).count();
sum_dim = std::max(outer_dim, inner_dim);
dim = scale_dim * inner_dim;
Output(0)->ReshapeLike(Input(0));
Output(0)->ReshapeLike(Input(-1));
auto* dYdata = Input(-1).template data<T, Context>();
auto* Adata = Input(1).template data<T, Context>();
......@@ -99,7 +99,7 @@ void CuDNNAffineGradientOp<Context>::RunWithType() {
Output(2)->ReshapeLike(Input(1));
auto* dBdata = Output(2)->template mutable_data<T, Context>();
// eltwise
if (Input(0).count() == Input(1).count()) {
if (Input(-1).count() == Input(1).count()) {
math::Axpy<T, Context>(Output(2)->count(),
1.f, dYdata, dBdata, &ctx());
} else {
......@@ -212,8 +212,8 @@ void CuDNNAffineGradientOp<Context>::ComputeBiasGradient_v2(
template <class Context>
void CuDNNAffineGradientOp<Context>::RunOnDevice() {
if (XIsType(Input(0), float)) RunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
if (XIsType(Input(-1), float)) RunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(-1), { "float32" });
}
DEPLOY_CUDNN(AffineGradient);
......
#include "utils/math_functions.h"
#include "operators/arithmetic/dot_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
namespace dragon {
......@@ -99,9 +98,9 @@ void DotGradientOp<Context>::DotRunWithType() {
auto* dYdata = Input(2).template data<T, CPUContext>();
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dX2data = Output(1)->template mutable_data<T, Context>();
this->ctx().template Copy<T, Context, Context>(
ctx().template Copy<T, Context, Context>(
Output(0)->count(), dX1data, X2data);
this->ctx().template Copy<T, Context, Context>(
ctx().template Copy<T, Context, Context>(
Output(1)->count(), dX2data, X1data);
math::MulScalar<T, Context>(Output(0)->count(), dYdata[0], dX1data);
math::MulScalar<T, Context>(Output(1)->count(), dYdata[0], dX2data);
......
#include "operators/arithmetic/eltwise_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/eltwise_op.h"
namespace dragon {
......
#include "operators/arithmetic/exp_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/exp_op.h"
namespace dragon {
......
#include "operators/arithmetic/gram_matrix_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/gram_matrix_op.h"
namespace dragon {
......
#include "operators/arithmetic/inner_product_op.h"
#include "core/workspace.h"
#include "utils/filler.h"
#include "operators/arithmetic/inner_product_op.h"
namespace dragon {
......
#include "operators/arithmetic/log_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/log_op.h"
namespace dragon {
......
#include "operators/arithmetic/matmul_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/matmul_op.h"
namespace dragon {
......
#include "operators/arithmetic/pow_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/pow_op.h"
namespace dragon {
......
#include "operators/arithmetic/add_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/fundamental_op.h"
namespace dragon {
template <class Context> template <typename T>
void RAddOp<Context>::EltwiseRunWithType() {
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
math::Add<T, Context>(Output(0)->count(), X1data, X2data, Ydata);
auto* x1 = Input(0).template data<T, Context>();
auto* x2 = Input(1).template data<T, Context>();
auto* y = Output(0)->template mutable_data<T, Context>();
math::Add<T, Context>(Output(0)->count(), x1, x2, y);
}
template <class Context> template <typename T>
void RAddOp<Context>::BroadcastRunWithType(int type) {
TIndex outer_dim, inner_dim;
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
auto* x1 = Input(0).template data<T, Context>();
auto* x2 = Input(1).template data<T, Context>();
auto* y = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Input(1).count(), Ydata, X2data);
Output(0)->count(), y, x2);
if (type == 0 || type == 1) {
if (type == 0) {
......@@ -33,155 +34,127 @@ void RAddOp<Context>::BroadcastRunWithType(int type) {
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
1.0, multiplier, X1data,
1.0, Ydata, &ctx());
}
else if (type == 2) {
1.0, multiplier, x1,
1.0, y, &ctx());
} else if (type == 2) {
outer_dim = Input(1).dim(0);
inner_dim = Input(1).count(1);
DECLARE_MULTIPLIER(multiplier, inner_dim);
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
1.0, X1data, multiplier,
1.0, Ydata, &ctx());
1.0, x1, multiplier,
1.0, y, &ctx());
}
}
template <class Context>
void RAddOp<Context>::RunOnDevice() {
DeclareX1X2;
Output(0)->ReshapeLike(Input(1));
if (XIsType(Input(0), float)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
RRunByX1X2(float);
} else if (XIsType(Input(0), float16)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float16>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
RRunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(0),
{ "float32", "float16" });
}
}
DEPLOY_CPU(RAdd);
#ifdef WITH_CUDA
DEPLOY_CUDA(RAdd);
#endif
OPERATOR_SCHEMA(RAdd).NumInputs(2).NumOutputs(1);
OPERATOR_SCHEMA(RAdd)
.NumInputs(2).NumOutputs(1)
.Inplace({ { 1, 0 } });
template <class Context> template <typename T>
void RAddGradientOp<Context>::EltwiseRunWithType() {
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
auto* dx2 = Output(1)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(1)->count(), dX2data, dYdata);
Output(1)->count(), dx2, dy);
}
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(0)->count(), dX1data, dYdata);
Output(0)->count(), dx1, dy);
}
}
template <class Context> template <typename T>
void RAddGradientOp<Context>::BroadcastRunWithType(int type) {
DefineX1X2;
TIndex outer_dim, inner_dim;
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
if (type == 0 || type == 1) {
if (type == 0) {
outer_dim = Input(-1).count();
outer_dim = X2->count();
inner_dim = 1;
} else {
outer_dim = Input(-1).count(0, Input(-1).axis(-1));
inner_dim = Input(-1).dim(-1);
outer_dim = X2->count(0, X2->axis(-1));
inner_dim = X2->dim(-1);
}
DECLARE_MULTIPLIER(multiplier, outer_dim);
math::Gemv<T, Context>(
CblasTrans, outer_dim, inner_dim,
1.0, dYdata, multiplier,
0.0, dX1data, &ctx());
}
else if (type == 2) {
outer_dim = Input(-1).dim(0);
inner_dim = Input(-1).count(1);
1.0, dy, multiplier,
0.0, dx1, &ctx());
} else if (type == 2) {
outer_dim = X2->dim(0);
inner_dim = X2->count(1);
DECLARE_MULTIPLIER(multiplier, inner_dim);
math::Gemv<T, Context>(
CblasNoTrans, outer_dim, inner_dim,
1.0, dYdata, multiplier,
0.0, dX1data, &ctx());
1.0, dy, multiplier,
0.0, dx1, &ctx());
}
}
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(Output(1)->count(), dX2data, dYdata);
auto* dx2 = Output(1)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
X2->count(), dx2, dy);
}
}
template <class Context>
void RAddGradientOp<Context>::RunOnDevice() {
Output(1)->ReshapeLike(Input(-1));
Output(0)->ReshapeLike(Input(0));
if (XIsType(Input(0), float)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else if (XIsType(Input(0), float16)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float16>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
DefineX1X2;
Output(0)->ReshapeLike(*X1);
Output(1)->ReshapeLike(*X2);
if (XIsType(Input(-1), float)) {
RRunByX1X2(float);
} else if (XIsType(Input(-1), float16)) {
RRunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(-1),
{ "float32", "float16" });
}
}
DEPLOY_CPU(RAddGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(RAddGradient);
#endif
OPERATOR_SCHEMA(RAddGradient).NumInputs(2).NumOutputs(2);
OPERATOR_SCHEMA(RAddGradient).NumInputs(1).NumOutputs(2);
class GetRAddGradient : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetRAddGradient);
vector<OperatorDef> MakeDefs() override {
return SingleDef(def.type() + "Gradient", "",
vector<string> {I(0), GO(0)},
vector<string> {GO(0)},
vector<string> {GI(0), GI(1)});
}
};
......
#include "operators/arithmetic/sub_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/fundamental_op.h"
namespace dragon {
template <class Context> template <typename T>
void RSubOp<Context>::EltwiseRunWithType() {
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
math::Sub<T, Context>(Input(0).count(), X1data, X2data, Ydata);
auto* x1 = Input(0).template data<T, Context>();
auto* x2 = Input(1).template data<T, Context>();
auto* y = Output(0)->template mutable_data<T, Context>();
math::Sub<T, Context>(Output(0)->count(), x1, x2, y);
}
template <class Context> template <typename T>
void RSubOp<Context>::BroadcastRunWithType(int type) {
TIndex outer_dim, inner_dim;
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
auto* x1 = Input(0).template data<T, Context>();
auto* x2 = Input(1).template data<T, Context>();
auto* y = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Input(1).count(), Ydata, X2data);
Output(0)->count(), y, x2);
if (type == 0 || type == 1) {
if (type == 0) {
......@@ -33,157 +34,127 @@ void RSubOp<Context>::BroadcastRunWithType(int type) {
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
1.0, multiplier, X1data,
-1.0, Ydata, &ctx());
}
else if (type == 2) {
1.0, multiplier, x1,
-1.0, y, &ctx());
} else if (type == 2) {
outer_dim = Input(1).dim(0);
inner_dim = Input(1).count(1);
DECLARE_MULTIPLIER(multiplier, inner_dim);
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
1.0, X1data, multiplier,
-1.0, Ydata, &ctx());
1.0, x1, multiplier,
-1.0, y, &ctx());
}
}
template <class Context>
void RSubOp<Context>::RunOnDevice() {
DeclareX1X2;
Output(0)->ReshapeLike(Input(1));
if (XIsType(Input(0), float)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
RRunByX1X2(float);
} else if (XIsType(Input(0), float16)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float16>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
RRunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(0),
{ "float32", "float16" });
}
}
DEPLOY_CPU(RSub);
#ifdef WITH_CUDA
DEPLOY_CUDA(RSub);
#endif
OPERATOR_SCHEMA(RSub).NumInputs(2).NumOutputs(1);
OPERATOR_SCHEMA(RSub)
.NumInputs(2).NumOutputs(1)
.Inplace({ { 1, 0 } });
template <class Context> template <typename T>
void RSubGradientOp<Context>::EltwiseRunWithType() {
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
math::Scale<T, Context>(Output(1)->count(),
-1.0, dYdata, dX2data, &ctx());
auto* dx2 = Output(1)->template mutable_data<T, Context>();
math::Scale<T, Context>(
Output(1)->count(), -1, dy, dx2, &ctx());
}
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(0)->count(), dX1data, dYdata);
Output(0)->count(), dx1, dy);
}
}
template <class Context> template <typename T>
void RSubGradientOp<Context>::BroadcastRunWithType(int type) {
DefineX1X2;
TIndex outer_dim, inner_dim;
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
if (type == 0 || type == 1) {
if (type == 0) {
outer_dim = Input(-1).count();
outer_dim = X2->count();
inner_dim = 1;
} else {
outer_dim = Input(-1).count(0, Input(-1).axis(-1));
inner_dim = Input(-1).dim(-1);
outer_dim = X2->count(0, X2->axis(-1));
inner_dim = X2->dim(-1);
}
DECLARE_MULTIPLIER(multiplier, outer_dim);
math::Gemv<T, Context>(
CblasTrans, outer_dim, inner_dim,
1.0, dYdata, multiplier,
0.0, dX1data, &ctx());
}
else if (type == 2) {
outer_dim = Input(-1).dim(0);
inner_dim = Input(-1).count(1);
1.0, dy, multiplier,
0.0, dx1, &ctx());
} else if (type == 2) {
outer_dim = X2->dim(0);
inner_dim = X2->count(1);
DECLARE_MULTIPLIER(multiplier, inner_dim);
math::Gemv<T, Context>(
CblasNoTrans, outer_dim, inner_dim,
1.0, dYdata, multiplier,
0.0, dX1data, &ctx());
1.0, dy, multiplier,
0.0, dx1, &ctx());
}
}
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(1)->count(), dX2data, dYdata);
math::MulScalar<T, Context>(Output(1)->count(), -1.f, dX2data);
auto* dx2 = Output(1)->template mutable_data<T, Context>();
math::Scale<T, Context>(
X2->count(), -1, dy, dx2, &ctx());
}
}
template <class Context>
void RSubGradientOp<Context>::RunOnDevice() {
Output(1)->ReshapeLike(Input(-1));
Output(0)->ReshapeLike(Input(0));
if (XIsType(Input(0), float)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else if (XIsType(Input(0), float16)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float16>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
DefineX1X2;
Output(0)->ReshapeLike(*X1);
Output(1)->ReshapeLike(*X2);
if (XIsType(Input(-1), float)) {
RRunByX1X2(float);
} else if (XIsType(Input(-1), float16)) {
RRunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(-1),
{ "float32", "float16" });
}
}
DEPLOY_CPU(RSubGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(RSubGradient);
#endif
OPERATOR_SCHEMA(RSubGradient).NumInputs(2).NumOutputs(2);
OPERATOR_SCHEMA(RSubGradient).NumInputs(1).NumOutputs(2);
class GetRSubGradient : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetRSubGradient);
vector<OperatorDef> MakeDefs() override {
return SingleDef(def.type() + "Gradient", "",
vector<string> {I(0), GO(0)},
vector<string> {GO(0)},
vector<string> {GI(0), GI(1)});
}
};
......
#include "operators/arithmetic/square_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/square_op.h"
namespace dragon {
......
#include "operators/arithmetic/sub_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/math_functions.h"
#include "operators/arithmetic/fundamental_op.h"
namespace dragon {
......@@ -9,17 +9,18 @@ void SubOp<Context>::EltwiseRunWithType() {
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
math::Sub<T, Context>(Input(0).count(), X1data, X2data, Ydata);
math::Sub<T, Context>(Output(0)->count(), X1data, X2data, Ydata);
}
template <class Context> template <typename T>
void SubOp<Context>::BroadcastRunWithType(int type) {
TIndex outer_dim, inner_dim;
auto* X1data = Input(0).template data<T, Context>();
auto* X2data = Input(1).template data<T, Context>();
auto* Ydata = Output(0)->template mutable_data<T, Context>();
auto* x1 = Input(0).template data<T, Context>();
auto* x2 = Input(1).template data<T, Context>();
auto* y = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Input(0).count(), Ydata, X1data);
Output(0)->count(), y, x1);
if (type == 0 || type == 1) {
if (type == 0) {
......@@ -33,8 +34,8 @@ void SubOp<Context>::BroadcastRunWithType(int type) {
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
-1.0, multiplier, X2data,
1.0, Ydata, &ctx());
-1.0, multiplier, x2,
1.0, y, &ctx());
}
else if (type == 2) {
outer_dim = Input(0).dim(0);
......@@ -43,146 +44,118 @@ void SubOp<Context>::BroadcastRunWithType(int type) {
math::Gemm<T, Context>(
CblasNoTrans, CblasNoTrans,
outer_dim, inner_dim, 1,
-1.0, X2data, multiplier,
1.0, Ydata, &ctx());
-1.0, x2, multiplier,
1.0, y, &ctx());
}
}
template <class Context>
void SubOp<Context>::RunOnDevice() {
DeclareX1X2;
Output(0)->ReshapeLike(Input(0));
if (XIsType(Input(0), float)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(1).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(1).count(0, Input(1).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(1).ndim() == 1 && Input(1).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
RunByX1X2(float);
} else if (XIsType(Input(0), float16)) {
if (Input(0).dims() == Input(1).dims())
EltwiseRunWithType<float16>();
else if (Input(0).dim(0) == Input(1).dim(0) && Input(1).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(0).dim(-1) == Input(1).dim(-1) &&
Input(1).count(0, Input(1).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(1).ndim() == 1 && Input(1).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(0).DimString() << " " << Input(1).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
RunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(0),
{ "float32", "float16" });
}
}
DEPLOY_CPU(Sub);
#ifdef WITH_CUDA
DEPLOY_CUDA(Sub);
#endif
OPERATOR_SCHEMA(Sub).NumInputs(2).NumOutputs(1).Inplace({ { 0, 0 }, { 1, 0 } });
OPERATOR_SCHEMA(Sub)
.NumInputs(2).NumOutputs(1)
.Inplace({ { 0, 0 } });
template <class Context> template <typename T>
void SubGradientOp<Context>::EltwiseRunWithType() {
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
math::Scale<T, Context>(Output(1)->count(),
-1.0, dYdata, dX2data, &ctx());
auto* dx2 = Output(1)->template mutable_data<T, Context>();
math::Scale<T, Context>(Output(1)->count(),
-1.0, dy, dx2, &ctx());
}
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(0)->count(), dX1data, dYdata);
Output(0)->count(), dx1, dy);
}
}
template <class Context> template <typename T>
void SubGradientOp<Context>::BroadcastRunWithType(int type) {
DefineX1X2;
TIndex outer_dim, inner_dim;
auto* dYdata = Input(-1).template data<T, Context>();
auto* dy = Input(-1).template data<T, Context>();
if (Output(1)->name() != "ignore") {
auto* dX2data = Output(1)->template mutable_data<T, Context>();
auto* dx2 = Output(1)->template mutable_data<T, Context>();
if (type == 0 || type == 1) {
if (type == 0) {
outer_dim = Input(-1).count();
outer_dim = X1->count();
inner_dim = 1;
} else {
outer_dim = Input(-1).count(0, Input(-1).axis(-1));
inner_dim = Input(-1).dim(-1);
outer_dim = X1->count(0, X1->axis(-1));
inner_dim = X1->dim(-1);
}
DECLARE_MULTIPLIER(multiplier, outer_dim);
math::Gemv<T, Context>(
CblasTrans, outer_dim, inner_dim,
-1.0, dYdata, multiplier,
0.0, dX2data, &ctx());
}
else if (type == 2) {
outer_dim = Input(-1).dim(0);
inner_dim = Input(-1).count(1);
-1.0, dy, multiplier,
0.0, dx2, &ctx());
} else if (type == 2) {
outer_dim = X1->dim(0);
inner_dim = X1->count(1);
DECLARE_MULTIPLIER(multiplier, inner_dim);
math::Gemv<T, Context>(
CblasNoTrans, outer_dim, inner_dim,
-1.0, dYdata, multiplier,
0.0, dX2data, &ctx());
-1.0, dy, multiplier,
0.0, dx2, &ctx());
}
}
if (Output(0)->name() != "ignore") {
auto* dX1data = Output(0)->template mutable_data<T, Context>();
auto* dx1 = Output(0)->template mutable_data<T, Context>();
ctx().template Copy<T, Context, Context>(
Output(0)->count(), dX1data, dYdata);
X1->count(), dx1, dy);
}
}
template <class Context>
void SubGradientOp<Context>::RunOnDevice() {
Output(0)->ReshapeLike(Input(-1));
Output(1)->ReshapeLike(Input(0));
if (XIsType(Input(0), float)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else if (XIsType(Input(0), float16)) {
if (Input(-1).dims() == Input(0).dims())
EltwiseRunWithType<float16>();
else if (Input(-1).dim(0) == Input(0).dim(0) && Input(0).count(1) == 1)
BroadcastRunWithType<float16>(2);
else if (Input(-1).dim(-1) == Input(0).dim(-1) &&
Input(0).count(0, Input(0).axis(-1)) == 1)
BroadcastRunWithType<float16>(1);
else if (Input(0).ndim() == 1 && Input(0).dim(0) == 1)
BroadcastRunWithType<float16>(0);
else LOG(FATAL) << "Could not be broadcast together with shapes "
<< Input(-1).DimString() << " " << Input(0).DimString();
} else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "float16" });
DefineX1X2;
Output(0)->ReshapeLike(*X1);
Output(1)->ReshapeLike(*X2);
if (XIsType(Input(-1), float)) {
RunByX1X2(float);
} else if (XIsType(Input(-1), float16)) {
RunByX1X2(float16);
} else {
LOG(FATAL) << DTypeHelper(Input(-1),
{ "float32", "float16" });
}
}
DEPLOY_CPU(SubGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(SubGradient);
#endif
OPERATOR_SCHEMA(SubGradient).NumInputs(2).NumOutputs(2).Inplace({ { 1, 0 } });
OPERATOR_SCHEMA(SubGradient).NumInputs(1).NumOutputs(2);
class GetSubGradient : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetSubGradient);
vector<OperatorDef> MakeDefs() override {
return SingleDef(def.type() + "Gradient", "",
vector<string> {I(1), GO(0)},
vector<string> {GO(0)},
vector<string> {GI(0), GI(1)});
}
};
......
#include "operators/control_flow/compare_op.h"
#include "utils/op_kernel.h"
#include "operators/control_flow/compare_op.h"
namespace dragon {
......
#include "operators/loss/ctc_loss_op.h"
#include "core/workspace.h"
#include "utils/filler.h"
#include "operators/loss/ctc_loss_op.h"
namespace dragon {
......@@ -12,7 +12,8 @@ OPERATOR_SCHEMA(CTCLoss).NumInputs(2).NumOutputs(1);
template <class Context> template <typename T>
void CTCLossGradientOp<Context>::RunWithType() {
auto* gradT = ws()->GetTensor("/mnt/" + anchor() + "/ctc/grads");
auto* gradT = ws()->GetTensor(
"/mnt/" + anchor() + "/ctc/grads");
Output(0)->ReshapeLike(*gradT);
auto* Gdata = gradT->template data<T, Context>();
......
#include "operators/loss/ctc_loss_op.h"
#include "core/workspace.h"
#include "operators/loss/ctc_loss_op.h"
#ifdef WITH_CUDNN
......@@ -15,7 +15,8 @@ void CuDNNCTCLossOp<Context>::WrapIO() {
const auto batch_size = Input(0).dim(1);
const auto max_num_labels = Input(1).dim(1);
CHECK_EQ(batch_size, Input(1).dim(0))
<< "\nExcepted " << batch_size << " groups(i.e. batch_size) of labels,"
<< "\nExcepted " << batch_size
<< " groups(i.e. batch_size) of labels,"
<< "\nbut got " << Input(1).dim(0) << ".";
// CuDNN currently does not support variable input lengths
input_lengths = vector<int>(batch_size, max_seq_len);
......@@ -23,12 +24,16 @@ void CuDNNCTCLossOp<Context>::WrapIO() {
auto* Ldata = Input(1).template data<int, CPUContext>();
for (int n = 0; n < batch_size; ++n) {
auto start = Ldata + n * max_num_labels;
auto res = std::find(start, start + max_num_labels, (int)padding_mask);
auto res = std::find(
start, start + max_num_labels,
(int)padding_mask);
int len = std::distance(start, res);
CHECK_LE(len, CUDNN_LABEL_LENGTH_LIMIT)
<< "\nThe max label length is " << CUDNN_LABEL_LENGTH_LIMIT
<< "\nThe max label length is "
<< CUDNN_LABEL_LENGTH_LIMIT
<< ", but got " << len << ".";
std::copy(start, start + len, std::back_inserter(packed_labels));
std::copy(start, start + len,
std::back_inserter(packed_labels));
label_lengths[n] = len;
}
Output(0)->Reshape(vector<TIndex>({ 1 }));
......
#include "operators/loss/l1_loss_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/loss/l1_loss_op.h"
namespace dragon {
......@@ -19,10 +19,13 @@ void L1LossOp<Context>::RunWithType() {
math::Mul<T, Context>(diff->count(), Wdata, diff_data, diff_data);
}
T normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
T normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
}
T loss = math::ASum<T, Context>(diff->count(), diff_data);
math::Set<T, Context>(1, loss / normalizer, Ydata);
}
......@@ -52,11 +55,13 @@ void L1LossGradientOp<Context>::RunWithType() {
1, &dYdata_host, dYdata);
kernel::AbsGrad<T, Context>(diff->count(), diff_data, diff_data);
T alpha = dYdata_host, normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
alpha = alpha / normalizer;
T alpha = dYdata_host, normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
} alpha = alpha / normalizer;
for (int i = 0; i < 2; i++) {
if (Output(i)->name() == "ignore") continue;
Output(i)->ReshapeLike(Input(i));
......
#include "operators/loss/l2_loss_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/loss/l2_loss_op.h"
namespace dragon {
......@@ -17,10 +17,13 @@ void L2LossOp<Context>::RunWithType() {
math::Mul<T, Context>(diff->count(), Wdata, diff_data, diff_data);
}
T normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
T normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
}
T loss = T(0.5) * math::Dot<T, Context>(diff->count(),
diff_data, diff_data, &ctx());
math::Set<T, Context>(1, loss / normalizer, Ydata);
......@@ -50,11 +53,13 @@ void L2LossGradientOp<Context>::RunWithType() {
T dYdata_host; ctx().template Copy<T, CPUContext, Context>(
1, &dYdata_host, dYdata);
T alpha = dYdata_host, normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
alpha = alpha / normalizer;
T alpha = dYdata_host, normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
} alpha = alpha / normalizer;
for (int i = 0; i < 2; i++) {
if (Output(i)->name() == "ignore") continue;
Output(i)->ReshapeLike(Input(i));
......
#include "operators/loss/sigmoid_cross_entropy_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/loss/sigmoid_cross_entropy_op.h"
namespace dragon {
......@@ -10,10 +10,10 @@ void SigmoidCrossEntropyOp<Context>::RunWithType() {
auto* Xdata = Input(0).template data<T, Context>();
auto* Tdata = Input(1).template data<T, Context>();
auto* Ldata = losses.template mutable_data<T, Context>();
auto* Vdata = valid.template mutable_data<T, Context>();
auto* Fdata = flags.template mutable_data<T, Context>();
kernel::SigmoidCrossEntropy<T, Context>(
Input(0).count(), Xdata, Tdata, Ldata, Vdata);
Input(0).count(), Xdata, Tdata, Ldata, Fdata, &ctx());
if (normalization == "UNIT") {
Output(0)->ReshapeLike(losses);
......@@ -21,13 +21,17 @@ void SigmoidCrossEntropyOp<Context>::RunWithType() {
return;
}
T normalizer;
if (normalization == "VALID")
T normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<T, Context>(valid.count(), Vdata), 1.f);
else if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
math::ASum<T, Context>(
flags.count(), Fdata), 1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
}
T loss = math::ASum<T, Context>(losses.count(), Ldata);
Output(0)->Reshape({ 1 });
auto* Ydata = Output(0)->template mutable_data<T, Context>();
......@@ -39,7 +43,7 @@ void SigmoidCrossEntropyOp<Context>::RunOnDevice() {
CHECK_EQ(Input(0).count(), Input(1).count())
<< "\nNumber of predictions must match the number of labels.";
losses.ReshapeLike(Input(0));
valid.ReshapeLike(Input(0));
flags.ReshapeLike(Input(0));
if (XIsType(Input(0), float)) RunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
......@@ -55,11 +59,11 @@ template <class Context> template <typename T>
void SigmoidCrossEntropyGradientOp<Context>::RunWithType() {
auto* Xdata = Input(0).template data<T, Context>();
auto* Tdata = Input(1).template data<T, Context>();
auto* Vdata = valid.template mutable_data<T, Context>();
auto* dXdata = Output(0)->template mutable_data<T, Context>();
auto* Fdata = flags.template mutable_data<T, Context>();
kernel::SigmoidCrossEntropyGrad<T, Context>(
Input(0).count(), Xdata, Tdata, dXdata, Vdata);
Input(0).count(), Xdata, Tdata, dXdata, Fdata, &ctx());
if (normalization == "UNIT") {
auto* dYdata = Input(-1).template data<T, Context>();
......@@ -67,13 +71,17 @@ void SigmoidCrossEntropyGradientOp<Context>::RunWithType() {
dYdata, dXdata, dXdata); return;
}
T normalizer;
if (normalization == "VALID")
T normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<T, Context>(valid.count(), Vdata), 1.f);
else if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
math::ASum<T, Context>(
flags.count(), Fdata), 1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
}
auto* dYdata = Input(-1).template data<T, Context>();
T dYdata_host; ctx().template Copy<T, CPUContext, Context>(
1, &dYdata_host, dYdata);
......@@ -84,7 +92,7 @@ void SigmoidCrossEntropyGradientOp<Context>::RunWithType() {
template <class Context>
void SigmoidCrossEntropyGradientOp<Context>::RunOnDevice() {
Output(0)->ReshapeLike(Input(0));
valid.ReshapeLike(Input(0));
flags.ReshapeLike(Input(0));
if (XIsType(Input(0), float)) RunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
......@@ -96,7 +104,8 @@ DEPLOY_CUDA(SigmoidCrossEntropyGradient);
#endif
OPERATOR_SCHEMA(SigmoidCrossEntropyGradient).NumInputs(3).NumOutputs(1);
class GetSigmoidCrossEntropyGradient final : public GradientMakerBase {
class GetSigmoidCrossEntropyGradient
final : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetSigmoidCrossEntropyGradient);
vector<OperatorDef> MakeDefs() override {
......@@ -105,6 +114,9 @@ class GetSigmoidCrossEntropyGradient final : public GradientMakerBase {
vector<string> {GI(0)});
}
};
REGISTER_GRADIENT(SigmoidCrossEntropy, GetSigmoidCrossEntropyGradient);
REGISTER_GRADIENT(
SigmoidCrossEntropy,
GetSigmoidCrossEntropyGradient
);
} // namespace dragon
} // namespace dragon
\ No newline at end of file
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/loss/sigmoid_focal_loss_op.h"
namespace dragon {
template <class Context> template <typename T>
void SigmoidFocalLossOp<Context>::RunWithType() {
auto* Xdata = Input(0).template data<T, Context>();
auto* Tdata = Input(1).template data<T, Context>();
auto* Ldata = losses.template mutable_data<T, Context>();
auto* Fdata = flags.template mutable_data<T, Context>();
kernel::SigmoidFocalLoss<T, Context>(
outer_dim, axis_dim, inner_dim,
pos_alpha, neg_alpha, gamma, neg_id,
Xdata, Tdata, Ldata, Fdata, &ctx());
if (normalization == "UNIT") {
Output(0)->ReshapeLike(losses);
Output(0)->template Copy<Context, Context>(losses);
return;
}
T normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<T, Context>(
flags.count(), Fdata), 1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = outer_dim * inner_dim;
}
T loss = math::ASum<T, Context>(losses.count(), Ldata);
Output(0)->Reshape({ 1 });
auto* Ydata = Output(0)->template mutable_data<T, Context>();
math::Set<T, Context>(1, loss / normalizer, Ydata);
}
template <class Context>
void SigmoidFocalLossOp<Context>::RunOnDevice() {
outer_dim = Input(0).count(0, axis);
axis_dim = Input(0).dim(axis);
inner_dim = Input(0).count(axis + 1);
CHECK_EQ(outer_dim * inner_dim, Input(1).count())
<< "\nNumber of predictions must match the number of labels.";
losses.ReshapeLike(Input(0));
flags.ReshapeLike(Input(0));
if (XIsType(Input(0), float)) RunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
}
DEPLOY_CPU(SigmoidFocalLoss);
#ifdef WITH_CUDA
DEPLOY_CUDA(SigmoidFocalLoss);
#endif
OPERATOR_SCHEMA(SigmoidFocalLoss).NumInputs(2).NumOutputs(1);
template <class Context> template <typename T>
void SigmoidFocalLossGradientOp<Context>::RunWithType() {
auto* Xdata = Input(0).template data<T, Context>();
auto* Tdata = Input(1).template data<T, Context>();
auto* dXdata = Output(0)->template mutable_data<T, Context>();
auto* Fdata = flags.template mutable_data<T, Context>();
kernel::SigmoidFocalLossGradient<T, Context>(
outer_dim, axis_dim, inner_dim,
pos_alpha, neg_alpha, gamma, neg_id,
Xdata, Tdata, dXdata, Fdata, &ctx());
if (normalization == "UNIT") {
auto* dYdata = Input(-1).template data<T, Context>();
math::Mul<T, Context>(Output(0)->count(),
dYdata, dXdata, dXdata); return;
}
T normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<T, Context>(
flags.count(), Fdata), 1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
}
auto* dYdata = Input(-1).template data<T, Context>();
T dYdata_host; ctx().template Copy<T, CPUContext, Context>(
1, &dYdata_host, dYdata);
math::Scal<T, Context>(Output(0)->count(),
dYdata_host / normalizer, dXdata, &ctx());
}
template <class Context>
void SigmoidFocalLossGradientOp<Context>::RunOnDevice() {
outer_dim = Input(0).count(0, axis);
axis_dim = Input(0).dim(axis);
inner_dim = Input(0).count(axis + 1);
Output(0)->ReshapeLike(Input(0));
flags.ReshapeLike(Input(0));
if (XIsType(Input(0), float)) RunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
}
DEPLOY_CPU(SigmoidFocalLossGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(SigmoidFocalLossGradient);
#endif
OPERATOR_SCHEMA(SigmoidFocalLossGradient).NumInputs(3).NumOutputs(1);
class GetSigmoidFocalLossGradient
final : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetSigmoidFocalLossGradient);
vector<OperatorDef> MakeDefs() override {
return SingleDef(def.type() + "Gradient", "",
vector<string> {I(0), I(1), GO(0)},
vector<string> {GI(0)});
}
};
REGISTER_GRADIENT(
SigmoidFocalLoss,
GetSigmoidFocalLossGradient
);
} // namespace dragon
\ No newline at end of file
#include "operators/loss/smooth_l1_loss_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/loss/smooth_l1_loss_op.h"
namespace dragon {
......@@ -27,10 +27,13 @@ void SmoothL1LossOp<Context>::RunWithType() {
outside_w_data, error_data, error_data);
}
T normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
T normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
}
T loss = math::ASum<T, Context>(error->count(), error_data);
math::Set<T, Context>(1, loss / normalizer, Ydata);
}
......@@ -66,11 +69,12 @@ void SmoothL1LossGradientOp<Context>::RunWithType() {
kernel::SmoothL1Grad<T, Context>(
diff->count(), beta, diff_data, diff_data);
T alpha = dYdata_host, normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = Input(0).count();
else if (normalization == "NONE") normalizer = 1;
alpha = alpha / normalizer;
T alpha = dYdata_host, normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = Input(0).count();
} alpha = alpha / normalizer;
for (int i = 0; i < 2; i++) {
if (Output(i)->name() == "ignore") continue;
......@@ -107,7 +111,8 @@ DEPLOY_CUDA(SmoothL1LossGradient);
#endif
OPERATOR_SCHEMA(SmoothL1LossGradient).NumInputs(3, 5).NumOutputs(2);
class GetSmoothL1LossGradient final : public GradientMakerBase {
class GetSmoothL1LossGradient
final : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetSmoothL1LossGradient);
vector<OperatorDef> MakeDefs() override {
......@@ -119,6 +124,9 @@ class GetSmoothL1LossGradient final : public GradientMakerBase {
vector<string> {GI(0), GI(1)});
}
};
REGISTER_GRADIENT(SmoothL1Loss, GetSmoothL1LossGradient);
REGISTER_GRADIENT(
SmoothL1Loss,
GetSmoothL1LossGradient
);
} // namespace dragon
\ No newline at end of file
#include "operators/activation/softmax_op.h"
#include "operators/loss/softmax_cross_entropy_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "utils/proto_utils.h"
#include "operators/activation/softmax_op.h"
#include "operators/loss/softmax_cross_entropy_op.h"
namespace dragon {
......@@ -37,10 +37,13 @@ void SoftmaxCrossEntropyOp<Context>::RunWithType() {
Ldata, Ydata); return;
}
T normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = outer_dim * inner_dim;
else if (normalization == "NONE") normalizer = 1;
T normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = outer_dim * inner_dim;
}
T loss = math::ASum<T, Context>(losses.count(), Ldata);
Output(0)->Reshape({ 1 });
auto* Ydata = Output(0)->template mutable_data<T, Context>();
......@@ -85,10 +88,13 @@ void SoftmaxCrossEntropyGradientOp<Context>::RunWithType() {
Pdata, dXdata, dXdata); return;
}
T normalizer;
if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = outer_dim * inner_dim;
else if (normalization == "NONE") normalizer = 1;
T normalizer = 1;
if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = outer_dim * inner_dim;
}
auto* dYdata = Input(-1).template data<T, Context>();
T dYdata_host; ctx().template Copy<T, CPUContext, Context>(
1, &dYdata_host, dYdata);
......@@ -113,7 +119,8 @@ DEPLOY_CUDA(SoftmaxCrossEntropyGradient);
#endif
OPERATOR_SCHEMA(SoftmaxCrossEntropyGradient).NumInputs(3).NumOutputs(1);
class GetSoftmaxCrossEntropyGradient final : public GradientMakerBase {
class GetSoftmaxCrossEntropyGradient
final : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetSoftmaxCrossEntropyGradient);
vector<OperatorDef> MakeDefs() override {
......@@ -122,6 +129,9 @@ class GetSoftmaxCrossEntropyGradient final : public GradientMakerBase {
vector<string> {GI(0)});
}
};
REGISTER_GRADIENT(SoftmaxCrossEntropy, GetSoftmaxCrossEntropyGradient);
REGISTER_GRADIENT(
SoftmaxCrossEntropy,
GetSoftmaxCrossEntropyGradient
);
} // namespace dragon
\ No newline at end of file
#include "operators/activation/softmax_op.h"
#include "operators/loss/sparse_softmax_focal_loss_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "utils/proto_utils.h"
#include "operators/activation/softmax_op.h"
#include "operators/loss/softmax_focal_loss_op.h"
namespace dragon {
template <class Context> template <typename T>
void SparseSoftmaxFocalLossOp<Context>::RunWithType() {
void SoftmaxFocalLossOp<Context>::RunWithType() {
auto* Pdata = this->prob->template data<T, Context>();
auto* Tdata = Input(1).template data<T, Context>();
auto* Idata = !this->ignores.count() ? nullptr :
......@@ -16,7 +16,7 @@ void SparseSoftmaxFocalLossOp<Context>::RunWithType() {
auto* Ldata = losses.template mutable_data<T, Context>();
auto* Fdata = flags.template mutable_data<T, Context>();
kernel::SparseSoftmaxFocalLoss<T, Context>(
kernel::SoftmaxFocalLoss<T, Context>(
outer_dim, Input(0).dim(axis), inner_dim,
pos_alpha, neg_alpha, gamma, neg_id,
Pdata, Tdata, Idata, this->ignores.count(),
......@@ -28,13 +28,17 @@ void SparseSoftmaxFocalLossOp<Context>::RunWithType() {
return;
}
T normalizer;
if (normalization == "VALID")
T normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<T, Context>(flags.count(), Fdata), 1.f);
else if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = outer_dim * inner_dim;
else if (normalization == "NONE") normalizer = 1;
math::ASum<T, Context>(
flags.count(), Fdata), 1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL"){
normalizer = outer_dim * inner_dim;
}
T loss = math::ASum<T, Context>(losses.count(), Ldata);
Output(0)->Reshape({ 1 });
auto* Ydata = Output(0)->template mutable_data<T, Context>();
......@@ -42,7 +46,7 @@ void SparseSoftmaxFocalLossOp<Context>::RunWithType() {
}
template <class Context>
void SparseSoftmaxFocalLossOp<Context>::RunOnDevice() {
void SoftmaxFocalLossOp<Context>::RunOnDevice() {
outer_dim = Input(0).count(0, axis);
inner_dim = Input(0).count(axis + 1);
CHECK_EQ(outer_dim * inner_dim, Input(1).count())
......@@ -57,14 +61,14 @@ void SparseSoftmaxFocalLossOp<Context>::RunOnDevice() {
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
}
DEPLOY_CPU(SparseSoftmaxFocalLoss);
DEPLOY_CPU(SoftmaxFocalLoss);
#ifdef WITH_CUDA
DEPLOY_CUDA(SparseSoftmaxFocalLoss);
DEPLOY_CUDA(SoftmaxFocalLoss);
#endif
OPERATOR_SCHEMA(SparseSoftmaxFocalLoss).NumInputs(2).NumOutputs(1);
OPERATOR_SCHEMA(SoftmaxFocalLoss).NumInputs(2).NumOutputs(1);
template <class Context> template <typename T>
void SparseSoftmaxFocalLossGradientOp<Context>::RunWithType() {
void SoftmaxFocalLossGradientOp<Context>::RunWithType() {
auto* Pdata = this->prob->template mutable_data<T, Context>();
auto* Tdata = Input(1).template data<T, Context>();
auto* Idata = !this->ignores.count() ? nullptr :
......@@ -72,7 +76,7 @@ void SparseSoftmaxFocalLossGradientOp<Context>::RunWithType() {
auto* dXdata = Output(0)->template mutable_data<T, Context>();
auto* Fdata = flags.template mutable_data<T, Context>();
kernel::SparseSoftmaxFocalLossGrad<T, Context>(
kernel::SoftmaxFocalLossGrad<T, Context>(
outer_dim, Output(0)->dim(axis), inner_dim,
pos_alpha, neg_alpha, gamma, neg_id,
Pdata, Tdata, Idata, this->ignores.count(),
......@@ -88,13 +92,17 @@ void SparseSoftmaxFocalLossGradientOp<Context>::RunWithType() {
Pdata, dXdata, dXdata); return;
}
T normalizer;
if (normalization == "VALID")
T normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<T, Context>(flags.count(), Fdata), 1.f);
else if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = outer_dim * inner_dim;
else if (normalization == "NONE") normalizer = 1;
math::ASum<T, Context>(
flags.count(), Fdata), 1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = outer_dim * inner_dim;
}
auto* dYdata = Input(-1).template data<T, Context>();
T dYdata_host; ctx().template Copy<T, CPUContext, Context>(
1, &dYdata_host, dYdata);
......@@ -103,7 +111,7 @@ void SparseSoftmaxFocalLossGradientOp<Context>::RunWithType() {
}
template <class Context>
void SparseSoftmaxFocalLossGradientOp<Context>::RunOnDevice() {
void SoftmaxFocalLossGradientOp<Context>::RunOnDevice() {
this->prob = ws()->GetTensor("/mnt/" + anchor() + "/softmax/prob");
outer_dim = this->prob->count(0, axis);
inner_dim = this->prob->count(axis + 1);
......@@ -114,21 +122,25 @@ void SparseSoftmaxFocalLossGradientOp<Context>::RunOnDevice() {
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
}
DEPLOY_CPU(SparseSoftmaxFocalLossGradient);
DEPLOY_CPU(SoftmaxFocalLossGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(SparseSoftmaxFocalLossGradient);
DEPLOY_CUDA(SoftmaxFocalLossGradient);
#endif
OPERATOR_SCHEMA(SparseSoftmaxFocalLossGradient).NumInputs(3).NumOutputs(1);
OPERATOR_SCHEMA(SoftmaxFocalLossGradient).NumInputs(3).NumOutputs(1);
class GetSparseSoftmaxFocalLossGradient final : public GradientMakerBase {
class GetSoftmaxFocalLossGradient
final : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetSparseSoftmaxFocalLossGradient);
GRADIENT_MAKER_CTOR(GetSoftmaxFocalLossGradient);
vector<OperatorDef> MakeDefs() override {
return SingleDef(def.type() + "Gradient", "",
vector<string> {I(0), I(1), GO(0)},
vector<string> {GI(0)});
}
};
REGISTER_GRADIENT(SparseSoftmaxFocalLoss, GetSparseSoftmaxFocalLossGradient);
REGISTER_GRADIENT(
SoftmaxFocalLoss,
GetSoftmaxFocalLossGradient
);
} // namespace dragon
\ No newline at end of file
#include "operators/activation/softmax_op.h"
#include "operators/loss/sparse_softmax_cross_entropy_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "utils/proto_utils.h"
#include "operators/activation/softmax_op.h"
#include "operators/loss/sparse_softmax_cross_entropy_op.h"
namespace dragon {
......@@ -23,11 +23,13 @@ void SparseSoftmaxCrossEntropyOp<Context>::SoftmaxRun() {
template <class Context>
void SparseSoftmaxCrossEntropyOp<Context>::SoftmaxRunFP16() {
Tensor* XF32 = ws()->CreateTensor("/mnt/" + anchor() + "/softmax/xf32");
Tensor* XF32 = ws()->CreateTensor(
"/mnt/" + anchor() + "/softmax/xf32");
XF32->ReshapeLike(Input(0));
auto* XdataF16 = Input(0).template data<float16, Context>();
auto* XdataF32 = XF32->template mutable_data<float, Context>();
kernel::TypeA2B<float16, float, Context>(Input(0).count(), XdataF16, XdataF32);
kernel::TypeA2B<float16, float, Context>(
Input(0).count(), XdataF16, XdataF32);
OperatorDef softmax_def = MakeOperatorDef("Softmax", "",
vector<string>({ XF32->name() }),
vector<string>({ "/mnt/" + anchor() + "/softmax/prob" }));
......@@ -35,7 +37,8 @@ void SparseSoftmaxCrossEntropyOp<Context>::SoftmaxRunFP16() {
if (def().has_device_option())
softmax_def.mutable_device_option()
->CopyFrom(def().device_option());
if (!softmax_op) softmax_op.reset(CreateOperator(softmax_def, ws()));
if (!softmax_op) softmax_op.reset(
CreateOperator(softmax_def, ws()));
else softmax_op->MutableOp(softmax_def);
softmax_op->Run();
}
......@@ -60,13 +63,17 @@ void SparseSoftmaxCrossEntropyOp<Context>::RunWithType() {
return;
}
Tx normalizer;
if (normalization == "VALID")
Tx normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<Tx, Context>(flags.count(), Fdata), (Tx)1.f);
else if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = outer_dim * inner_dim;
else if (normalization == "NONE") normalizer = 1;
math::ASum<Tx, Context>(
flags.count(), Fdata), (Tx)1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = outer_dim * inner_dim;
}
Tx loss = math::ASum<Tx, Context>(losses.count(), Ldata);
Output(0)->Reshape({ 1 });
auto* Ydata = Output(0)->template mutable_data<Tx, Context>();
......@@ -126,13 +133,17 @@ void SparseSoftmaxCrossEntropyGradientOp<Context>::RunWithType() {
return;
}
Tx normalizer;
if (normalization == "VALID")
Tx normalizer = 1;
if (normalization == "VALID") {
normalizer = std::max(
math::ASum<Tx, Context>(flags.count(), Fdata), (Tx)1.f);
else if (normalization == "BATCH_SIZE") normalizer = Input(0).dim(0);
else if (normalization == "FULL") normalizer = outer_dim * inner_dim;
else if (normalization == "NONE") normalizer = 1;
math::ASum<Tx, Context>(
flags.count(), Fdata), (Tx)1.f);
} else if (normalization == "BATCH_SIZE") {
normalizer = Input(0).dim(0);
} else if (normalization == "FULL") {
normalizer = outer_dim * inner_dim;
}
auto* dYdata = Input(-1).template data<Tx, Context>();
Tx dYdata_host; ctx().template Copy<Tx, CPUContext, Context>(
1, &dYdata_host, dYdata);
......@@ -167,7 +178,8 @@ DEPLOY_CUDA(SparseSoftmaxCrossEntropyGradient);
#endif
OPERATOR_SCHEMA(SparseSoftmaxCrossEntropyGradient).NumInputs(3).NumOutputs(1);
class GetSparseSoftmaxCrossEntropyGradient final : public GradientMakerBase {
class GetSparseSoftmaxCrossEntropyGradient
final : public GradientMakerBase {
public:
GRADIENT_MAKER_CTOR(GetSparseSoftmaxCrossEntropyGradient);
vector<OperatorDef> MakeDefs() override {
......@@ -176,6 +188,9 @@ class GetSparseSoftmaxCrossEntropyGradient final : public GradientMakerBase {
vector<string> {GI(0)});
}
};
REGISTER_GRADIENT(SparseSoftmaxCrossEntropy, GetSparseSoftmaxCrossEntropyGradient);
REGISTER_GRADIENT(
SparseSoftmaxCrossEntropy,
GetSparseSoftmaxCrossEntropyGradient
);
} // namespace dragon
\ No newline at end of file
#include <algorithm>
#include "operators/misc/accuracy_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/misc/accuracy_op.h"
namespace dragon {
......
#include "operators/misc/astype_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/misc/astype_op.h"
namespace dragon {
......
#include "operators/misc/gradient_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "operators/misc/gradient_op.h"
namespace dragon {
......
#include "operators/misc/image_data_op.h"
#include "utils/op_kernel.h"
#include "operators/misc/image_data_op.h"
namespace dragon {
......
#include "operators/misc/initialize_op.h"
#include "core/workspace.h"
#include "operators/misc/initialize_op.h"
namespace dragon {
......
......@@ -26,11 +26,11 @@ RunOp<Context>::RunOp(const OperatorDef& def, Workspace* ws)
// init interpreter & load module
Py_Initialize();
PyObject* py_module = PyImport_ImportModule(module.c_str());
CHECK(py_module) << "\nFail to import py module: " << module;
CHECK(py_module) << "\nFailed to Import Module: " << module;
PyObject* py_dict = PyModule_GetDict(py_module);
PyObject* py_op = PyDict_GetItemString(py_dict, op.c_str());
CHECK(py_op) << "\nFail not import operator: " << op
<< " from module: " << module;
CHECK(py_op) << "\nFailed to Import Operator: " << op
<< " from Module: " << module;
self = PyObject_CallObject(py_op, NULL);
// wrap inputs and outputs
......@@ -46,9 +46,22 @@ RunOp<Context>::RunOp(const OperatorDef& def, Workspace* ws)
PyObject_SetAttr(self, Bytes("param_str_"), CS2Bytes(param_str));
// backward compatibility: self.setup(inputs, outputs)
if (PyObject_HasAttr(self, Bytes("setup"))) {
PyObject_CallMethod(self, "setup", "OO", inputs, outputs);
}
if (PyObject_HasAttr(self, Bytes("setup")))
CHECK(PyObject_CallMethod(
self, "setup", "OO", inputs, outputs))
<< CallMethodHelper("setup");
}
template <class Context>
string RunOp<Context>::CallMethodHelper(
const string& method) {
std::stringstream ss;
ss <<"\nFailed to call: "
<< "<" + module << "." << op
<< "." << method << "(*args, **kwargs)>\n"
<< "This is a FATAL error to terminate "
<< "<" << name() << ">.";
return ss.str();
}
template <class Context>
......@@ -58,14 +71,20 @@ void RunOp<Context>::RunOnDevice() {
// backward compatibility: reshape(inputs, outputs)
if (PyObject_HasAttr(self, Bytes("reshape"))) {
PyObject_CallMethod(self, "reshape", "OO", inputs, outputs);
CHECK(PyObject_CallMethod(
self, "reshape", "OO", inputs, outputs))
<< CallMethodHelper("reshape");
}
// overloaded run inferfaces
if (PyObject_HasAttr(self, Bytes("forward"))) {
PyObject_CallMethod(self, "forward", "OO", inputs, outputs);
CHECK(PyObject_CallMethod(
self, "forward", "OO", inputs, outputs))
<< CallMethodHelper("forward");
} else if (PyObject_HasAttr(self, Bytes("run"))) {
PyObject_CallMethod(self, "run", "OO", inputs, outputs);
CHECK(PyObject_CallMethod(
self, "run", "OO", inputs, outputs))
<< CallMethodHelper("run");
}
}
......@@ -85,17 +104,20 @@ void TemplateGradientOp<Context>::RunOnDevice() {
// backward compatibility: reshape(inputs, outputs)
if (PyObject_HasAttr(this->self, Bytes("reshape"))) {
PyObject_CallMethod(this->self, "reshape",
"OO", this->inputs, this->outputs);
CHECK(PyObject_CallMethod(this->self, "reshape",
"OO", this->inputs, this->outputs))
<< this->CallMethodHelper("reshape");
}
// overloaded run inferfaces
if (PyObject_HasAttr(this->self, Bytes("backward"))) {
PyObject_CallMethod(this->self, "forward",
"OO", this->inputs, this->outputs);
CHECK(PyObject_CallMethod(this->self, "backward",
"OO", this->inputs, this->outputs))
<< this->CallMethodHelper("backward");
} else if (PyObject_HasAttr(this->self, Bytes("grad"))) {
PyObject_CallMethod(this->self, "grad",
"OO", this->inputs, this->outputs);
CHECK(PyObject_CallMethod(this->self, "grad",
"OO", this->inputs, this->outputs))
<< this->CallMethodHelper("grad");
}
}
......
#include "operators/mpi/mpi_broadcast_op.h"
#include "utils/math_functions.h"
#include "operators/mpi/mpi_broadcast_op.h"
#ifdef WITH_MPI
......
#include "operators/mpi/mpi_gather_op.h"
#include "utils/math_functions.h"
#include "operators/mpi/mpi_gather_op.h"
#ifdef WITH_MPI
......
#include "operators/ndarray/arange_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/ndarray/arange_op.h"
namespace dragon {
......
#include "operators/ndarray/argreduce_op.h"
#include "utils/op_kernel.h"
#include "operators/ndarray/argreduce_op.h"
namespace dragon {
......
#include "operators/ndarray/concat_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/ndarray/concat_op.h"
namespace dragon {
......
#include "operators/ndarray/crop_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/ndarray/crop_op.h"
namespace dragon {
......
#include "operators/ndarray/expand_dims_op.h"
#include "core/workspace.h"
#include "operators/ndarray/expand_dims_op.h"
namespace dragon {
......@@ -9,7 +9,8 @@ void ExpandDimsOp<Context>::RunOnDevice() {
if (axis == -1 || axis >= (int)dims.size()) dims.push_back(1);
else dims.insert(dims.begin() + axis, 1);
// save Xshape
Tensor* sv = ws()->CreateTensor("/mnt/" + anchor() + "/expand_dims/x_shape");
Tensor* sv = ws()->CreateTensor(
"/mnt/" + anchor() + "/expand_dims/x_shape");
sv->Reshape({ (TIndex)Input(0).ndim() });
auto* Sdata = sv->template mutable_data<TIndex, CPUContext>();
for (int i = 0; i < Input(0).ndim(); i++) Sdata[i] = Input(0).dim(i);
......@@ -22,11 +23,14 @@ DEPLOY_CPU(ExpandDims);
#ifdef WITH_CUDA
DEPLOY_CUDA(ExpandDims);
#endif
OPERATOR_SCHEMA(ExpandDims).NumInputs(1).NumOutputs(1).Inplace({ { 0, 0 } });
OPERATOR_SCHEMA(ExpandDims)
.NumInputs(1).NumOutputs(1)
.Inplace({ { 0, 0 } });
template <class Context>
void ExpandDimsGradientOp<Context>::RunOnDevice() {
Tensor* sv = ws()->GetTensor("/mnt/" + anchor() + "/expand_dims/x_shape");
Tensor* sv = ws()->GetTensor(
"/mnt/" + anchor() + "/expand_dims/x_shape");
auto* Sdata = sv->template mutable_data<TIndex, CPUContext>();
vector<TIndex> x_shape(sv->count());
for (int i = 0; i < sv->count(); i++) x_shape[i] = Sdata[i];
......@@ -39,7 +43,9 @@ DEPLOY_CPU(ExpandDimsGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(ExpandDimsGradient);
#endif
OPERATOR_SCHEMA(ExpandDimsGradient).NumInputs(1).NumOutputs(1).Inplace({ { 0, 0 } });
OPERATOR_SCHEMA(ExpandDimsGradient)
.NumInputs(1).NumOutputs(1)
.Inplace({ { 0, 0 } });
class GetExpandDimsGradient final : public GradientMakerBase {
public:
......
#include "operators/ndarray/flatten_op.h"
#include "core/workspace.h"
#include "operators/ndarray/flatten_op.h"
namespace dragon {
......@@ -28,8 +28,12 @@ void FlattenOp<Context>::KeepRun() {
<< ", can not keep " + keep_axes << " .";
vector<TIndex> output_dims;
int i = 0;
for (; i < keep_axes - 1; i++) output_dims.push_back(Input(0).dim(i));
if (Input(0).count(i) != 1) output_dims.push_back(Input(0).count(i));
for (; i < keep_axes - 1; i++)
output_dims.push_back(Input(0).dim(i));
if (Input(0).count(i) != 1)
output_dims.push_back(Input(0).count(i));
if (Output(0)->name() != Input(0).name())
Output(0)->template Copy<Context, Context>(Input(0));
}
......@@ -37,10 +41,12 @@ void FlattenOp<Context>::KeepRun() {
template <class Context>
void FlattenOp<Context>::RunOnDevice() {
// save Xshape
Tensor* sv = ws()->CreateTensor("/mnt/" + anchor() + "/flatten/x_shape");
Tensor* sv = ws()->CreateTensor(
"/mnt/" + anchor() + "/flatten/x_shape");
sv->Reshape({ (TIndex)Input(0).ndim() });
auto* Sdata = sv->template mutable_data<TIndex, CPUContext>();
for (int i = 0; i < Input(0).ndim(); i++) Sdata[i] = Input(0).dim(i);
for (int i = 0; i < Input(0).ndim(); i++)
Sdata[i] = Input(0).dim(i);
if (keep_axes != INT_MAX) KeepRun();
else SqueezeRun();
}
......@@ -49,12 +55,15 @@ DEPLOY_CPU(Flatten);
#ifdef WITH_CUDA
DEPLOY_CUDA(Flatten);
#endif
OPERATOR_SCHEMA(Flatten).NumInputs(1).NumOutputs(1).Inplace({ { 0, 0 } });
OPERATOR_SCHEMA(Flatten)
.NumInputs(1).NumOutputs(1)
.Inplace({ { 0, 0 } });
template <class Context>
void FlattenGradientOp<Context>::RunOnDevice() {
Tensor* sv = ws()->GetTensor("/mnt/" + anchor() + "/flatten/x_shape");
Tensor* sv = ws()->GetTensor(
"/mnt/" + anchor() + "/flatten/x_shape");
auto* Sdata = sv->template mutable_data<TIndex, CPUContext>();
vector<TIndex> x_shape(sv->count());
for (int i = 0; i < sv->count(); i++) x_shape[i] = Sdata[i];
......@@ -67,7 +76,9 @@ DEPLOY_CPU(FlattenGradient);
#ifdef WITH_CUDA
DEPLOY_CUDA(FlattenGradient);
#endif
OPERATOR_SCHEMA(FlattenGradient).NumInputs(1).NumOutputs(1).Inplace({ { 0, 0 } });
OPERATOR_SCHEMA(FlattenGradient)
.NumInputs(1).NumOutputs(1)
.Inplace({ { 0, 0 } });
class GetFlattenGradient final : public GradientMakerBase {
public:
......
#include "operators/ndarray/gather_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/ndarray/gather_op.h"
namespace dragon {
......@@ -29,7 +29,8 @@ void GatherOp<Context>::RunOnDevice() {
inner_dim = Input(0).count(axis + 1);
Output(0)->Reshape(output_dims);
CHECK(Input(1).template IsType<int>()) << "\nThe type of indices should be int32.";
CHECK(Input(1).template IsType<int>())
<< "\nThe type of indices should be int32.";
if (XIsType(Input(0), float)) RunWithType<float>();
else if (XIsType(Input(0), int)) RunWithType<int>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "int32" });
......@@ -62,7 +63,8 @@ void GatherGradientOp<Context>::RunOnDevice() {
inner_dim = Input(0).count(axis + 1);
Output(0)->ReshapeLike(Input(0));
CHECK(Input(1).template IsType<int>()) << "\nThe type of indices should be int32.";
CHECK(Input(1).template IsType<int>())
<< "\nThe type of indices should be int32.";
if (XIsType(Input(0), float)) RunWithType<float>();
else if (XIsType(Input(0), int)) RunWithType<int>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32", "int32" });
......
#include "operators/ndarray/one_hot_op.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/ndarray/one_hot_op.h"
namespace dragon {
......
#include "operators/ndarray/pad_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/ndarray/pad_op.h"
namespace dragon {
......@@ -53,8 +53,10 @@ void PadOp<Context>::EdgeRunWithType() {
template <class Context>
void PadOp<Context>::RunOnDevice() {
CHECK_EQ(Input(0).ndim(), pad_l.size())
<< "\nThe padding is performed on " << pad_l.size() << " dimensions, "
<< "but the num of dimensions of input is " << Input(0).ndim() << ".";
<< "\nThe padding is performed on "
<< pad_l.size() << " dimensions, "
<< "but the num of dimensions of input is "
<< Input(0).ndim() << ".";
// do nothing
if (process_axes.size() == 0) {
......@@ -80,11 +82,15 @@ void PadOp<Context>::RunOnDevice() {
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
} else if (mode == "REFLECT") {
CHECK_LE(pad_l[axis], dim + 1)
<< "\nThe dimension of axis " << axis << " is " << dim << ","
<< "\nwhile the excepted bounds of pad_l for reflecting are (0, " << dim + 1 << "].";
<< "\nThe dimension of axis " << axis
<< " is " << dim << ","
<< "\nwhile the excepted bounds of pad_l "
<< "for reflecting are (0, " << dim + 1 << "].";
CHECK_LE(pad_r[axis], dim - 1)
<< "\nThe dimension of axis " << axis << " is " << dim << ","
<< "\nwhile the excepted bounds of pad_r for reflecting are (0, " << dim - 1 << "].";
<< "\nThe dimension of axis " << axis
<< " is " << dim << ","
<< "\nwhile the excepted bounds of pad_r "
<< "for reflecting are (0, " << dim - 1 << "].";
if (XIsType(Input(0), float)) ReflectRunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
} else if (mode == "EDGE") {
......@@ -161,8 +167,10 @@ void PadGradientOp<Context>::EdgeRunWithType() {
template <class Context>
void PadGradientOp<Context>::RunOnDevice() {
CHECK_EQ(Input(0).ndim(), pad_l.size())
<< "\nThe padding is performed on " << pad_l.size() << " dimensions, "
<< "but the number of dimensions of input is " << Input(0).ndim() << ".";
<< "\nThe padding is performed on "
<< pad_l.size() << " dimensions, "
<< "but the number of dimensions of input is "
<< Input(0).ndim() << ".";
// do nothing
if (process_axes.size() == 0) {
......@@ -188,11 +196,15 @@ void PadGradientOp<Context>::RunOnDevice() {
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
} else if (mode == "REFLECT") {
CHECK_LE(pad_l[axis], dim + 1)
<< "\nThe dimension of axis " << axis << " is " << dim << ","
<< "\nwhile the excepted bounds of pad_l for reflecting are (0, " << dim + 1 << "].";
<< "\nThe dimension of axis " << axis
<< " is " << dim << ","
<< "\nwhile the excepted bounds of pad_l "
<< "for reflecting are (0, " << dim + 1 << "].";
CHECK_LE(pad_r[axis], dim - 1)
<< "\nThe dimension of axis " << axis << " is " << dim << ","
<< "\nwhile the excepted bounds of pad_r for reflecting are (0, " << dim - 1 << "].";
<< "\nThe dimension of axis " << axis
<< " is " << dim << ","
<< "\nwhile the excepted bounds of pad_r "
<< "for reflecting are (0, " << dim - 1 << "].";
if (XIsType(Input(0), float)) ReflectRunWithType<float>();
else LOG(FATAL) << DTypeHelper(Input(0), { "float32" });
} else if (mode == "EDGE") {
......
#include "operators/ndarray/random_pick_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/ndarray/random_pick_op.h"
namespace dragon {
template <class Context> template <typename T>
void RandomPickOp<Context>::RunWithType() {
auto* indices = pick_indices->template mutable_data<int, CPUContext>();
/*
for (int i = 0; i < pick_indices->count(); i++)
indices[i] = int((*ctx().rand_generator())() % x_slice_dim); */
indices[i] = int((*ctx().rand_generator())() % x_slice_dim);
auto* Xdata = Input(0).template data<T, Context>();
indices = pick_indices->template mutable_data<int, Context>();
......@@ -31,7 +30,8 @@ void RandomPickOp<Context>::RunOnDevice() {
inner_dim = Input(0).count(axis + 1);
Output(0)->Reshape(output_dims);
pick_indices = ws()->CreateTensor("/mnt/" + anchor() + "/pick/indices");
pick_indices = ws()->CreateTensor(
"/mnt/" + anchor() + "/pick/indices");
pick_indices->Reshape({ max_samples });
if (XIsType(Input(0), float)) RunWithType<float>();
......@@ -64,7 +64,8 @@ void RandomPickGradientOp<Context>::RunWithType() {
template <class Context>
void RandomPickGradientOp<Context>::RunOnDevice() {
pick_indices = ws()->GetTensor("/mnt/" + anchor() + "/pick/indices");
pick_indices = ws()->GetTensor(
"/mnt/" + anchor() + "/pick/indices");
x_slice_dim = Input(0).dim(axis);
y_slice_dim = pick_indices->count();
......
#include "operators/ndarray/reduce_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/ndarray/reduce_op.h"
namespace dragon {
......
#include "operators/ndarray/repeat_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/ndarray/repeat_op.h"
namespace dragon {
......
#include "operators/ndarray/reshape_op.h"
#include "core/workspace.h"
#include "operators/ndarray/reshape_op.h"
namespace dragon {
......@@ -32,8 +32,8 @@ void ReshapeOp<Context>::RunOnDevice() {
if (require_shape[i] == 0) {
// handle unchanged dim
CHECK_LT(i, (int)Xdims.size())
<< "\nDim(" << i << ") is out of the Xdims range of (0, "
<< Xdims.size() << ").";
<< "\nDim(" << i << ") is out of the Xdims "
<< "range of (0, " << Xdims.size() << ").";
new_shape[i] = Xdims[i];
} else if (require_shape[i] > 0) {
// handle reseted dim
......@@ -41,8 +41,8 @@ void ReshapeOp<Context>::RunOnDevice() {
} else {
// handle inferred dim
CHECK_EQ(infer_dim, -1)
<< "\nDim(" << infer_dim << ") required infer before"
<< "\ncould not infer for dim(" << i << ") both.";
<< "\nCould not infer Dim( " << infer_dim << "), "
<< "Dim(" << i << ") both.";
new_shape[i] = -1;
infer_dim = i;
}
......@@ -55,7 +55,8 @@ void ReshapeOp<Context>::RunOnDevice() {
if (new_shape[i] == -1) {
CHECK_EQ(Input(0).count() % total_count, 0)
<< "\nCan not change the total size: "
<< Input(0).DimString() << " -> " << DimString(new_shape);
<< Input(0).DimString()
<< " -> " << DimString(new_shape);
new_shape[i] = Input(0).count() / total_count;
total_count *= new_shape[i];
break;
......@@ -64,9 +65,11 @@ void ReshapeOp<Context>::RunOnDevice() {
}
CHECK_EQ(total_count, Input(0).count())
<< "\nCan not change the total size."
<< Input(0).DimString() << " -> " << DimString(new_shape);
<< Input(0).DimString()
<< " -> " << DimString(new_shape);
// save Xshape
Tensor* sv = ws()->CreateTensor("/mnt/" + anchor() + "/reshape/x_shape");
Tensor* sv = ws()->CreateTensor(
"/mnt/" + anchor() + "/reshape/x_shape");
sv->Reshape({ (TIndex)Input(0).ndim() });
auto* Sdata = sv->template mutable_data<TIndex, CPUContext>();
for (int i = 0; i < Input(0).ndim(); i++) Sdata[i] = Input(0).dim(i);
......@@ -79,12 +82,15 @@ DEPLOY_CPU(Reshape);
#ifdef WITH_CUDA
DEPLOY_CUDA(Reshape);
#endif
OPERATOR_SCHEMA(Reshape).NumInputs(1).NumOutputs(1).Inplace({ { 0, 0 } });
OPERATOR_SCHEMA(Reshape)
.NumInputs(1).NumOutputs(1)
.Inplace({ { 0, 0 } });
template <class Context>
void ReshapeGradientOp<Context>::RunOnDevice() {
Tensor* sv = ws()->GetTensor("/mnt/" + anchor() + "/reshape/x_shape");
Tensor* sv = ws()->GetTensor(
"/mnt/" + anchor() + "/reshape/x_shape");
auto* Sdata = sv->template mutable_data<TIndex, CPUContext>();
vector<TIndex> x_shape(sv->count());
for (int i = 0; i < sv->count(); i++) x_shape[i] = Sdata[i];
......
#include "operators/ndarray/slice_op.h"
#include "utils/math_functions.h"
#include "utils/op_kernel.h"
#include "utils/math_functions.h"
#include "operators/ndarray/slice_op.h"
namespace dragon {
......
#include "operators/ndarray/stack_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/ndarray/stack_op.h"
namespace dragon {
......
#include "operators/ndarray/tile_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/ndarray/tile_op.h"
namespace dragon {
......
#include "operators/ndarray/transpose_op.h"
#include "core/workspace.h"
#include "utils/op_kernel.h"
#include "operators/ndarray/transpose_op.h"
namespace dragon {
......
#include "operators/norm/batch_norm_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/filler.h"
#include "utils/math_functions.h"
#include "operators/norm/batch_norm_op.h"
namespace dragon {
......
#include "operators/norm/batch_renorm_op.h"
#include "core/workspace.h"
#include "utils/math_functions.h"
#include "utils/filler.h"
#include "utils/math_functions.h"
#include "operators/norm/batch_renorm_op.h"
namespace dragon {
......
#include "operators/norm/batch_norm_op.h"
#include "core/workspace.h"
#include "utils/filler.h"
#include "operators/norm/batch_norm_op.h"
#ifdef WITH_CUDNN
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!