27 #ifndef LBANN_LAYER_CROP_HPP_INCLUDED 28 #define LBANN_LAYER_CROP_HPP_INCLUDED 30 #pragma GCC diagnostic push 31 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 35 #include "lbann/proto/layers.pb.h" 49 template <
typename TensorDataType,
55 "crop layer only supports DATA_PARALLEL");
56 #ifdef LBANN_HAS_GPU_FP16 58 typename std::conditional<std::is_same<TensorDataType, fp16>::value,
60 TensorDataType>::type;
102 template <
typename ArchiveT>
107 std::string
get_type()
const override {
return "crop"; }
117 const auto& dist = input.DistData();
118 m_input_v.reset(input.Construct(input.Grid(), input.Root()));
119 m_output_v.reset(input.Construct(input.Grid(), input.Root()));
127 (dist.blockWidth == 1 ? El::ELEMENT : El::BLOCK),
134 std::stringstream err;
140 if (input_dims.size() != output_dims.size()) {
142 <<
"expects a crop input tensor with " << output_dims.size()
144 <<
"but parent layer " 146 <<
"outputs a tensor with " << input_dims.size() <<
" dimensions";
149 if (loc_dims.size() != 1 || loc_dims[0] != (int)input_dims.size()) {
151 <<
"expects a 1D crop position tensor with " << output_dims.size()
153 <<
"but parent layer " 155 <<
"outputs a tensor with dimensions ";
156 for (
size_t i = 0; i < loc_dims.size(); ++i) {
157 err << (i > 0 ?
" x " :
"") << loc_dims[i];
211 const El::Int num_dims = output_dims.size();
212 const auto& local_width = input.LocalWidth();
213 const auto& region_size = output_dims.back();
216 m_crop_pos_v->Empty(
false);
217 m_crop_pos_v->AlignWith(input);
219 if (m_crop_pos_v->DistData() == input1.DistData()) {
220 El::LockedView(*m_crop_pos_v, input1);
223 El::Copy(input1, *m_crop_pos_v);
225 const auto& local_crop_pos = m_crop_pos_v->LockedMatrix();
229 for (El::Int local_col = 0; local_col < local_width; ++local_col) {
230 const auto& col = input.GlobalCol(local_col);
233 std::vector<El::Int> crop_offsets;
234 for (El::Int d = 0; d < num_dims; ++d) {
235 const auto& pos = local_crop_pos(d, local_col);
238 std::stringstream err;
239 err <<
"crop position not in range [0,1] (pos=(";
240 for (El::Int i = 0; i < local_crop_pos.Height(); ++i) {
241 err << (i > 0 ?
"," :
"") << local_crop_pos(i, local_col);
246 const El::Int num_offsets = input_dims[d] - output_dims[d] + 1;
247 crop_offsets.push_back(
248 std::min(El::Int(static_cast<CompareType>(pos) * num_offsets),
253 std::vector<El::Int> output_pos(num_dims, 0);
254 while (output_pos[0] < output_dims[0]) {
257 auto input_index = output_pos[0] + crop_offsets[0];
258 auto output_index = output_pos[0];
259 for (El::Int d = 1; d < num_dims; ++d) {
261 (input_dims[d] * input_index + output_pos[d] + crop_offsets[d]);
262 output_index = output_dims[d] * output_index + output_pos[d];
264 El::LockedView(*m_input_v,
266 El::IR(input_index, input_index + region_size),
268 El::View(*m_output_v,
270 El::IR(output_index, output_index + region_size),
272 El::Copy(*m_input_v, *m_output_v);
275 output_pos.back() += region_size;
276 for (El::Int d = num_dims - 1; d >= 1; --d) {
277 if (output_pos[d] >= output_dims[d]) {
297 const auto& local_crop_pos = m_crop_pos_v->LockedMatrix();
302 const El::Int num_dims = output_dims.size();
303 const auto& local_width = gradient_wrt_input.LocalWidth();
304 const auto& region_size = output_dims.back();
308 for (El::Int local_col = 0; local_col < local_width; ++local_col) {
309 const auto& col = gradient_wrt_input.GlobalCol(local_col);
312 std::vector<El::Int> crop_offsets;
313 for (El::Int d = 0; d < num_dims; ++d) {
314 const auto& pos = local_crop_pos(d, local_col);
317 std::stringstream err;
318 err <<
"crop position not in range [0,1] (pos=(";
319 for (El::Int i = 0; i < local_crop_pos.Height(); ++i) {
320 err << (i > 0 ?
"," :
"") << local_crop_pos(i, local_col);
325 const El::Int num_offsets = input_dims[d] - output_dims[d] + 1;
326 crop_offsets.push_back(
327 std::min(El::Int(static_cast<CompareType>(pos) * num_offsets),
332 std::vector<El::Int> output_pos(num_dims, 0);
333 while (output_pos[0] < output_dims[0]) {
336 auto input_index = output_pos[0] + crop_offsets[0];
337 auto output_index = output_pos[0];
338 for (El::Int d = 1; d < num_dims; ++d) {
340 (input_dims[d] * input_index + output_pos[d] + crop_offsets[d]);
341 output_index = output_dims[d] * output_index + output_pos[d];
343 El::LockedView(*m_output_v,
345 El::IR(output_index, output_index + region_size),
349 El::IR(input_index, input_index + region_size),
351 El::Copy(*m_output_v, *m_input_v);
354 output_pos.back() += region_size;
355 for (El::Int d = num_dims - 1; d >= 1; --d) {
356 if (output_pos[d] >= output_dims[d]) {
375 template <
typename T, data_layout L, El::Device D>
378 proto.set_datatype(proto::ProtoDataType<T>);
379 auto* msg = proto.mutable_crop();
383 #ifndef LBANN_CROP_LAYER_INSTANTIATE 384 #define PROTO_DEVICE(T, Device) \ 385 extern template class crop_layer<T, data_layout::DATA_PARALLEL, Device> 389 #endif // LBANN_CROP_LAYER_INSTANTIATE 393 #pragma GCC diagnostic pop 394 #endif // LBANN_LAYER_CROP_HPP_INCLUDED std::unique_ptr< AbsDistMatrixType > m_input_v
crop_layer & operator=(const crop_layer &other)
virtual void setup_dims()
Setup tensor dimensions Called by the 'setup' function. If there are any input tensors, the base method sets all uninitialized output tensor dimensions equal to the first input tensor dimensions.
void fp_compute() override
Apply layer operation. Called by the 'forward_prop' function. Given the input tensors, the output tensors are populated with computed values.
int get_backprop_requirements() const override
Returns the necessary tensors for computing backpropagation.
friend class cereal::access
std::vector< int > get_input_dims(size_t input_index=0) const
Get input tensor dimensions.
void setup_dims() override
Setup tensor dimensions Called by the 'setup' function. If there are any input tensors, the base method sets all uninitialized output tensor dimensions equal to the first input tensor dimensions.
std::string get_type() const override
Get the layer type's name.
std::unique_ptr< AbsDistMatrixType > m_output_v
El::AbstractDistMatrix< TensorDataType > AbsDistMatrixType
The tensor type expected in this object.
void bp_compute() override
Compute objective funciton gradients. Called by the 'back_prop' function. Given the input...
void write_specific_proto(lbann_data::Layer &proto) const final
constexpr El::Device Device
OutputAbsDistMatrixType & get_prev_error_signals(int child_index=0)
InputAbsDistMatrixType & get_prev_activations(int parent_index=0)
std::unique_ptr< AbsDistMatrixType > m_crop_pos_v
const OutputAbsDistMatrixType & get_activations(const Layer &child) const override
void set_output_dims(std::vector< int > dims, size_t output_index=0)
Set output tensor dimensions.
void assign_to_repeated(google::protobuf::RepeatedField< T > &field, ContainerT const &values)
Assign a range of values to a repeated protobuf field.
void serialize(ArchiveT &ar)
Extract crop from tensor at a position.
TensorDataType CompareType
std::vector< const Layer * > get_parent_layers() const
std::string get_name() const
Get the layer instance's name.
crop_layer * copy() const override
Copy function. This function dynamically allocates memory for a layer instance and instantiates a cop...
El::Device get_device_allocation() const override
Get the device allocation for the data tensors. We assume that the decice allocation of the previous ...
data_layout
Data layout that is optimized for different modes of parallelism.
crop_layer(const crop_layer &other)
crop_layer(lbann_comm *comm, std::vector< int > dims)
void setup_data(size_t max_mini_batch_size) override
Setup layer data. Called by the 'setup' function. Memory is allocated for distributed matrices...
void setup_data(size_t max_mini_batch_size) override
std::vector< int > get_output_dims(size_t output_index=0) const
Get output tensor dimensions.
bool can_run_inplace() const override
If True, the computation can run in-place (feeding each input activations tensor as the corresponding...
data_layout get_data_layout() const override
Get data layout of the data tensors. We assume that the data layouts of the previous activations...
int m_expected_num_parent_layers
data_type_layer & operator=(data_type_layer &&other)=default
const InputAbsDistMatrixType & get_error_signals(const Layer &parent) const override