-
Notifications
You must be signed in to change notification settings - Fork 610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Linear Transformation kernel for CPU #1300
Changes from 123 commits
1584f61
d584290
a3f8104
dffea7e
fc4ea7b
0bc4c75
0d90738
7c7007b
ddeca11
969ebea
99e168a
9383459
7b20891
f5867c4
e8fec71
a825181
9af5c64
092b907
b3120df
3d09334
5aec1b0
7d31a5a
5696c01
ff8ec67
5049772
4f63345
a9b9eea
ebb2bfa
ec5116d
d54ada4
3a40a46
f3802d0
f60bf2e
2f0f1b2
94f716f
dcd3b77
cdf26fc
3cd1139
14bdb4b
8649c98
c50c840
0dc11c4
a835685
2fc1495
5b2bd4f
ecb39a2
b63e612
ce7ceb9
0abf9d3
7414446
45f0b58
e32d21a
9f1c5ba
6f84fcc
51264e3
ecf7aaa
3b184d5
23cff3d
c571a11
d72338e
ad0e3d8
148f65e
a8187ca
2af5721
258084c
a1c9865
fd9ff9c
0744dbd
2d00e34
8312d4c
0176be4
2a79823
0419cc8
3d48025
a0bd651
ddfbd0d
fd4cec6
d39109d
8479ef6
e522f77
da67362
b86939c
8c4bdff
e232dc9
23b035a
d152501
f0b0337
562ee2e
932b069
c5a7d4a
b399ee4
4985ea0
7d3f2a6
c5691ca
f4c46c0
918823c
4891484
4791ccb
91dcb3f
fa7d6a8
eafaf9a
00c443e
d2d9a99
3a2e492
1abed02
e5ff2b6
b6d8e54
7330d1f
62b44c9
d3a809b
15331ba
4af0d44
5b5c209
945f4b9
13473f8
2c8f833
403776b
0244f94
036ad6b
e4a7062
eb829bc
2a954c6
c2d90f3
83bd20a
c484b66
495d841
8a963bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (c) 2019, NVIDIA CORPORATION. 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. | ||
|
||
#ifndef DALI_KERNELS_IMGPROC_POINTWISE_LINEAR_TRANSFORMATION_CPU_H_ | ||
#define DALI_KERNELS_IMGPROC_POINTWISE_LINEAR_TRANSFORMATION_CPU_H_ | ||
|
||
#include <vector> | ||
#include <utility> | ||
#include "dali/core/format.h" | ||
#include "dali/core/convert.h" | ||
#include "dali/core/geom/box.h" | ||
#include "dali/kernels/common/block_setup.h" | ||
#include "dali/kernels/imgproc/surface.h" | ||
#include "dali/kernels/imgproc/roi.h" | ||
|
||
namespace dali { | ||
namespace kernels { | ||
|
||
template <typename OutputType, typename InputType, int channels_out, int channels_in, int ndims> | ||
class LinearTransformationCpu { | ||
private: | ||
static_assert(ndims == 3, "This kernel is currently implemented for 3 dims only"); | ||
static constexpr int spatial_ndims_ = ndims - 1; | ||
using Mat = ::dali::mat<channels_out, channels_in, float>; | ||
using Vec = ::dali::vec<channels_out, float>; | ||
|
||
public: | ||
KernelRequirements Setup(KernelContext &context, const InTensorCPU<InputType, ndims> &in, | ||
Mat tmatrix = Mat::eye(), Vec tvector = {}, | ||
const Roi<spatial_ndims_> *roi = nullptr) { | ||
DALI_ENFORCE(in.shape.shape.back() == channels_in, | ||
"Unexpected number of channels. Number of channels in InTensorCPU has to match" | ||
" the number of channels, that the kernel is instantiated with"); | ||
DALI_ENFORCE(!roi || all_coords(roi->hi >= roi->lo), | ||
make_string("Invalid ROI: it doesn't follow {lo, hi} convention. ", roi)); | ||
|
||
auto adjusted_roi = AdjustRoi(roi, in.shape); | ||
KernelRequirements req; | ||
TensorListShape<ndims> output_shape({ShapeFromRoi(adjusted_roi, channels_out)}); | ||
req.output_shapes = {std::move(output_shape)}; | ||
return req; | ||
} | ||
|
||
|
||
void Run(KernelContext &context, const OutTensorCPU<OutputType, ndims> &out, | ||
const InTensorCPU<InputType, ndims> &in, Mat tmatrix = Mat::eye(), Vec tvector = {}, | ||
const Roi<spatial_ndims_> *roi = nullptr) { | ||
auto adjusted_roi = AdjustRoi(roi, in.shape); | ||
auto ptr = out.data; | ||
auto in_width = in.shape[1]; | ||
|
||
for (int y = adjusted_roi.lo.y; y < adjusted_roi.hi.y; y++) { | ||
auto *row_ptr = &in.data[y * in_width * channels_in]; | ||
for (int x = adjusted_roi.lo.x; x < adjusted_roi.hi.x; x++) { | ||
vec<channels_in, float> v_in; | ||
for (int k = 0; k < channels_in; k++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really, cause what I silently did here is casting the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove this static cast, as it will silence warnings if something really stupid happens (e.g. someone runs it on a tensor of boolean values). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
v_in[k] = row_ptr[channels_in * x + k]; | ||
} | ||
vec<channels_out> v_out = tmatrix * v_in + tvector; | ||
for (int k = 0; k < channels_out; k++) { | ||
*ptr++ = ConvertSat<OutputType>(v_out[k]); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
} // namespace kernels | ||
} // namespace dali | ||
|
||
#endif // DALI_KERNELS_IMGPROC_POINTWISE_LINEAR_TRANSFORMATION_CPU_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What else can it be? It looks like renaming John, Bob and Alice to JohnHuman, BobHumand and AliceHuman.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming test suites in a way, that it ends with
Test
seems to be quite a common thing. Be aware, that for a test caseTEST(Mat, Constructor)
gtest's macro-magic generates a classMat_Constructor
. In no case such name implies, that this class is actually a test. I'd say it's a thing we could add to the code style#1330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I strongly oppose making it a requirement. While I may even agree upon this in case of something as short as "Mat", adding "Test" to all test names will just add noise and produce long strings in GTest output.