[WIP] HSV,RGB color model conversions (#125)
* CUDA implementation for hsv_to_rgb and rgb_to_hsv Signed-off-by: raver119 <raver119@gmail.com> * hsv_to_rgb and rgb_to_hsv operations Test coverage: c order 1d, 2d, 3d array Signed-off-by: Abdelrauf <rauf@konduit.ai> * Index check Signed-off-by: Abdelrauf <rauf@konduit.ai> * Suppress Msvc floating point errors Signed-off-by: Abdelrauf <rauf@konduit.ai> * Added Index Check for adjust_saturation and adjust_hue Signed-off-by: Abdelrauf <rauf@konduit.ai> * minor fix Signed-off-by: raver119 <raver119@gmail.com> * Fixes missed Msvc floating narrowing errors Signed-off-by: Abdelrauf <rauf@konduit.ai>master
parent
bfd9e3692a
commit
e0a9cb6c08
|
@ -12,6 +12,21 @@
|
|||
"cmakeCommandArgs": " -DCUDA_BLAS=true -DLIBND4J_NAME=nd4jcuda -DMSVC_DEV=true -DCOMPUTE=61 -DBUILD_TESTS=true",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "WSL-GCC-Debug",
|
||||
"generator": "Unix Makefiles",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeExecutable": "/usr/bin/cmake",
|
||||
"cmakeCommandArgs": "-DLIBND4J_ALL_OPS=true -DCMAKE_BUILD_TYPE=Debug -DCPU_BLAS=true -DLIBND4J_NAME=nd4jcpu -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DOPENBLAS_PATH=/usr/lib/openblas-base/ -DEXTENSION=avx2 ",
|
||||
"buildCommandArgs": "-j 4",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "linux_x64" ],
|
||||
"wslPath": "${defaultWSLPath}",
|
||||
"addressSanitizerRuntimeFlags": "detect_leaks=0",
|
||||
"variables": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -41,6 +41,7 @@
|
|||
#include <ops/declarable/headers/tests.h>
|
||||
#include <ops/declarable/headers/kernels.h>
|
||||
#include <ops/declarable/headers/BarnesHutTsne.h>
|
||||
#include <ops/declarable/headers/color_models.h>
|
||||
#include <dll.h>
|
||||
#include <helpers/shape.h>
|
||||
#include <helpers/TAD.h>
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Konduit K.K.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License, Version 2.0 which is available at
|
||||
* https://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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include <ops/declarable/headers/color_models.h>
|
||||
#include <ops/declarable/CustomOperations.h>
|
||||
#include <helpers/ConstantTadHelper.h>
|
||||
#include <execution/Threads.h>
|
||||
|
||||
namespace nd4j {
|
||||
namespace ops {
|
||||
|
||||
|
||||
|
||||
CONFIGURABLE_OP_IMPL(hsv_to_rgb, 1, 1, false, 0, 0) {
|
||||
|
||||
auto input = INPUT_VARIABLE(0);
|
||||
auto output = OUTPUT_VARIABLE(0);
|
||||
|
||||
if (input->isEmpty())
|
||||
return Status::OK();
|
||||
|
||||
const int rank = input->rankOf();
|
||||
const int arg_size = block.getIArguments()->size();
|
||||
const int dimC = arg_size > 0 ? (INT_ARG(0) >= 0 ? INT_ARG(0) : INT_ARG(0) + rank) : rank - 1;
|
||||
|
||||
REQUIRE_TRUE(rank >= 1, 0, "HSVtoRGB: Fails to meet the rank requirement: %i >= 1 ", rank);
|
||||
if (arg_size > 0) {
|
||||
REQUIRE_TRUE(dimC >= 0 && dimC < rank, 0, "Index of the Channel dimension out of range: %i not in [%i,%i) ", INT_ARG(0), -rank, rank);
|
||||
}
|
||||
REQUIRE_TRUE(input->sizeAt(dimC) == 3, 0, "HSVtoRGB: operation expects 3 channels (H, S, V), but got %i instead", input->sizeAt(dimC));
|
||||
|
||||
helpers::transform_hsv_rgb(block.launchContext(), input, output, dimC);
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
CONFIGURABLE_OP_IMPL(rgb_to_hsv, 1, 1, false, 0, 0) {
|
||||
|
||||
auto input = INPUT_VARIABLE(0);
|
||||
auto output = OUTPUT_VARIABLE(0);
|
||||
|
||||
if (input->isEmpty())
|
||||
return Status::OK();
|
||||
|
||||
const int rank = input->rankOf();
|
||||
const int arg_size = block.getIArguments()->size();
|
||||
const int dimC = arg_size > 0 ? (INT_ARG(0) >= 0 ? INT_ARG(0) : INT_ARG(0) + rank) : rank - 1;
|
||||
|
||||
REQUIRE_TRUE(rank >= 1, 0, "RGBtoHSV: Fails to meet the rank requirement: %i >= 1 ", rank);
|
||||
if (arg_size > 0) {
|
||||
REQUIRE_TRUE(dimC >= 0 && dimC < rank, 0, "Index of the Channel dimension out of range: %i not in [%i,%i) ", INT_ARG(0), -rank, rank);
|
||||
}
|
||||
REQUIRE_TRUE(input->sizeAt(dimC) == 3, 0, "RGBtoHSV: operation expects 3 channels (H, S, V), but got %i instead", input->sizeAt(dimC));
|
||||
|
||||
helpers::transform_rgb_hsv(block.launchContext(), input, output, dimC);
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
|
||||
DECLARE_TYPES(hsv_to_rgb) {
|
||||
getOpDescriptor()->setAllowedInputTypes({ ALL_FLOATS })
|
||||
->setSameMode(true);
|
||||
}
|
||||
|
||||
DECLARE_TYPES(rgb_to_hsv) {
|
||||
getOpDescriptor()->setAllowedInputTypes({ ALL_FLOATS })
|
||||
->setSameMode(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,10 +39,14 @@ CONFIGURABLE_OP_IMPL(adjust_hue, 1, 1, true, 0, 0) {
|
|||
return Status::OK();
|
||||
|
||||
const int rank = input->rankOf();
|
||||
const int dimC = block.getIArguments()->size() > 0 ? (INT_ARG(0) >= 0 ? INT_ARG(0) : INT_ARG(0) + rank) : rank - 1;
|
||||
const int arg_size = block.getIArguments()->size();
|
||||
const int dimC = arg_size > 0 ? (INT_ARG(0) >= 0 ? INT_ARG(0) : INT_ARG(0) + rank) : rank - 1;
|
||||
|
||||
REQUIRE_TRUE(block.numT() > 0 || block.width() > 1, 0, "ADJUST_HUE: delta factor is required !");
|
||||
REQUIRE_TRUE(rank >= 3, 0, "ADJUST_HUE: op expects rank of input array to be >= 3, but got %i instead", rank);
|
||||
if (arg_size > 0) {
|
||||
REQUIRE_TRUE(dimC >= 0 && dimC < rank, 0, "Index of the Channel dimension out of range: %i not in [%i,%i) ", INT_ARG(0), -rank, rank);
|
||||
}
|
||||
REQUIRE_TRUE(input->sizeAt(dimC) == 3, 0, "ADJUST_HUE: operation expects image with 3 channels (R, G, B), but got %i instead", input->sizeAt(dimC));
|
||||
|
||||
NDArray* delta = nullptr;
|
||||
|
|
|
@ -38,9 +38,13 @@ CONFIGURABLE_OP_IMPL(adjust_saturation, 1, 1, true, 0, 0) {
|
|||
return Status::OK();
|
||||
|
||||
const int rank = input->rankOf();
|
||||
const int dimC = block.getIArguments()->size() > 0 ? (INT_ARG(0) >= 0 ? INT_ARG(0) : INT_ARG(0) + rank) : rank - 1;
|
||||
const int arg_size = block.getIArguments()->size();
|
||||
const int dimC = arg_size > 0 ? (INT_ARG(0) >= 0 ? INT_ARG(0) : INT_ARG(0) + rank) : rank - 1;
|
||||
|
||||
REQUIRE_TRUE(rank >= 3, 0, "ADJUST_SATURATION: op expects rank of input array to be >= 3, but got %i instead", rank);
|
||||
if (arg_size > 0) {
|
||||
REQUIRE_TRUE(dimC >= 0 && dimC < rank, 0, "Index of the Channel dimension out of range: %i not in [%i,%i) ", INT_ARG(0), -rank, rank);
|
||||
}
|
||||
REQUIRE_TRUE(input->sizeAt(dimC) == 3, 0, "ADJUST_SATURATION: operation expects image with 3 channels (R, G, B), but got %i instead", input->sizeAt(dimC));
|
||||
REQUIRE_TRUE(block.numT() > 0 || block.width() > 1, 0, "ADJUST_SATURATION: scale factor is required !");
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Konduit K.K.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License, Version 2.0 which is available at
|
||||
* https://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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef LIBND4J_HEADERS_COLOR_MODELS_H
|
||||
#define LIBND4J_HEADERS_COLOR_MODELS_H
|
||||
|
||||
#include <ops/declarable/headers/common.h>
|
||||
#include <ops/declarable/CustomOperations.h>
|
||||
#include <helpers/ConstantTadHelper.h>
|
||||
#include <execution/Threads.h>
|
||||
#include <ops/declarable/helpers/color_models_conv.h>
|
||||
|
||||
namespace nd4j {
|
||||
namespace ops {
|
||||
|
||||
/**
|
||||
* Rgb To Hsv
|
||||
* Input arrays:
|
||||
* 0 - input array with rank >= 1, must have at least one dimension equal 3, that is dimension containing channels.
|
||||
* Int arguments:
|
||||
* 0 - optional argument, corresponds to dimension with 3 channels
|
||||
*/
|
||||
#if NOT_EXCLUDED(OP_rgb_to_hsv)
|
||||
DECLARE_CONFIGURABLE_OP(rgb_to_hsv, 1, 1, false, 0, 0);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Hsv To Rgb
|
||||
* Input arrays:
|
||||
* 0 - input array with rank >= 1, must have at least one dimension equal 3, that is dimension containing channels.
|
||||
* Int arguments:
|
||||
* 0 - optional argument, corresponds to dimension with 3 channels
|
||||
*/
|
||||
#if NOT_EXCLUDED(OP_hsv_to_rgb)
|
||||
DECLARE_CONFIGURABLE_OP(hsv_to_rgb, 1, 1, false, 0, 0);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Konduit K.K.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License, Version 2.0 which is available at
|
||||
* https://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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
******************************************************************************/
|
||||
|
||||
#include <op_boilerplate.h>
|
||||
#include <templatemath.h>
|
||||
#include <NDArray.h>
|
||||
|
||||
namespace nd4j {
|
||||
namespace ops {
|
||||
namespace helpers {
|
||||
|
||||
void transform_hsv_rgb(nd4j::LaunchContext* context, const NDArray* input, NDArray* output, const int dimC);
|
||||
void transform_rgb_hsv(nd4j::LaunchContext* context, const NDArray* input, NDArray* output, const int dimC);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Konduit K.K.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License, Version 2.0 which is available at
|
||||
* https://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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
******************************************************************************/
|
||||
|
||||
#include <ops/declarable/helpers/adjust_hue.h>
|
||||
#include <ops/declarable/helpers/color_models_conv.h>
|
||||
#include <helpers/ConstantTadHelper.h>
|
||||
#include <execution/Threads.h>
|
||||
|
||||
namespace nd4j {
|
||||
namespace ops {
|
||||
namespace helpers {
|
||||
|
||||
//local
|
||||
template <typename T, typename Op>
|
||||
FORCEINLINE static void triple_transformer(const NDArray* input, NDArray* output, const int dimC, Op op) {
|
||||
|
||||
const int rank = input->rankOf();
|
||||
|
||||
const T* x = input->bufferAsT<T>();
|
||||
T* z = output->bufferAsT<T>();
|
||||
|
||||
if (dimC == rank - 1 && input->ews() == 1 && output->ews() == 1 && input->ordering() == 'c' && output->ordering() == 'c') {
|
||||
|
||||
auto func = PRAGMA_THREADS_FOR{
|
||||
for (auto i = start; i < stop; i += increment) {
|
||||
op(x[i], x[i + 1], x[i + 2], z[i], z[i + 1], z[i + 2]);
|
||||
}
|
||||
};
|
||||
|
||||
samediff::Threads::parallel_for(func, 0, input->lengthOf(), 3);
|
||||
}
|
||||
else {
|
||||
auto packX = nd4j::ConstantTadHelper::getInstance()->tadForDimensions(input->getShapeInfo(), dimC);
|
||||
auto packZ = nd4j::ConstantTadHelper::getInstance()->tadForDimensions(output->getShapeInfo(), dimC);
|
||||
|
||||
const Nd4jLong numOfTads = packX.numberOfTads();
|
||||
const Nd4jLong xDimCstride = input->stridesOf()[dimC];
|
||||
const Nd4jLong zDimCstride = output->stridesOf()[dimC];
|
||||
|
||||
auto func = PRAGMA_THREADS_FOR{
|
||||
for (auto i = start; i < stop; i += increment) {
|
||||
const T* xTad = x + packX.platformOffsets()[i];
|
||||
T* zTad = z + packZ.platformOffsets()[i];
|
||||
op(xTad[0], xTad[xDimCstride], xTad[2 * xDimCstride], zTad[0], zTad[zDimCstride], zTad[2 * zDimCstride]);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
samediff::Threads::parallel_tad(func, 0, numOfTads);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
FORCEINLINE static void hsv_rgb(const NDArray* input, NDArray* output, const int dimC) {
|
||||
auto op = nd4j::ops::helpers::hsvToRgb<T>;
|
||||
return triple_transformer<T>(input, output, dimC, op);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCEINLINE static void rgb_hsv(const NDArray* input, NDArray* output, const int dimC) {
|
||||
auto op = nd4j::ops::helpers::rgbToHsv<T>;
|
||||
return triple_transformer<T>(input, output, dimC, op);
|
||||
}
|
||||
|
||||
void transform_hsv_rgb(nd4j::LaunchContext* context, const NDArray* input, NDArray* output, const int dimC) {
|
||||
BUILD_SINGLE_SELECTOR(input->dataType(), hsv_rgb, (input, output, dimC), FLOAT_TYPES);
|
||||
}
|
||||
|
||||
void transform_rgb_hsv(nd4j::LaunchContext* context, const NDArray* input, NDArray* output, const int dimC) {
|
||||
BUILD_SINGLE_SELECTOR(input->dataType(), rgb_hsv, (input, output, dimC), FLOAT_TYPES);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Konduit K.K.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License, Version 2.0 which is available at
|
||||
* https://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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
******************************************************************************/
|
||||
#include <ops/declarable/helpers/color_models_conv.h>
|
||||
#include <ops/declarable/helpers/adjust_hue.h>
|
||||
#include <ops/declarable/helpers/adjust_saturation.h>
|
||||
#include <helpers/ConstantTadHelper.h>
|
||||
#include <PointersManager.h>
|
||||
|
||||
namespace nd4j {
|
||||
namespace ops {
|
||||
namespace helpers {
|
||||
|
||||
template <typename T>
|
||||
static void _CUDA_G rgbToHsvCuda(const void* vx, const Nd4jLong* xShapeInfo, const Nd4jLong* xTadOffsets,
|
||||
void* vz, const Nd4jLong *zShapeInfo, const Nd4jLong* zTadOffsets,
|
||||
const Nd4jLong numOfTads, const int dimC) {
|
||||
|
||||
const T* x = reinterpret_cast<const T*>(vx);
|
||||
T* z = reinterpret_cast<T*>(vz);
|
||||
|
||||
__shared__ int rank;
|
||||
__shared__ Nd4jLong xDimCstride, zDimCstride;
|
||||
|
||||
if (threadIdx.x == 0) {
|
||||
rank = shape::rank(xShapeInfo);
|
||||
xDimCstride = shape::stride(xShapeInfo)[dimC];
|
||||
zDimCstride = shape::stride(zShapeInfo)[dimC];
|
||||
}
|
||||
__syncthreads();
|
||||
|
||||
const auto tid = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
|
||||
for (Nd4jLong i = tid; i < numOfTads; i += gridDim.x * blockDim.x) {
|
||||
const T* xTad = x + xTadOffsets[i];
|
||||
T* zTad = z + zTadOffsets[i];
|
||||
|
||||
rgbToHsv<T>(xTad[0], xTad[xDimCstride], xTad[2 * xDimCstride], zTad[0], zTad[zDimCstride], zTad[2 * zDimCstride]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void _CUDA_G hsvToRgbCuda(const void* vx, const Nd4jLong* xShapeInfo, const Nd4jLong* xTadOffsets,
|
||||
void* vz, const Nd4jLong *zShapeInfo, const Nd4jLong* zTadOffsets,
|
||||
const Nd4jLong numOfTads, const int dimC) {
|
||||
|
||||
const T* x = reinterpret_cast<const T*>(vx);
|
||||
T* z = reinterpret_cast<T*>(vz);
|
||||
|
||||
__shared__ int rank;
|
||||
__shared__ Nd4jLong xDimCstride, zDimCstride;
|
||||
|
||||
if (threadIdx.x == 0) {
|
||||
rank = shape::rank(xShapeInfo);
|
||||
xDimCstride = shape::stride(xShapeInfo)[dimC];
|
||||
zDimCstride = shape::stride(zShapeInfo)[dimC];
|
||||
}
|
||||
__syncthreads();
|
||||
|
||||
const auto tid = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
|
||||
for (Nd4jLong i = tid; i < numOfTads; i += gridDim.x * blockDim.x) {
|
||||
const T* xTad = x + xTadOffsets[i];
|
||||
T* zTad = z + zTadOffsets[i];
|
||||
|
||||
hsvToRgb<T>(xTad[0], xTad[xDimCstride], xTad[2 * xDimCstride], zTad[0], zTad[zDimCstride], zTad[2 * zDimCstride]);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
static _CUDA_H void hsvToRgbCudaLauncher(const int blocksPerGrid, const int threadsPerBlock, const cudaStream_t *stream,
|
||||
const void* vx, const Nd4jLong* xShapeInfo, const Nd4jLong* xTadOffsets,
|
||||
void* vz, const Nd4jLong* zShapeInfo, const Nd4jLong* zTadOffsets,
|
||||
const Nd4jLong numOfTads, const int dimC) {
|
||||
|
||||
hsvToRgbCuda<T><<<blocksPerGrid, threadsPerBlock, 256, *stream>>>(vx, xShapeInfo, xTadOffsets, vz, zShapeInfo, zTadOffsets, numOfTads, dimC);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static _CUDA_H void rgbToHsvCudaLauncher(const int blocksPerGrid, const int threadsPerBlock, const cudaStream_t *stream,
|
||||
const void* vx, const Nd4jLong* xShapeInfo, const Nd4jLong* xTadOffsets,
|
||||
void* vz, const Nd4jLong* zShapeInfo, const Nd4jLong* zTadOffsets,
|
||||
const Nd4jLong numOfTads, const int dimC) {
|
||||
|
||||
rgbToHsvCuda<T><<<blocksPerGrid, threadsPerBlock, 256, *stream>>>(vx, xShapeInfo, xTadOffsets, vz, zShapeInfo, zTadOffsets, numOfTads, dimC);
|
||||
}
|
||||
|
||||
|
||||
void transform_hsv_rgb(nd4j::LaunchContext* context, const NDArray* input, NDArray* output, const int dimC) {
|
||||
auto packX = nd4j::ConstantTadHelper::getInstance()->tadForDimensions(input->getShapeInfo(), {dimC});
|
||||
auto packZ = nd4j::ConstantTadHelper::getInstance()->tadForDimensions(output->getShapeInfo(), {dimC});
|
||||
|
||||
const Nd4jLong numOfTads = packX.numberOfTads();
|
||||
|
||||
const int threadsPerBlock = MAX_NUM_THREADS / 2;
|
||||
const int blocksPerGrid = (numOfTads + threadsPerBlock - 1) / threadsPerBlock;
|
||||
|
||||
PointersManager manager(context, "hsv_to_rgb");
|
||||
|
||||
NDArray::prepareSpecialUse({output}, {input});
|
||||
BUILD_SINGLE_SELECTOR(input->dataType(), hsvToRgbCudaLauncher, (blocksPerGrid, threadsPerBlock, context->getCudaStream(), input->getSpecialBuffer(), input->getSpecialShapeInfo(), packX.platformOffsets(), output->specialBuffer(), output->specialShapeInfo(), packZ.platformOffsets(), numOfTads, dimC), FLOAT_TYPES);
|
||||
NDArray::registerSpecialUse({output}, {input});
|
||||
|
||||
manager.synchronize();
|
||||
}
|
||||
|
||||
void transform_rgb_hsv(nd4j::LaunchContext* context, const NDArray* input, NDArray* output, const int dimC) {
|
||||
auto packX = nd4j::ConstantTadHelper::getInstance()->tadForDimensions(input->getShapeInfo(), {dimC});
|
||||
auto packZ = nd4j::ConstantTadHelper::getInstance()->tadForDimensions(output->getShapeInfo(), {dimC});
|
||||
|
||||
const Nd4jLong numOfTads = packX.numberOfTads();
|
||||
|
||||
const int threadsPerBlock = MAX_NUM_THREADS / 2;
|
||||
const int blocksPerGrid = (numOfTads + threadsPerBlock - 1) / threadsPerBlock;
|
||||
|
||||
PointersManager manager(context, "rgb_to_hsv");
|
||||
|
||||
NDArray::prepareSpecialUse({output}, {input});
|
||||
BUILD_SINGLE_SELECTOR(input->dataType(), rgbToHsvCudaLauncher, (blocksPerGrid, threadsPerBlock, context->getCudaStream(), input->getSpecialBuffer(), input->getSpecialShapeInfo(), packX.platformOffsets(), output->specialBuffer(), output->specialShapeInfo(), packZ.platformOffsets(), numOfTads, dimC), FLOAT_TYPES);
|
||||
NDArray::registerSpecialUse({output}, {input});
|
||||
|
||||
manager.synchronize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -238,3 +238,458 @@ TEST_F(DeclarableOpsTests16, test_reverse_1) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_rgb_to_hsv_1) {
|
||||
/*
|
||||
test case generated by python colorsys and scaled to suit our needs
|
||||
from colorsys import *
|
||||
from random import *
|
||||
import numpy as np
|
||||
rgbs = np.array([randint(0,255) for x in range(0,3*4*5)]).reshape([5,4,3])
|
||||
hsvs=np.apply_along_axis(lambda x: np.array(rgb_to_hsv(x[0]/255,x[1]/255,x[2]/255))*np.array([360,1,1]),2,rgbs)
|
||||
rgbs.ravel()
|
||||
hsvs.ravel()
|
||||
*/
|
||||
auto rgbs = NDArrayFactory::create<float>('c', { 5, 4, 3 },
|
||||
{
|
||||
213.f, 220.f, 164.f, 121.f, 180.f, 180.f, 18.f, 245.f, 75.f, 235.f, 76.f, 74.f, 168.f,
|
||||
50.f, 233.f, 191.f, 132.f, 100.f, 207.f, 37.f, 245.f, 77.f, 250.f, 182.f, 111.f, 52.f,
|
||||
59.f, 193.f, 147.f, 137.f, 168.f, 103.f, 121.f, 48.f, 191.f, 187.f, 53.f, 82.f, 239.f,
|
||||
156.f, 37.f, 118.f, 244.f, 90.f, 7.f, 221.f, 98.f, 243.f, 12.f, 209.f, 192.f, 2.f,
|
||||
115.f, 205.f, 79.f, 247.f, 32.f, 70.f, 152.f, 180.f
|
||||
});
|
||||
auto expected = NDArrayFactory::create<float>('c', { 5, 4, 3 },
|
||||
{
|
||||
6.75000000e+01f, 2.54545455e-01f, 8.62745098e-01f, 1.80000000e+02f,
|
||||
3.27777778e-01f, 7.05882353e-01f, 1.35066079e+02f, 9.26530612e-01f,
|
||||
9.60784314e-01f, 7.45341615e-01f, 6.85106383e-01f, 9.21568627e-01f,
|
||||
2.78688525e+02f, 7.85407725e-01f, 9.13725490e-01f, 2.10989011e+01f,
|
||||
4.76439791e-01f, 7.49019608e-01f, 2.89038462e+02f, 8.48979592e-01f,
|
||||
9.60784314e-01f, 1.56416185e+02f, 6.92000000e-01f, 9.80392157e-01f,
|
||||
3.52881356e+02f, 5.31531532e-01f, 4.35294118e-01f, 1.07142857e+01f,
|
||||
2.90155440e-01f, 7.56862745e-01f, 3.43384615e+02f, 3.86904762e-01f,
|
||||
6.58823529e-01f, 1.78321678e+02f, 7.48691099e-01f, 7.49019608e-01f,
|
||||
2.30645161e+02f, 7.78242678e-01f, 9.37254902e-01f, 3.19159664e+02f,
|
||||
7.62820513e-01f, 6.11764706e-01f, 2.10126582e+01f, 9.71311475e-01f,
|
||||
9.56862745e-01f, 2.90896552e+02f, 5.96707819e-01f, 9.52941176e-01f,
|
||||
1.74822335e+02f, 9.42583732e-01f, 8.19607843e-01f, 2.06600985e+02f,
|
||||
9.90243902e-01f, 8.03921569e-01f, 1.06883721e+02f, 8.70445344e-01f,
|
||||
9.68627451e-01f, 1.95272727e+02f, 6.11111111e-01f, 7.05882353e-01f
|
||||
});
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 5,4,3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &rgbs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
|
||||
nd4j::ops::rgb_to_hsv op;
|
||||
auto status = op.execute(&ctx);
|
||||
#if 0
|
||||
//visual check
|
||||
rgbs.printBuffer("rgbs ");
|
||||
actual.printBuffer("HSV ");
|
||||
expected.printBuffer("exp");
|
||||
#endif
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_rgb_to_hsv_2) {
|
||||
/*
|
||||
swapped_rgbs=rgbs.swapaxes(1,2).ravel()
|
||||
swapped_hsvs=hsvs.swapaxes(1,2).ravel()
|
||||
*/
|
||||
auto rgbs = NDArrayFactory::create<float>('c', { 5,3,4 },
|
||||
{
|
||||
213.f, 121.f, 18.f, 235.f, 220.f, 180.f, 245.f, 76.f, 164.f, 180.f, 75.f, 74.f, 168.f,
|
||||
191.f, 207.f, 77.f, 50.f, 132.f, 37.f, 250.f, 233.f, 100.f, 245.f, 182.f, 111.f, 193.f,
|
||||
168.f, 48.f, 52.f, 147.f, 103.f, 191.f, 59.f, 137.f, 121.f, 187.f, 53.f, 156.f, 244.f,
|
||||
221.f, 82.f, 37.f, 90.f, 98.f, 239.f, 118.f, 7.f, 243.f, 12.f, 2.f, 79.f, 70.f,
|
||||
209.f, 115.f, 247.f, 152.f, 192.f, 205.f, 32.f, 180.f
|
||||
});
|
||||
auto expected = NDArrayFactory::create<float>('c', { 5,3,4 },
|
||||
{
|
||||
6.75000000e+01f, 1.80000000e+02f, 1.35066079e+02f, 7.45341615e-01f,
|
||||
2.54545455e-01f, 3.27777778e-01f, 9.26530612e-01f, 6.85106383e-01f,
|
||||
8.62745098e-01f, 7.05882353e-01f, 9.60784314e-01f, 9.21568627e-01f,
|
||||
2.78688525e+02f, 2.10989011e+01f, 2.89038462e+02f, 1.56416185e+02f,
|
||||
7.85407725e-01f, 4.76439791e-01f, 8.48979592e-01f, 6.92000000e-01f,
|
||||
9.13725490e-01f, 7.49019608e-01f, 9.60784314e-01f, 9.80392157e-01f,
|
||||
3.52881356e+02f, 1.07142857e+01f, 3.43384615e+02f, 1.78321678e+02f,
|
||||
5.31531532e-01f, 2.90155440e-01f, 3.86904762e-01f, 7.48691099e-01f,
|
||||
4.35294118e-01f, 7.56862745e-01f, 6.58823529e-01f, 7.49019608e-01f,
|
||||
2.30645161e+02f, 3.19159664e+02f, 2.10126582e+01f, 2.90896552e+02f,
|
||||
7.78242678e-01f, 7.62820513e-01f, 9.71311475e-01f, 5.96707819e-01f,
|
||||
9.37254902e-01f, 6.11764706e-01f, 9.56862745e-01f, 9.52941176e-01f,
|
||||
1.74822335e+02f, 2.06600985e+02f, 1.06883721e+02f, 1.95272727e+02f,
|
||||
9.42583732e-01f, 9.90243902e-01f, 8.70445344e-01f, 6.11111111e-01f,
|
||||
8.19607843e-01f, 8.03921569e-01f, 9.68627451e-01f, 7.05882353e-01f
|
||||
});
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 5,3,4 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &rgbs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
ctx.setIArguments({ 1 });
|
||||
nd4j::ops::rgb_to_hsv op;
|
||||
auto status = op.execute(&ctx);
|
||||
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_rgb_to_hsv_3) {
|
||||
/*
|
||||
2D
|
||||
*/
|
||||
auto rgbs = NDArrayFactory::create<float>('c', { 8,3 },
|
||||
{ 130.f, 61.f, 239.f, 117.f, 16.f, 168.f, 181.f, 223.f, 0.f, 49.f, 195.f, 195.f, 131.f,
|
||||
153.f, 78.f, 86.f, 21.f, 209.f, 101.f, 14.f, 107.f, 191.f, 98.f, 210.f });
|
||||
auto expected = NDArrayFactory::create<float>('c', { 8,3 },
|
||||
{ 263.25842697f, 0.74476987f, 0.9372549f, 279.86842105f,
|
||||
0.9047619f, 0.65882353f, 71.30044843f, 1.f,
|
||||
0.8745098f, 180.f, 0.74871795f, 0.76470588f,
|
||||
77.6f, 0.49019608f, 0.6f, 260.74468085f,
|
||||
0.89952153f, 0.81960784f, 296.12903226f, 0.86915888f,
|
||||
0.41960784f, 289.82142857f, 0.53333333f, 0.82352941f });
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 8,3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &rgbs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
|
||||
nd4j::ops::rgb_to_hsv op;
|
||||
auto status = op.execute(&ctx);
|
||||
#if 0
|
||||
//visual check
|
||||
rgbs.printBuffer("rgbs ");
|
||||
actual.printBuffer("HSV ");
|
||||
expected.printBuffer("exp");
|
||||
#endif
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_rgb_to_hsv_4) {
|
||||
/*
|
||||
2D
|
||||
*/
|
||||
auto rgbs = NDArrayFactory::create<float>('c', { 3,8 },
|
||||
{ 130.f, 117.f, 181.f, 49.f, 131.f, 86.f, 101.f, 191.f, 61.f, 16.f, 223.f, 195.f, 153.f,
|
||||
21.f, 14.f, 98.f, 239.f, 168.f, 0.f, 195.f, 78.f, 209.f, 107.f, 210.f });
|
||||
auto expected = NDArrayFactory::create<float>('c', { 3, 8 },
|
||||
{ 263.25842697f, 279.86842105f, 71.30044843f, 180.f,
|
||||
77.6f, 260.74468085f, 296.12903226f, 289.82142857f,
|
||||
0.74476987f, 0.9047619f, 1.f, 0.74871795f,
|
||||
0.49019608f, 0.89952153f, 0.86915888f, 0.53333333f,
|
||||
0.9372549f, 0.65882353f, 0.8745098f, 0.76470588f,
|
||||
0.6f, 0.81960784f, 0.41960784f, 0.82352941f });
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 3, 8 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &rgbs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
ctx.setIArguments({ 0 });
|
||||
nd4j::ops::rgb_to_hsv op;
|
||||
auto status = op.execute(&ctx);
|
||||
#if 0
|
||||
//visual check
|
||||
rgbs.printBuffer("rgbs ");
|
||||
actual.printBuffer("HSV ");
|
||||
expected.printBuffer("exp");
|
||||
#endif
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_rgb_to_hsv_5) {
|
||||
/*
|
||||
|
||||
*/
|
||||
auto rgbs = NDArrayFactory::create<float>('c', { 3 },
|
||||
{ 213.f, 220.f, 164.f });
|
||||
auto expected = NDArrayFactory::create<float>('c', { 3 },
|
||||
{ 6.75000000e+01f, 2.54545455e-01f, 8.62745098e-01f });
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &rgbs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
|
||||
nd4j::ops::rgb_to_hsv op;
|
||||
auto status = op.execute(&ctx);
|
||||
#if 0
|
||||
//visual check
|
||||
rgbs.printBuffer("rgbs ");
|
||||
actual.printBuffer("HSV ");
|
||||
expected.printBuffer("exp");
|
||||
#endif
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_rgb_to_hsv_6) {
|
||||
/*
|
||||
|
||||
*/
|
||||
auto rgbs = NDArrayFactory::create<float>('c', { 3,8 },
|
||||
{ 130.f, 117.f, 181.f, 49.f, 131.f, 86.f, 101.f, 191.f, 61.f, 16.f, 223.f, 195.f, 153.f,
|
||||
21.f, 14.f, 98.f, 239.f, 168.f, 0.f, 195.f, 78.f, 209.f, 107.f, 210.f });
|
||||
|
||||
auto expected = NDArrayFactory::create<float>('c', { 3 },
|
||||
{ 263.25842697f, 0.74476987f, 0.9372549f });
|
||||
|
||||
//get subarray
|
||||
std::unique_ptr<NDArray> subArrRgbs(rgbs.subarray({ NDIndex::all(), NDIndex::point(0) }));
|
||||
subArrRgbs->reshapei({ 3 });
|
||||
#if 0
|
||||
//[RANK][SHAPE][STRIDES][OPTIONS][EWS][ORDER]
|
||||
subArrRgbs->printShapeInfo("subArrRgbs");
|
||||
#endif
|
||||
auto actual = NDArrayFactory::create<float>('c', { 3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, subArrRgbs.get());
|
||||
ctx.setOutputArray(0, &actual);
|
||||
ctx.setIArguments({ 0 });
|
||||
nd4j::ops::rgb_to_hsv op;
|
||||
auto status = op.execute(&ctx);
|
||||
#if 0
|
||||
//visual check
|
||||
subArrRgbs->printBuffer("subArrRgbs ");
|
||||
actual.printBuffer("HSV ");
|
||||
expected.printBuffer("exp");
|
||||
#endif
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_hsv_to_rgb_1) {
|
||||
/*
|
||||
using the same numbers of rgb_to_hsv_1 test
|
||||
*/
|
||||
auto expected = NDArrayFactory::create<float>('c', { 5,4,3 },
|
||||
{ 213.f, 220.f, 164.f, 121.f, 180.f, 180.f, 18.f, 245.f, 75.f, 235.f, 76.f, 74.f, 168.f,
|
||||
50.f, 233.f, 191.f, 132.f, 100.f, 207.f, 37.f, 245.f, 77.f, 250.f, 182.f, 111.f, 52.f,
|
||||
59.f, 193.f, 147.f, 137.f, 168.f, 103.f, 121.f, 48.f, 191.f, 187.f, 53.f, 82.f, 239.f,
|
||||
156.f, 37.f, 118.f, 244.f, 90.f, 7.f, 221.f, 98.f, 243.f, 12.f, 209.f, 192.f, 2.f,
|
||||
115.f, 205.f, 79.f, 247.f, 32.f, 70.f, 152.f, 180.f }
|
||||
);
|
||||
auto hsvs = NDArrayFactory::create<float>('c', { 5,4,3 },
|
||||
{
|
||||
6.75000000e+01f, 2.54545455e-01f, 8.62745098e-01f, 1.80000000e+02f,
|
||||
3.27777778e-01f, 7.05882353e-01f, 1.35066079e+02f, 9.26530612e-01f,
|
||||
9.60784314e-01f, 7.45341615e-01f, 6.85106383e-01f, 9.21568627e-01f,
|
||||
2.78688525e+02f, 7.85407725e-01f, 9.13725490e-01f, 2.10989011e+01f,
|
||||
4.76439791e-01f, 7.49019608e-01f, 2.89038462e+02f, 8.48979592e-01f,
|
||||
9.60784314e-01f, 1.56416185e+02f, 6.92000000e-01f, 9.80392157e-01f,
|
||||
3.52881356e+02f, 5.31531532e-01f, 4.35294118e-01f, 1.07142857e+01f,
|
||||
2.90155440e-01f, 7.56862745e-01f, 3.43384615e+02f, 3.86904762e-01f,
|
||||
6.58823529e-01f, 1.78321678e+02f, 7.48691099e-01f, 7.49019608e-01f,
|
||||
2.30645161e+02f, 7.78242678e-01f, 9.37254902e-01f, 3.19159664e+02f,
|
||||
7.62820513e-01f, 6.11764706e-01f, 2.10126582e+01f, 9.71311475e-01f,
|
||||
9.56862745e-01f, 2.90896552e+02f, 5.96707819e-01f, 9.52941176e-01f,
|
||||
1.74822335e+02f, 9.42583732e-01f, 8.19607843e-01f, 2.06600985e+02f,
|
||||
9.90243902e-01f, 8.03921569e-01f, 1.06883721e+02f, 8.70445344e-01f,
|
||||
9.68627451e-01f, 1.95272727e+02f, 6.11111111e-01f, 7.05882353e-01f
|
||||
});
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 5,4,3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &hsvs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
|
||||
nd4j::ops::hsv_to_rgb op;
|
||||
auto status = op.execute(&ctx);
|
||||
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_hsv_to_rgb_2) {
|
||||
/*
|
||||
using the same numbers of hsv_to_rgb_2
|
||||
*/
|
||||
auto expected = NDArrayFactory::create<float>('c', { 5,3,4 },
|
||||
{ 213.f, 121.f, 18.f, 235.f, 220.f, 180.f, 245.f, 76.f, 164.f, 180.f, 75.f, 74.f, 168.f,
|
||||
191.f, 207.f, 77.f, 50.f, 132.f, 37.f, 250.f, 233.f, 100.f, 245.f, 182.f, 111.f, 193.f,
|
||||
168.f, 48.f, 52.f, 147.f, 103.f, 191.f, 59.f, 137.f, 121.f, 187.f, 53.f, 156.f, 244.f,
|
||||
221.f, 82.f, 37.f, 90.f, 98.f, 239.f, 118.f, 7.f, 243.f, 12.f, 2.f, 79.f, 70.f,
|
||||
209.f, 115.f, 247.f, 152.f, 192.f, 205.f, 32.f, 180.f }
|
||||
);
|
||||
auto hsvs = NDArrayFactory::create<float>('c', { 5,3,4 },
|
||||
{
|
||||
6.75000000e+01f, 1.80000000e+02f, 1.35066079e+02f, 7.45341615e-01f,
|
||||
2.54545455e-01f, 3.27777778e-01f, 9.26530612e-01f, 6.85106383e-01f,
|
||||
8.62745098e-01f, 7.05882353e-01f, 9.60784314e-01f, 9.21568627e-01f,
|
||||
2.78688525e+02f, 2.10989011e+01f, 2.89038462e+02f, 1.56416185e+02f,
|
||||
7.85407725e-01f, 4.76439791e-01f, 8.48979592e-01f, 6.92000000e-01f,
|
||||
9.13725490e-01f, 7.49019608e-01f, 9.60784314e-01f, 9.80392157e-01f,
|
||||
3.52881356e+02f, 1.07142857e+01f, 3.43384615e+02f, 1.78321678e+02f,
|
||||
5.31531532e-01f, 2.90155440e-01f, 3.86904762e-01f, 7.48691099e-01f,
|
||||
4.35294118e-01f, 7.56862745e-01f, 6.58823529e-01f, 7.49019608e-01f,
|
||||
2.30645161e+02f, 3.19159664e+02f, 2.10126582e+01f, 2.90896552e+02f,
|
||||
7.78242678e-01f, 7.62820513e-01f, 9.71311475e-01f, 5.96707819e-01f,
|
||||
9.37254902e-01f, 6.11764706e-01f, 9.56862745e-01f, 9.52941176e-01f,
|
||||
1.74822335e+02f, 2.06600985e+02f, 1.06883721e+02f, 1.95272727e+02f,
|
||||
9.42583732e-01f, 9.90243902e-01f, 8.70445344e-01f, 6.11111111e-01f,
|
||||
8.19607843e-01f, 8.03921569e-01f, 9.68627451e-01f, 7.05882353e-01f
|
||||
});
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 5,3,4 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &hsvs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
ctx.setIArguments({ 1 });
|
||||
nd4j::ops::hsv_to_rgb op;
|
||||
auto status = op.execute(&ctx);
|
||||
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_hsv_to_rgb_3) {
|
||||
/*
|
||||
2D
|
||||
*/
|
||||
auto expected = NDArrayFactory::create<float>('c', { 8,3 },
|
||||
{ 130.f, 61.f, 239.f, 117.f, 16.f, 168.f, 181.f, 223.f, 0.f, 49.f, 195.f, 195.f, 131.f,
|
||||
153.f, 78.f, 86.f, 21.f, 209.f, 101.f, 14.f, 107.f, 191.f, 98.f, 210.f });
|
||||
auto hsvs = NDArrayFactory::create<float>('c', { 8,3 },
|
||||
{ 263.25842697f, 0.74476987f, 0.9372549f, 279.86842105f,
|
||||
0.9047619f, 0.65882353f, 71.30044843f, 1.f,
|
||||
0.8745098f, 180.f, 0.74871795f, 0.76470588f,
|
||||
77.6f, 0.49019608f, 0.6f, 260.74468085f,
|
||||
0.89952153f, 0.81960784f, 296.12903226f, 0.86915888f,
|
||||
0.41960784f, 289.82142857f, 0.53333333f, 0.82352941f });
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 8,3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &hsvs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
|
||||
nd4j::ops::hsv_to_rgb op;
|
||||
auto status = op.execute(&ctx);
|
||||
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_hsv_to_rgb_4) {
|
||||
/*
|
||||
2D
|
||||
*/
|
||||
auto expected = NDArrayFactory::create<float>('c', { 3,8 },
|
||||
{ 130.f, 117.f, 181.f, 49.f, 131.f, 86.f, 101.f, 191.f, 61.f, 16.f, 223.f, 195.f, 153.f,
|
||||
21.f, 14.f, 98.f, 239.f, 168.f, 0.f, 195.f, 78.f, 209.f, 107.f, 210.f });
|
||||
auto hsvs = NDArrayFactory::create<float>('c', { 3,8 },
|
||||
{ 263.25842697f, 279.86842105f, 71.30044843f, 180.f,
|
||||
77.6f, 260.74468085f, 296.12903226f, 289.82142857f,
|
||||
0.74476987f, 0.9047619f, 1.f, 0.74871795f,
|
||||
0.49019608f, 0.89952153f, 0.86915888f, 0.53333333f,
|
||||
0.9372549f, 0.65882353f, 0.8745098f, 0.76470588f,
|
||||
0.6f, 0.81960784f, 0.41960784f, 0.82352941f });
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 3,8 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &hsvs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
ctx.setIArguments({ 0 });
|
||||
nd4j::ops::hsv_to_rgb op;
|
||||
auto status = op.execute(&ctx);
|
||||
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_hsv_to_rgb_5) {
|
||||
/*
|
||||
|
||||
*/
|
||||
auto expected = NDArrayFactory::create<float>('c', { 3 },
|
||||
{ 213.f, 220.f, 164.f });
|
||||
auto hsvs = NDArrayFactory::create<float>('c', { 3 },
|
||||
{ 6.75000000e+01f, 2.54545455e-01f, 8.62745098e-01f });
|
||||
|
||||
|
||||
auto actual = NDArrayFactory::create<float>('c', { 3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, &hsvs);
|
||||
ctx.setOutputArray(0, &actual);
|
||||
|
||||
nd4j::ops::hsv_to_rgb op;
|
||||
auto status = op.execute(&ctx);
|
||||
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DeclarableOpsTests16, test_hsv_to_rgb_6) {
|
||||
|
||||
auto expected = NDArrayFactory::create<double>('c', { 3 },
|
||||
{ 130.0, 61.0, 239.0 });
|
||||
auto hsvs = NDArrayFactory::create<double>('c', { 3,8 },
|
||||
{ 263.25842697, 279.86842105, 71.30044843, 180,
|
||||
77.6, 260.74468085, 296.12903226, 289.82142857,
|
||||
0.74476987, 0.9047619, 1., 0.74871795,
|
||||
0.49019608, 0.89952153, 0.86915888, 0.53333333,
|
||||
0.9372549, 0.65882353, 0.8745098, 0.76470588,
|
||||
0.6, 0.81960784, 0.41960784, 0.82352941
|
||||
});
|
||||
|
||||
//get subarray
|
||||
std::unique_ptr<NDArray> subArrHsvs(hsvs.subarray({ NDIndex::all(), NDIndex::point(0) }));
|
||||
subArrHsvs->reshapei({ 3 });
|
||||
#if 0
|
||||
//[RANK][SHAPE][STRIDES][OPTIONS][EWS][ORDER]
|
||||
subArrHsvs->printShapeInfo("subArrHsvs");
|
||||
#endif
|
||||
auto actual = NDArrayFactory::create<double>('c', { 3 });
|
||||
|
||||
Context ctx(1);
|
||||
ctx.setInputArray(0, subArrHsvs.get());
|
||||
ctx.setOutputArray(0, &actual);
|
||||
nd4j::ops::hsv_to_rgb op;
|
||||
auto status = op.execute(&ctx);
|
||||
#if 0
|
||||
//visual check
|
||||
subArrHsvs->printBuffer("subArrHsvs ");
|
||||
actual.printBuffer("rgb ");
|
||||
expected.printBuffer("exp");
|
||||
#endif
|
||||
ASSERT_EQ(ND4J_STATUS_OK, status);
|
||||
ASSERT_TRUE(expected.equalsTo(actual));
|
||||
|
||||
}
|
Loading…
Reference in New Issue