commit
483947c45d
@ -0,0 +1,48 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#include "paddle/framework/lod_rank_table.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
void LoDRankTable::Reset(const LoD& lod, size_t level) {
|
||||
this->coarse_lod_.clear();
|
||||
this->items_.clear();
|
||||
PADDLE_ENFORCE(level < lod.size(),
|
||||
"Cannot rank lod since the level %d is less than lod size %d",
|
||||
level, lod.size());
|
||||
coarse_lod_.reserve(level);
|
||||
for (size_t i = 0; i < level; ++i) {
|
||||
coarse_lod_.push_back(lod[i]);
|
||||
}
|
||||
auto& vec = lod[level];
|
||||
for (size_t i = 0; i < vec.size() - 1; ++i) {
|
||||
TableItem item;
|
||||
item.index = i;
|
||||
item.length = vec[i + 1] - vec[i];
|
||||
items_.emplace_back(item);
|
||||
}
|
||||
// NOTE(yuyang18):
|
||||
//
|
||||
// The time complexity of stable_sort is O(N*log(N)) if additional memory is
|
||||
// available. It is easy to debug and unit test when using `stable_sort`
|
||||
// instead of `sort`. Also, the items of a rank table will not be too large.
|
||||
std::stable_sort(items_.begin(), items_.end(),
|
||||
[](const TableItem& a, const TableItem& b) {
|
||||
return a.length > b.length;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace framework
|
||||
} // namespace paddle
|
@ -0,0 +1,55 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#pragma once
|
||||
#include "paddle/framework/lod_tensor.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
|
||||
// LoD Rank Table stores the `level` of `lod` which is ordered by sequence
|
||||
// length in descending order. It is useful when implement dynamic RNN and is
|
||||
// shared by dynamic RNN memory, dynamic RNN slice input and dynamic RNN slice
|
||||
// output operators.
|
||||
//
|
||||
// The table item contains two element. The length of sequence and the index of
|
||||
// sequence in that level.
|
||||
//
|
||||
// LoDRankTable also stores the coarse_lod, which is the lod information whose
|
||||
// level is less than input level, in order to restore the output LoD
|
||||
// information.
|
||||
class LoDRankTable {
|
||||
public:
|
||||
struct TableItem {
|
||||
size_t index;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
LoDRankTable() {}
|
||||
|
||||
void Reset(const LoD& lod, size_t level);
|
||||
|
||||
const std::vector<TableItem>& items() const { return this->items_; }
|
||||
|
||||
const LoD& coarse_lod() const { return this->coarse_lod_; }
|
||||
|
||||
size_t level() const { return coarse_lod_.size(); }
|
||||
|
||||
private:
|
||||
LoD coarse_lod_;
|
||||
std::vector<TableItem> items_;
|
||||
};
|
||||
|
||||
} // namespace framework
|
||||
} // namespace paddle
|
@ -0,0 +1,23 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "paddle/framework/lod_tensor.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
using LoDTensorArray = std::vector<LoDTensor>;
|
||||
}
|
||||
} // namespace paddle
|
@ -0,0 +1,154 @@
|
||||
/* Copyright (c) 2017 PaddlePaddle Authors. All Rights Reserve.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#include "MKLDNNAddtoLayer.h"
|
||||
|
||||
using namespace mkldnn; // NOLINT
|
||||
|
||||
namespace paddle {
|
||||
|
||||
REGISTER_LAYER(mkldnn_addto, MKLDNNAddtoLayer);
|
||||
|
||||
bool MKLDNNAddtoLayer::init(const LayerMap& layerMap,
|
||||
const ParameterMap& parameterMap) {
|
||||
if (!MKLDNNLayer::init(layerMap, parameterMap)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
layerSize_ = getSize();
|
||||
for (size_t i = 0; i < inputLayers_.size(); i++) {
|
||||
CHECK_EQ(layerSize_, inputLayers_[i]->getSize()) << "input size must equal";
|
||||
}
|
||||
if (biasParameter_.get() != NULL) {
|
||||
biases_ =
|
||||
std::unique_ptr<Weight>(new Weight(1, layerSize_, biasParameter_, 0));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::reshape(
|
||||
int& bs, int& ic, int& ih, int& iw, int oc, int& oh, int& ow) {
|
||||
CHECK_EQ(layerSize_, getSize()) << "this layer size can not be changed";
|
||||
reshapeInput(bs, ih, iw);
|
||||
ic = inputLayers_[0]->getSize() / ih / iw;
|
||||
CHECK_EQ((size_t)ic * ih * iw, inputLayers_[0]->getSize());
|
||||
CHECK_EQ(inputElemenCnt_, (size_t)bs * ic * ih * iw);
|
||||
for (size_t i = 0; i < inputLayers_.size(); i++) {
|
||||
CHECK_EQ(int64_t(bs), inputLayers_[i]->getOutput().getBatchSize());
|
||||
CHECK_EQ(layerSize_, inputLayers_[i]->getSize());
|
||||
}
|
||||
|
||||
oc = ic;
|
||||
oh = ih;
|
||||
ow = iw;
|
||||
reshapeOutput(oh, ow);
|
||||
resizeOutput(bs, oc * oh * ow);
|
||||
printSizeInfo();
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::resetFwd(std::vector<primitive>& pipeline,
|
||||
MKLDNNMatrixPtr& in,
|
||||
MKLDNNMatrixPtr& wgt,
|
||||
MKLDNNMatrixPtr& bias,
|
||||
MKLDNNMatrixPtr& out) {
|
||||
if (biases_) {
|
||||
LOG(FATAL) << "not implemented yet";
|
||||
}
|
||||
resetFwdBuffers(inVals_, out);
|
||||
in = inVals_[0];
|
||||
|
||||
std::shared_ptr<sum::primitive_desc> fwdPD;
|
||||
resetFwdPD(fwdPD, inVals_, out);
|
||||
|
||||
resetFwdPipeline(pipeline, fwdPD, inVals_, out);
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::resetBwd(std::vector<primitive>& pipeline,
|
||||
MKLDNNMatrixPtr& in,
|
||||
MKLDNNMatrixPtr& wgt,
|
||||
MKLDNNMatrixPtr& bias,
|
||||
MKLDNNMatrixPtr& out) {
|
||||
resetBwdBuffers(inGrads_, out);
|
||||
in = inGrads_[0];
|
||||
|
||||
// backward only need share output grad to input grad
|
||||
for (size_t i = 0; i < inGrads_.size(); i++) {
|
||||
if (inGrads_[i] != nullptr) {
|
||||
inGrads_[i] = out;
|
||||
inputLayers_[i]->getOutputGrad()->setData(inGrads_[i]->getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::updateWeights(const UpdateCallback& callback) {
|
||||
if (biases_ && biases_->getWGrad()) {
|
||||
biases_->getParameterPtr()->incUpdate(callback);
|
||||
}
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::resetFwdBuffers(std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr& out) {
|
||||
inputs.resize(inputLayers_.size());
|
||||
for (size_t i = 0; i < inputs.size(); i++) {
|
||||
resetInValue(inputs[i], nullptr, i);
|
||||
CHECK(inputs[i]);
|
||||
inputs[i]->downSpatial();
|
||||
}
|
||||
for (size_t i = 1; i < inputs.size(); i++) {
|
||||
CHECK_PRIMITIVE_DESC_EQ(inputs[i], inputs[0]->getPrimitiveDesc());
|
||||
}
|
||||
|
||||
resetOutValue(out, inputs[0]->getPrimitiveDesc());
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::resetFwdPD(std::shared_ptr<sum::primitive_desc>& pd,
|
||||
std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr out) {
|
||||
std::vector<double> scales(inputs.size(), 1.0);
|
||||
std::vector<memory::primitive_desc> srcPDs;
|
||||
for (size_t i = 0; i < inputs.size(); i++) {
|
||||
srcPDs.push_back(inputs[i]->getPrimitiveDesc());
|
||||
}
|
||||
CHECK(out);
|
||||
pd.reset(new sum::primitive_desc(out->getMemoryDesc(), scales, srcPDs));
|
||||
CHECK_PRIMITIVE_DESC_EQ(out, pd->dst_primitive_desc());
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::resetFwdPipeline(
|
||||
std::vector<primitive>& pipeline,
|
||||
std::shared_ptr<sum::primitive_desc>& pd,
|
||||
std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr& out) {
|
||||
std::vector<primitive::at> srcs;
|
||||
for (size_t i = 0; i < inputs.size(); i++) {
|
||||
srcs.push_back(*(inputs[i]));
|
||||
}
|
||||
fwd_.reset(new sum(*pd, srcs, *out));
|
||||
pipeline.push_back(*fwd_);
|
||||
}
|
||||
|
||||
void MKLDNNAddtoLayer::resetBwdBuffers(std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr& out) {
|
||||
CHECK(outVal_);
|
||||
resetOutGrad(out, outVal_->getPrimitiveDesc());
|
||||
CHECK(out);
|
||||
|
||||
inputs.resize(inputLayers_.size());
|
||||
for (size_t i = 0; i < inputs.size(); i++) {
|
||||
resetInGrad(inputs[i], inVal_->getPrimitiveDesc(), i);
|
||||
CHECK_PRIMITIVE_DESC_EQ(inputs[i], out->getPrimitiveDesc());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace paddle
|
@ -0,0 +1,110 @@
|
||||
/* Copyright (c) 2017 PaddlePaddle Authors. All Rights Reserve.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MKLDNNLayer.h"
|
||||
#include "mkldnn.hpp"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
/**
|
||||
* @brief A subclass of MKLDNNLayer Addto layer.
|
||||
*
|
||||
* The config file api is mkldnn_addto
|
||||
*/
|
||||
class MKLDNNAddtoLayer : public MKLDNNLayer {
|
||||
protected:
|
||||
std::vector<MKLDNNMatrixPtr> inVals_;
|
||||
std::vector<MKLDNNMatrixPtr> inGrads_;
|
||||
|
||||
// layer size == ic * ih * iw == oc * oh *ow, and can not be changed
|
||||
size_t layerSize_;
|
||||
|
||||
// TODO(TJ): this part has not been optimized by MKL-DNN
|
||||
std::unique_ptr<Weight> biases_;
|
||||
|
||||
public:
|
||||
explicit MKLDNNAddtoLayer(const LayerConfig& config) : MKLDNNLayer(config) {}
|
||||
|
||||
~MKLDNNAddtoLayer() {}
|
||||
|
||||
bool init(const LayerMap& layerMap,
|
||||
const ParameterMap& parameterMap) override;
|
||||
|
||||
void reshape(
|
||||
int& bs, int& ic, int& ih, int& iw, int oc, int& oh, int& ow) override;
|
||||
|
||||
void resetFwd(std::vector<mkldnn::primitive>& pipeline,
|
||||
MKLDNNMatrixPtr& in,
|
||||
MKLDNNMatrixPtr& wgt,
|
||||
MKLDNNMatrixPtr& bias,
|
||||
MKLDNNMatrixPtr& out) override;
|
||||
|
||||
void resetBwd(std::vector<mkldnn::primitive>& pipeline,
|
||||
MKLDNNMatrixPtr& in,
|
||||
MKLDNNMatrixPtr& wgt,
|
||||
MKLDNNMatrixPtr& bias,
|
||||
MKLDNNMatrixPtr& out) override;
|
||||
|
||||
void updateWeights(const UpdateCallback& callback) override;
|
||||
|
||||
void printValueFormat() override {
|
||||
for (size_t i = 0; i < inVals_.size(); ++i) {
|
||||
VLOG(MKLDNN_FMTS) << i << " input: " << inVals_[i]->getFormat() << " >>>";
|
||||
}
|
||||
if (outVal_) {
|
||||
VLOG(MKLDNN_FMTS) << outVal_->getFormat() << " >>> ";
|
||||
}
|
||||
if (extOutVal_) {
|
||||
VLOG(MKLDNN_FMTS) << extOutVal_->getFormat();
|
||||
}
|
||||
}
|
||||
|
||||
void printGradFormat() override {
|
||||
if (extOutGrad_) {
|
||||
VLOG(MKLDNN_FMTS) << extOutGrad_->getFormat();
|
||||
}
|
||||
if (outGrad_) {
|
||||
VLOG(MKLDNN_FMTS) << outGrad_->getFormat() << " <<< ";
|
||||
}
|
||||
for (size_t i = 0; i < inGrads_.size(); ++i) {
|
||||
VLOG(MKLDNN_FMTS) << i << " input: " << inGrads_[i]->getFormat() << "<<<";
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Forward functions: reset buffers(inputs, output, bias),
|
||||
* reset primitive descriptor,
|
||||
* reset pipeline.
|
||||
*/
|
||||
void resetFwdBuffers(std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr& out);
|
||||
void resetFwdPD(std::shared_ptr<mkldnn::sum::primitive_desc>& pd,
|
||||
std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr out);
|
||||
void resetFwdPipeline(std::vector<mkldnn::primitive>& pipeline,
|
||||
std::shared_ptr<mkldnn::sum::primitive_desc>& pd,
|
||||
std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr& out);
|
||||
|
||||
/**
|
||||
* Backward functions: reset buffers(inputs, output, bias)
|
||||
*/
|
||||
void resetBwdBuffers(std::vector<MKLDNNMatrixPtr>& inputs,
|
||||
MKLDNNMatrixPtr& out);
|
||||
};
|
||||
|
||||
} // namespace paddle
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue