From 0421c0269e0511434284f4a3968b58929fed36c6 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Feb 2019 00:59:55 +0530 Subject: [PATCH 01/51] The core implementation. Ported from PR 94 on libgdf. --- .gitmodules | 3 + cpp/CMakeLists.txt | 12 +- cpp/include/cudf/functions.h | 143 ++++++++++++ cpp/include/cudf/types.h | 80 +++++++ cpp/src/binary/jit/code/code.h | 36 +++ cpp/src/binary/jit/code/gdf-data.cpp | 85 +++++++ cpp/src/binary/jit/code/kernel.cpp | 153 +++++++++++++ cpp/src/binary/jit/code/operation.cpp | 306 ++++++++++++++++++++++++++ cpp/src/binary/jit/code/traits.cpp | 237 ++++++++++++++++++++ cpp/src/binary/jit/core/binop.cpp | 237 ++++++++++++++++++++ cpp/src/binary/jit/core/launcher.cpp | 112 ++++++++++ cpp/src/binary/jit/core/launcher.h | 83 +++++++ cpp/src/binary/jit/util/operator.cpp | 43 ++++ cpp/src/binary/jit/util/operator.h | 48 ++++ cpp/src/binary/jit/util/type.cpp | 96 ++++++++ cpp/src/binary/jit/util/type.h | 35 +++ thirdparty/jitify | 1 + 17 files changed, 1709 insertions(+), 1 deletion(-) create mode 100644 cpp/src/binary/jit/code/code.h create mode 100644 cpp/src/binary/jit/code/gdf-data.cpp create mode 100644 cpp/src/binary/jit/code/kernel.cpp create mode 100644 cpp/src/binary/jit/code/operation.cpp create mode 100644 cpp/src/binary/jit/code/traits.cpp create mode 100644 cpp/src/binary/jit/core/binop.cpp create mode 100644 cpp/src/binary/jit/core/launcher.cpp create mode 100644 cpp/src/binary/jit/core/launcher.h create mode 100644 cpp/src/binary/jit/util/operator.cpp create mode 100644 cpp/src/binary/jit/util/operator.h create mode 100644 cpp/src/binary/jit/util/type.cpp create mode 100644 cpp/src/binary/jit/util/type.h create mode 160000 thirdparty/jitify diff --git a/.gitmodules b/.gitmodules index 7a64546f4d78..36f7151aa93f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ path = thirdparty/rmm url = https://github.com/rapidsai/rmm.git branch = branch-0.6 +[submodule "thirdparty/jitify"] + path = thirdparty/jitify + url = https://github.com/NVIDIA/jitify.git diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 9103e309652d..3145b6289bff 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -141,6 +141,7 @@ include_directories("${ARROW_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/include" "${CMAKE_SOURCE_DIR}/src" "${CMAKE_SOURCE_DIR}/thirdparty/cub" + "${CMAKE_SOURCE_DIR}/thirdparty/jitify" "${CMAKE_SOURCE_DIR}/thirdparty/moderngpu/src" "${CMAKE_SOURCE_DIR}/thirdparty/rmm/include" "${ZLIB_INCLUDE_DIRS}") @@ -188,6 +189,14 @@ add_library(cudf SHARED src/groupby/groupby.cu src/groupby/new_groupby.cu src/binary/binary_ops.cu + src/binary/jit/code/gdf-data.cpp + src/binary/jit/code/kernel.cpp + src/binary/jit/code/operation.cpp + src/binary/jit/code/traits.cpp + src/binary/jit/core/binop.cpp + src/binary/jit/core/launcher.cpp + src/binary/jit/util/operator.cpp + src/binary/jit/util/type.cpp src/bitmask/bitmask_ops.cu src/bitmask/valid_ops.cu src/compaction/stream_compaction_ops.cu @@ -232,7 +241,8 @@ endif(HT_LEGACY_ALLOCATOR) ################################################################################################### # - link libraries -------------------------------------------------------------------------------- -target_link_libraries(cudf rmm "${ARROW_LIB}" ${ZLIB_LIBRARIES} NVStrings) +# TODO: better nvrtc linking with optional variables +target_link_libraries(cudf rmm "${ARROW_LIB}" ${ZLIB_LIBRARIES} NVStrings nvrtc) ################################################################################################### # - python cffi bindings -------------------------------------------------------------------------- diff --git a/cpp/include/cudf/functions.h b/cpp/include/cudf/functions.h index ed7a72c237a6..ff48928df83a 100644 --- a/cpp/include/cudf/functions.h +++ b/cpp/include/cudf/functions.h @@ -592,6 +592,149 @@ gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output); /* binary operators */ +/** + * @brief Binary operation function between gdf_scalar and gdf_column structs. + * + * The function performs the binary operation of a gdf_scalar operand and a + * gdf_column operand. + * + * The valid field in the gdf_column output will be 1 (by bit) when the two + * operands (vax and vay) are not null. Otherwise, it will be 0 (by bit). + * + * It is required to set in an appropriate manner the fields in the gdf_scalar and + * gdf_column structs due to that the binary operation will not be performed. + * + * @param out (gdf_column) Output of the operation. + * @param vax (gdf_scalar) First operand of the operation. + * @param vay (gdf_column) Second operand of the operation. + * @param ope (enum) The binary operator that is going to be used in the operation. + * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate + * error code + */ +gdf_error gdf_binary_operation_v_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope); + +/** + * @brief Binary operation function between gdf_column and gdf_scalar structs. + * + * The function performs the binary operation of a gdf_column operand and a + * gdf_scalar operand. + * + * The valid field in the gdf_column output will be 1 (by bit) when the two + * operands (vax and vay) are not null. Otherwise, it will be 0 (by bit). + * + * It is required to set in an appropriate manner the fields in the gdf_scalar and + * gdf_column structs due to that the binary operation will not be performed. + * + * @param out (gdf_column) Output of the operation. + * @param vax (gdf_column) First operand of the operation. + * @param vay (gdf_scalar) Second operand of the operation. + * @param ope (enum) The binary operator that is going to be used in the operation. + * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate + * error code + */ +gdf_error gdf_binary_operation_v_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope); + +/** + * @brief Binary operation function between two gdf_column structs. + * + * The function performs the binary operation of two gdf_column operands. + * + * The valid field in the gdf_column output will be 1 (by bit) when the two + * operands (vax and vay) are not null. Otherwise, it will be 0 (by bit). + * + * It is required to set in an appropriate manner the fields in the gdf_column + * struct due to that the binary operation will not be performed. + * + * @param out (gdf_column) Output of the operation. + * @param vax (gdf_column) First operand of the operation. + * @param vay (gdf_column) Second operand of the operation. + * @param ope (enum) The binary operator that is going to be used in the operation. + * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate + * error code + */ +gdf_error gdf_binary_operation_v_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope); + +/** + * @brief Binary operation function between gdf_scalar and gdf_column structs. + * + * The function performs the binary operation of a gdf_scalar operand and a + * gdf_column operand. A default scalar operand is used to replace an operand + * in the binary operation when such operand is null. + * + * Whether any operand (vax or vay) is null, then it will be replaced with the + * default scalar operand value (def). In case both operands (vax and vay) are + * null, each of them will be replaced with the default scalar operand value. + * + * The valid field in the gdf_column output will be 1 (by bit) when two or three + * operands (vax, vay and def) are not null. Otherwise, it will be 0 (by bit). + * + * It is required to set in an appropriate manner the fields in the gdf_scalar and + * gdf_column structs due to that the binary operation will not be performed. + * + * @param out (gdf_column) Output of the operation. + * @param vax (gdf_column) First operand of the operation. + * @param vay (gdf_scalar) Second operand of the operation - gdf_scalar. + * @param def (gdf_scalar) Default operand used to replace a null operand. + * @param ope (enum) The binary operator that is going to be used in the operation. + * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate + * error code + */ +gdf_error gdf_binary_operation_v_s_v_d(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope); + +/** + * @brief Binary operation function between gdf_column and gdf_scalar structs. + * + * The function performs the binary operation of a gdf_column operand and a + * gdf_scalar operand. A default scalar operand is used to replace an operand + * in the binary operation when such operand is null. + * + * Whether any operand (vax or vay) is null, then it will be replaced with the + * default scalar operand value (def). In case both operands (vax and vay) are + * null, each of them will be replaced with the default scalar operand value. + * + * The valid field in the gdf_column output will be 1 (by bit) when two or three + * operands (vax, vay and def) are not null. Otherwise, it will be 0 (by bit). + * + * It is required to set in an appropriate manner the fields in the gdf_scalar and + * gdf_column structs due to that the binary operation will not be performed. + * + * @param out (gdf_column) Output of the operation. + * @param vax (gdf_column) First operand of the operation. + * @param vay (gdf_scalar) Second operand of the operation - gdf_scalar. + * @param def (gdf_scalar) Default operand used to replace a null operand. + * @param ope (enum) The binary operator that is going to be used in the operation. + * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate + * error code + */ +gdf_error gdf_binary_operation_v_v_s_d(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def, gdf_binary_operator ope); + +/** + * @brief Binary operation function between two gdf_column structs. + * + * The function performs the binary operation of two gdf_column operands. A default + * scalar operand is used to replace an operand in the binary operation when such + * operand is null. + * + * Whether any gdf_column (vax or vay) is null, then it will be replaced with the + * default scalar operand value (def). In case both operands (vax and vay) are null, + * each of them will be replaced with the default scalar operand value. + * + * The valid field in the gdf_column output will be 1 (by bit) when two or three + * operands (vax, vay and def) are not null. Otherwise, it will be 0 (by bit). + * + * It is required to set in an appropriate manner the fields in the gdf_scalar and + * gdf_column structs due to that the binary operation will not be performed. + * + * @param out (gdf_column) Output of the operation. + * @param vax (gdf_column) First operand of the operation. + * @param vay (gdf_column) Second operand of the operation. + * @param def (gdf_scalar) Default operand used to replace a null operand. + * @param ope (enum) The binary operator that is going to be used in the operation. + * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate + * error code. + */ +gdf_error gdf_binary_operation_v_v_v_d(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope); + /* arith */ gdf_error gdf_add_generic(gdf_column *lhs, gdf_column *rhs, gdf_column *output); diff --git a/cpp/include/cudf/types.h b/cpp/include/cudf/types.h index 5874a7fc2ca1..d498ae73bedb 100644 --- a/cpp/include/cudf/types.h +++ b/cpp/include/cudf/types.h @@ -27,10 +27,37 @@ typedef enum { GDF_TIMESTAMP, /**< Exact timestamp encoded with int64 since UNIX epoch (Default unit millisecond) */ GDF_CATEGORY, GDF_STRING, + GDF_UINT8, + GDF_UINT16, + GDF_UINT32, + GDF_UINT64, N_GDF_TYPES, /* additional types should go BEFORE N_GDF_TYPES */ } gdf_dtype; +/** + * @union gdf_data + * @brief Union used for scalar type. + * It stores a unique value for scalar type. + * It has a direct relationship with the gdf_dtype. + */ +typedef union { + int8_t si08; /**< GDF_INT8 */ + int16_t si16; /**< GDF_INT16 */ + int32_t si32; /**< GDF_INT32 */ + int64_t si64; /**< GDF_INT64 */ + uint8_t ui08; /**< GDF_UINT8 */ + uint16_t ui16; /**< GDF_UINT16 */ + uint32_t ui32; /**< GDF_UINT32 */ + uint64_t ui64; /**< GDF_UINT64 */ + float fp32; /**< GDF_FLOAT32 */ + double fp64; /**< GDF_FLOAT64 */ + int32_t dt32; /**< GDF_DATE32 */ + int64_t dt64; /**< GDF_DATE64 */ + int64_t tmst; /**< GDF_TIMESTAMP */ +} gdf_data; + + /* --------------------------------------------------------------------------*/ /** * @Synopsis These are all possible gdf error codes that can be returned from @@ -85,6 +112,24 @@ typedef struct { // here we can also hold info for decimal datatype or any other datatype that requires additional information } gdf_dtype_extra_info; + +/** + * @struct gdf_scalar + * @brief literal or variable + * + * The struct is used as a literal or a variable in the libgdf library. + * + * @var data A union that represents the value. + * @var dtype An enum that represents the type of the value. + * @var is_valid A boolean that represents whether the scalar is null. + */ +typedef struct { + gdf_data data; + gdf_dtype dtype; + bool is_valid; +} gdf_scalar; + + typedef struct gdf_column_{ void *data; /**< Pointer to the columns data */ gdf_valid_type *valid; /**< Pointer to the columns validity bit mask where the 'i'th bit indicates if the 'i'th row is NULL */ @@ -156,6 +201,41 @@ typedef enum { GDF_NUM_COLORS, /** Add new colors above this line */ } gdf_color; + +/** + * @enum gdf_binary_operator + * It contains the different operations that can be performed in the binary operations. + * The enumeration is used in the following functions: + * - gdf_binary_operation_v_s_v + * - gdf_binary_operation_v_v_s + * - gdf_binary_operation_v_v_v + * - gdf_binary_operation_v_s_v_d + * - gdf_binary_operation_v_v_s_d + * - gdf_binary_operation_v_v_v_d + */ +typedef enum { + GDF_ADD, + GDF_SUB, + GDF_MUL, + GDF_DIV, + GDF_TRUE_DIV, + GDF_FLOOR_DIV, + GDF_MOD, + GDF_POW, + GDF_EQUAL, + GDF_NOT_EQUAL, + GDF_LESS, + GDF_GREATER, + GDF_LESS_EQUAL, + GDF_GREATER_EQUAL, + //GDF_COMBINE, + //GDF_COMBINE_FIRST, + //GDF_ROUND, + //GDF_PRODUCT, + //GDF_DOT +} gdf_binary_operator; + + /* --------------------------------------------------------------------------*/ /** * @Synopsis This struct holds various information about how an operation should be diff --git a/cpp/src/binary/jit/code/code.h b/cpp/src/binary/jit/code/code.h new file mode 100644 index 000000000000..e714bae027eb --- /dev/null +++ b/cpp/src/binary/jit/code/code.h @@ -0,0 +1,36 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_BINARY_OPERATION_JIT_CODE_CODE_H +#define GDF_BINARY_OPERATION_JIT_CODE_CODE_H + +namespace gdf { +namespace binops { +namespace jit { +namespace code { + + extern const char* kernel; + extern const char* traits; + extern const char* operation; + extern const char* gdf_data; + +} +} +} +} + +#endif diff --git a/cpp/src/binary/jit/code/gdf-data.cpp b/cpp/src/binary/jit/code/gdf-data.cpp new file mode 100644 index 000000000000..bdc65a225180 --- /dev/null +++ b/cpp/src/binary/jit/code/gdf-data.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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. + */ + +namespace gdf { +namespace binops { +namespace jit { +namespace code { + +const char* gdf_data = +R"***( +#pragma once + + union gdf_data { + int8_t si08; + int16_t si16; + int32_t si32; + int64_t si64; + uint8_t ui08; + uint16_t ui16; + uint32_t ui32; + uint64_t ui64; + float fp32; + double fp64; + + operator int8_t() const { + return si08; + } + + operator int16_t() const { + return si16; + } + + operator int32_t() const { + return si32; + } + + operator int64_t() const { + return si64; + } + + operator uint8_t() const { + return ui08; + } + + operator uint16_t() const { + return ui16; + } + + operator uint32_t() const { + return ui32; + } + + operator uint64_t() const { + return ui64; + } + + operator float() const { + return fp32; + } + + operator double() const { + return fp64; + } + }; + +)***"; + +} // namespace code +} // namespace jit +} // namespace binops +} // namespace gdf diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp new file mode 100644 index 000000000000..72c44b8ac259 --- /dev/null +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -0,0 +1,153 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * Copyright 2018 Rommel Quintanilla + * + * 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. + */ + +namespace gdf { +namespace binops { +namespace jit { +namespace code { + +const char* kernel = +R"***( + #include + #include "traits.h" + #include "operation.h" + #include "gdf_data.h" + + template + __global__ + void kernel_v_s(int size, + TypeOut* out_data, TypeVax* vax_data, gdf_data vay_data, + uint32_t* out_valid, uint32_t* vax_valid, uint32_t vay_valid) { + int tid = threadIdx.x; + int blkid = blockIdx.x; + int blksz = blockDim.x; + int gridsz = gridDim.x; + + int start = tid + blkid * blksz; + int step = blksz * gridsz; + + for (int i=start; i(vax_data[i], (TypeVay)vay_data); + + if ((i % warpSize) == 0) { + int index = i / warpSize; + out_valid[index] = vax_valid[index] & vay_valid; + } + } + } + + template + __global__ + void kernel_v_v(int size, + TypeOut* out_data, TypeVax* vax_data, TypeVay* vay_data, + uint32_t* out_valid, uint32_t* vax_valid, uint32_t* vay_valid) { + int tid = threadIdx.x; + int blkid = blockIdx.x; + int blksz = blockDim.x; + int gridsz = gridDim.x; + + int start = tid + blkid * blksz; + int step = blksz * gridsz; + + for (int i=start; i(vax_data[i], vay_data[i]); + + if ((i % warpSize) == 0) { + int index = i / warpSize; + out_valid[index] = vax_valid[index] & vay_valid[index]; + } + } + } + + template + __global__ + void kernel_v_s_d(int size, + TypeOut* out_data, TypeVax* vax_data, gdf_data vay_data, gdf_data def_data, + uint32_t* out_valid, uint32_t* vax_valid, uint32_t vay_valid, uint32_t def_valid) { + int tid = threadIdx.x; + int blkid = blockIdx.x; + int blksz = blockDim.x; + int gridsz = gridDim.x; + + int start = tid + blkid * blksz; + int step = blksz * gridsz; + + for (int i=start; i> position) & 1; + TypeVax vax_data_aux = ((TypeVax)sel_vax * vax_data[i]) + + ((TypeVax)(sel_vax ^ 1) * (TypeVax)((TypeVal)def_data)); + + TypeVay vay_data_aux = ((TypeVay)(vay_valid & 1) * (TypeVay)vay_data) + + ((TypeVay)(vay_valid + 1) * (TypeVay)((TypeVal)def_data)); + + out_data[i] = TypeOpe::template operate(vax_data_aux, vay_data_aux); + + if ((i % warpSize) == 0) { + out_valid[index] = (vax_valid[index] & vay_valid) | + (vax_valid[index] & def_valid) | + (vay_valid & def_valid); + } + } + } + + template + __global__ + void kernel_v_v_d(int size, + TypeOut* out_data, TypeVax* vax_data, TypeVay* vay_data, gdf_data def_data, + uint32_t* out_valid, uint32_t* vax_valid, uint32_t* vay_valid, uint32_t def_valid) { + int tid = threadIdx.x; + int blkid = blockIdx.x; + int blksz = blockDim.x; + int gridsz = gridDim.x; + + int start = tid + blkid * blksz; + int step = blksz * gridsz; + + for (int i=start; i> position) & 1; + TypeVax vax_data_aux = ((TypeVax)sel_vax * vax_data[i]) + + ((TypeVax)(sel_vax ^ 1) * (TypeVax)((TypeVal)def_data)); + + uint32_t sel_vay = (is_vay_valid >> position) & 1; + TypeVay vay_data_aux = ((TypeVay)sel_vay * vay_data[i]) + + ((TypeVay)(sel_vay ^ 1) * (TypeVay)((TypeVal)def_data)); + + out_data[i] = TypeOpe::template operate(vax_data_aux, vay_data_aux); + + if ((i % warpSize) == 0) { + out_valid[index] = (vax_valid[index] & vay_valid[index]) | + (vax_valid[index] & def_valid) | + (vay_valid[index] & def_valid); + } + } + } +)***"; + +} // namespace code +} // namespace jit +} // namespace binops +} // namespace gdf diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp new file mode 100644 index 000000000000..781226395fb1 --- /dev/null +++ b/cpp/src/binary/jit/code/operation.cpp @@ -0,0 +1,306 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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. + */ + +namespace gdf { +namespace binops { +namespace jit { +namespace code { + +const char* operation = +R"***( +#pragma once + + struct Add { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x + (Common)y); + } + }; + + using RAdd = Add; + + struct Sub { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x - (Common)y); + } + }; + + struct RSub { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)y - (Common)x); + } + }; + + struct Mul { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x * (Common)y); + } + }; + + using RMul = Mul; + + struct Div { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x / (Common)y); + } + }; + + struct RDiv { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)y / (Common)x); + } + }; + + struct TrueDiv { + template + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)((double)x / (double)y); + } + }; + + struct RTrueDiv { + template + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)((double)y / (double)x); + } + }; + + struct FloorDiv { + template + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)floor((double)x / (double)y); + } + }; + + struct RFloorDiv { + template + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)floor((double)y / (double)x); + } + }; + + struct Mod { + template , + enableIf<(isIntegral)>* = nullptr> + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)((Common)x % (Common)y); + } + + template , + enableIf<(isFloat)>* = nullptr> + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)fmodf((Common)x, (Common)y); + } + + template , + enableIf<(isDouble)>* = nullptr> + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)fmod((Common)x, (Common)y); + } + }; + + struct RMod { + template , + enableIf<(isIntegral)>* = nullptr> + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)((Common)y % (Common)x); + } + + template , + enableIf<(isFloat)>* = nullptr> + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)fmodf((Common)y, (Common)x); + } + + template , + enableIf<(isDouble)>* = nullptr> + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)fmod((Common)y, (Common)x); + } + }; + + struct Pow { + template + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)pow((double)x, (double)y); + } + }; + + struct RPow { + template + static TypeOut operate(TypeVax x, TypeVay y) { + return (TypeOut)pow((double)y, (double)x); + } + }; + + struct Equal { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x == (Common)y); + } + }; + + using REqual = Equal; + + struct NotEqual { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x != (Common)y); + } + }; + + using RNotEqual = NotEqual; + + struct Less { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x < (Common)y); + } + }; + + struct RLess { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)y < (Common)x); + } + }; + + struct Greater { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x > (Common)y); + } + }; + + struct RGreater { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)y > (Common)x); + } + }; + + struct LessEqual { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x <= (Common)y); + } + }; + + struct RLessEqual { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)y <= (Common)x); + } + }; + + struct GreaterEqual { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)x >= (Common)y); + } + }; + + struct RGreaterEqual { + template + static TypeOut operate(TypeVax x, TypeVay y) { + using Common = CommonNumber; + return (TypeOut)((Common)y >= (Common)x); + } + }; +)***"; + +/* + * The following code could be used to detect overflow or underflow + * using 'Bit Hacks' in the operations, that's why the operation is + * divided into signed, unsigned and double functions. It's required + * to create a new field on gdf_column for this feature. + * + * struct Add { + * template , + * enableIf<(isIntegralSigned)>* = nullptr> + * __device__ + * TypeOut operate(TypeVax x, TypeVay y) { + * return (TypeOut)((Common)x + (Common)y); + * } + * + * template , + * enableIf<(isIntegralUnsigned)>* = nullptr> + * __device__ + * TypeOut operate(TypeVax x, TypeVay y) { + * return (TypeOut)((Common)x + (Common)y); + * } + * + * template , + * enableIf<(isFloatingPoint)>* = nullptr> + * __device__ + * TypeOut operate(TypeVax x, TypeVay y) { + * return (TypeOut)((Common)x + (Common)y); + * } + * }; + */ + +} // namespace code +} // namespace jit +} // namespace binops +} // namespace gdf diff --git a/cpp/src/binary/jit/code/traits.cpp b/cpp/src/binary/jit/code/traits.cpp new file mode 100644 index 000000000000..9e01d40f480d --- /dev/null +++ b/cpp/src/binary/jit/code/traits.cpp @@ -0,0 +1,237 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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. + */ + +namespace gdf { +namespace binops { +namespace jit { +namespace code { + +const char* traits = +R"***( +#pragma once + + struct IntegralSigned {}; + + struct IntegralUnsigned {}; + + + template + constexpr bool isIntegral = false; + + template <> + constexpr bool isIntegral = true; + + template <> + constexpr bool isIntegral = true; + + template <> + constexpr bool isIntegral = true; + + template <> + constexpr bool isIntegral = true; + + template <> + constexpr bool isIntegral = true; + + template <> + constexpr bool isIntegral = true; + + template <> + constexpr bool isIntegral = true; + + template <> + constexpr bool isIntegral = true; + + + + template + constexpr bool isFloatingPoint = false; + + template <> + constexpr bool isFloatingPoint = true; + + template <> + constexpr bool isFloatingPoint = true; + + + + template + constexpr bool isIntegralSigned = false; + + template <> + constexpr bool isIntegralSigned = true; + + template <> + constexpr bool isIntegralSigned = true; + + template <> + constexpr bool isIntegralSigned = true; + + template <> + constexpr bool isIntegralSigned = true; + + + + template + constexpr bool isIntegralUnsigned = false; + + template <> + constexpr bool isIntegralUnsigned = true; + + template <> + constexpr bool isIntegralUnsigned = true; + + template <> + constexpr bool isIntegralUnsigned = true; + + template <> + constexpr bool isIntegralUnsigned = true; + + + template + constexpr bool isFloat = false; + + template <> + constexpr bool isFloat = true; + + + template + constexpr bool isDouble = false; + + template <> + constexpr bool isDouble = true; + + + template + constexpr int MaxSize = ((sizeof(X) < sizeof(Y)) ? sizeof(Y) : sizeof(X)); + + template + struct HelperIntegralMap; + + template <> + struct HelperIntegralMap<1, IntegralSigned> { + using Type = int8_t; + }; + + template <> + struct HelperIntegralMap<2, IntegralSigned> { + using Type = int16_t; + }; + + template <> + struct HelperIntegralMap<4, IntegralSigned> { + using Type = int32_t; + }; + + template <> + struct HelperIntegralMap<8, IntegralSigned> { + using Type = int64_t; + }; + + template <> + struct HelperIntegralMap<1, IntegralUnsigned> { + using Type = uint8_t; + }; + + template <> + struct HelperIntegralMap<2, IntegralUnsigned> { + using Type = uint16_t; + }; + + template <> + struct HelperIntegralMap<4, IntegralUnsigned> { + using Type = uint32_t; + }; + + template <> + struct HelperIntegralMap<8, IntegralUnsigned> { + using Type = uint64_t; + }; + + template + using IntegralMap = typename HelperIntegralMap::Type; + + + + template + struct helperIf; + + template + struct helperIf { + using type = T; + }; + + template + struct helperIf { + using type = F; + }; + + template + using If = typename helperIf::type; + + + + template + struct helperEnableIf + {}; + + template + struct helperEnableIf { + using type = T; + }; + + template + using enableIf = typename helperEnableIf::type; + + + + template + struct HelperCommonNumber {}; + + template + struct HelperCommonNumber || isFloatingPoint)>> { + using Type = If<(sizeof(Vax) == 8 || sizeof(Vay) == 8), double, float>; + }; + + template + struct HelperCommonNumber && isIntegralSigned)>> { + using Type = IntegralMap<(MaxSize), IntegralSigned>; + }; + + template + struct HelperCommonNumber && isIntegralUnsigned)>> { + using Type = IntegralMap<(MaxSize), IntegralSigned>; + }; + + template + struct HelperCommonNumber && isIntegralSigned)>> { + using Type = IntegralMap<(MaxSize), IntegralSigned>; + }; + + template + struct HelperCommonNumber && isIntegralUnsigned)>> { + using Type = IntegralMap<(MaxSize), IntegralUnsigned>; + }; + + template + using CommonNumber = typename HelperCommonNumber::Type; +)***"; + +} // namespace code +} // namespace jit +} // namespace binops +} // namespace gdf diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp new file mode 100644 index 000000000000..da23acd18fd6 --- /dev/null +++ b/cpp/src/binary/jit/core/binop.cpp @@ -0,0 +1,237 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "binary/jit/core/launcher.h" +#include "binary/jit/util/operator.h" +#include "cudf.h" + +namespace gdf { +namespace binops { +namespace jit { + + struct Option { + Option(bool state, gdf_error value) + : is_correct{state}, gdf_error_value{value} + { } + + operator bool() { + return is_correct; + } + + gdf_error get_gdf_error() { + return gdf_error_value; + } + + private: + bool is_correct; + gdf_error gdf_error_value; + }; + + Option verify_scalar(gdf_scalar* scalar) { + if (scalar == nullptr) { + return Option(false, GDF_DATASET_EMPTY); + } + if ((scalar->dtype <= GDF_invalid) || (N_GDF_TYPES <= scalar->dtype)) { + return Option(false, GDF_UNSUPPORTED_DTYPE); + } + return Option(true, GDF_SUCCESS); + } + + Option verify_column(gdf_column* vector) { + if (vector == nullptr) { + return Option(false, GDF_DATASET_EMPTY); + } + if (vector->size == 0) { + return Option(false, GDF_SUCCESS); + } + if (vector->data == nullptr) { + return Option(false, GDF_DATASET_EMPTY); + } + if ((vector->dtype <= GDF_invalid) || (N_GDF_TYPES <= vector->dtype)) { + return Option(false, GDF_UNSUPPORTED_DTYPE); + } + return Option(true, GDF_SUCCESS); + } + + Option verify_column(gdf_column* out, gdf_column* vax) { + auto result = verify_column(out); + if (!result) { + return result; + } + result = verify_column(vax); + if (!result) { + return result; + } + if (out->size < vax->size) { + return Option(false, GDF_COLUMN_SIZE_MISMATCH); + } + return Option(true, GDF_SUCCESS); + } + + Option verify_column(gdf_column* out, gdf_column* vax, gdf_column* vay) { + auto result = verify_column(out); + if (!result) { + return result; + } + result = verify_column(vax); + if (!result) { + return result; + } + result = verify_column(vay); + if (!result) { + return result; + } + if ((out->size < vax->size) || (out->size < vay->size) || (vay->size != vax->size)) { + return Option(false, GDF_COLUMN_SIZE_MISMATCH); + } + return Option(true, GDF_SUCCESS); + } + + gdf_error binary_operation(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) { + auto option_scalar = verify_scalar(vax); + if (!option_scalar) { + return option_scalar.get_gdf_error(); + } + auto option_column = verify_column(out, vay); + if (!option_column) { + return option_column.get_gdf_error(); + } + + Launcher::launch().kernel("kernel_v_s") + .instantiate(ope, Operator::Type::Reverse, out, vay, vax) + .launch(out, vay, vax); + + return GDF_SUCCESS; + } + + gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) { + auto option_scalar = verify_scalar(vay); + if (!option_scalar) { + return option_scalar.get_gdf_error(); + } + auto option_column = verify_column(out, vax); + if (!option_column) { + return option_column.get_gdf_error(); + } + + Launcher::launch().kernel("kernel_v_s") + .instantiate(ope, Operator::Type::Direct, out, vax, vay) + .launch(out, vax, vay); + + return GDF_SUCCESS; + } + + gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) { + auto option_column = verify_column(out, vax, vay); + if (!option_column) { + return option_column.get_gdf_error(); + } + + Launcher::launch().kernel("kernel_v_v") + .instantiate(ope, Operator::Type::Direct, out, vax, vay) + .launch(out, vax, vay); + + return GDF_SUCCESS; + } + + gdf_error binary_operation(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { + auto option_column = verify_column(out, vay); + if (!option_column) { + return option_column.get_gdf_error(); + } + auto option_scalar_vax = verify_scalar(vax); + if (!option_scalar_vax) { + return option_scalar_vax.get_gdf_error(); + } + auto option_scalar_def = verify_scalar(def); + if (!option_scalar_def) { + return option_scalar_def.get_gdf_error(); + } + + Launcher::launch().kernel("kernel_v_s_d") + .instantiate(ope, Operator::Type::Reverse, out, vay, vax, def) + .launch(out, vay, vax, def); + + return GDF_SUCCESS; + } + + gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def, gdf_binary_operator ope) { + auto option_column = verify_column(out, vax); + if (!option_column) { + return option_column.get_gdf_error(); + } + auto option_scalar_vax = verify_scalar(vay); + if (!option_scalar_vax) { + return option_scalar_vax.get_gdf_error(); + } + auto option_scalar_def = verify_scalar(def); + if (!option_scalar_def) { + return option_scalar_def.get_gdf_error(); + } + + Launcher::launch().kernel("kernel_v_s_d") + .instantiate(ope, Operator::Type::Direct, out, vax, vay, def) + .launch(out, vax, vay, def); + + return GDF_SUCCESS; + } + + gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { + auto option_column = verify_column(out, vax, vay); + if (!option_column) { + return option_column.get_gdf_error(); + } + auto option_scalar = verify_scalar(def); + if (!option_scalar) { + return option_scalar.get_gdf_error(); + } + + Launcher::launch().kernel("kernel_v_v_d") + .instantiate(ope, Operator::Type::Direct, out, vax, vay, def) + .launch(out, vax, vay, def); + + return GDF_SUCCESS; + } + +} // namespace jit +} // namespace binops +} // namespace gdf + + +gdf_error gdf_binary_operation_v_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, vax, vay, ope); +} + +gdf_error gdf_binary_operation_v_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, vax, vay, ope); +} + +gdf_error gdf_binary_operation_v_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, vax, vay, ope); +} + +gdf_error gdf_binary_operation_v_s_v_d(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, vax, vay, def, ope); +} + +gdf_error gdf_binary_operation_v_v_s_d(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, vax, vay, def, ope); +} + +gdf_error gdf_binary_operation_v_v_v_d(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, vax, vay, def, ope); +} diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp new file mode 100644 index 000000000000..8a1811e454bc --- /dev/null +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -0,0 +1,112 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "binary/jit/core/launcher.h" +#include "binary/jit/code/code.h" +#include + +namespace gdf { +namespace binops { +namespace jit { + + static thread_local jitify::JitCache JitCache; + + std::istream* headersCode(std::string filename, std::iostream& stream) { + if (filename == "operation.h") { + stream << code::operation; + return &stream; + } + if (filename == "traits.h") { + stream << code::traits; + return &stream; + } + if (filename == "gdf_data.h") { + stream << code::gdf_data; + return &stream; + } + return nullptr; + } + + Launcher::Launcher() + : program {JitCache.program(code::kernel, headersName, compilerFlags, headersCode)} + { } + + Launcher::Launcher(Launcher&& launcher) + : program {std::move(launcher.program)} + { } + + Launcher& Launcher::kernel(std::string&& value) { + kernelName = value; + return *this; + } + + gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay) { + uint32_t vay_valid = (vay->is_valid ? UINT32_MAX : 0); + + program.kernel(kernelName.c_str()) + .instantiate(arguments) + .configure_1d_max_occupancy() + .launch(out->size, + out->data, vax->data, vay->data, + out->valid, vax->valid, vay_valid); + + return GDF_SUCCESS; + } + + gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_column* vay) { + program.kernel(kernelName.c_str()) + .instantiate(arguments) + .configure_1d_max_occupancy() + .launch(out->size, + out->data, vax->data, vay->data, + out->valid, vax->valid, vay->valid); + + return GDF_SUCCESS; + } + + gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def) + { + uint32_t vay_valid = (vay->is_valid ? UINT32_MAX : 0); + uint32_t def_valid = (def->is_valid ? UINT32_MAX : 0); + + program.kernel(kernelName) + .instantiate(arguments) + .configure_1d_max_occupancy() + .launch(out->size, + out->data, vax->data, vay->data, def->data, + out->valid, vax->valid, vay_valid, def_valid); + + return GDF_SUCCESS; + } + + gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def) + { + uint32_t def_valid = (def->is_valid ? UINT32_MAX : 0); + + program.kernel(kernelName) + .instantiate(arguments) + .configure_1d_max_occupancy() + .launch(out->size, + out->data, vax->data, vay->data, def->data, + out->valid, vax->valid, vay->valid, def_valid); + + return GDF_SUCCESS; + } + +} // namespace jit +} // namespace binops +} // namespace gdf diff --git a/cpp/src/binary/jit/core/launcher.h b/cpp/src/binary/jit/core/launcher.h new file mode 100644 index 000000000000..36774d39bbf9 --- /dev/null +++ b/cpp/src/binary/jit/core/launcher.h @@ -0,0 +1,83 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_BINARY_OPERATION_JIT_CORE_LAUNCHER_H +#define GDF_BINARY_OPERATION_JIT_CORE_LAUNCHER_H + +#include "binary/jit/util/type.h" +#include "binary/jit/util/operator.h" +#include + +namespace gdf { +namespace binops { +namespace jit { + + std::istream* headersCode(std::string filename, std::iostream& stream); + + class Launcher { + public: + static Launcher launch() { + return Launcher(); + } + + public: + Launcher(); + + Launcher(Launcher&&); + + public: + Launcher(const Launcher&) = delete; + + Launcher& operator=(Launcher&&) = delete; + + Launcher& operator=(const Launcher&) = delete; + + public: + Launcher& kernel(std::string&& value); + + template + Launcher& instantiate(gdf_binary_operator ope, Operator::Type type, Args&& ... args) { + Operator operatorSelector; + arguments.assign({getTypeName(args->dtype)..., operatorSelector.getOperatorName(ope, type)}); + return *this; + } + + gdf_error launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay); + + gdf_error launch(gdf_column* out, gdf_column* vax, gdf_column* vay); + + gdf_error launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def); + + gdf_error launch(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def); + + private: + std::vector compilerFlags { "-std=c++14" }; + std::vector headersName { "operation.h" , "traits.h" , "gdf_data.h" }; + + private: + jitify::Program program; + + private: + std::string kernelName; + std::vector arguments; + }; + +} // namespace jit +} // namespace binops +} // namespace gdf + +#endif diff --git a/cpp/src/binary/jit/util/operator.cpp b/cpp/src/binary/jit/util/operator.cpp new file mode 100644 index 000000000000..694b72e5c3ba --- /dev/null +++ b/cpp/src/binary/jit/util/operator.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "binary/jit/util/operator.h" +#include "binary/jit/util/type.h" +#include + +namespace gdf { +namespace binops { +namespace jit { + + Operator::Operator() + : buffer{'\0'} + { } + + char* Operator::getOperatorName(gdf_binary_operator ope, Operator::Type type) { + if (type == Operator::Type::Direct) { + buffer[0] = '\0'; + } else { + buffer[0] = 'R'; + buffer[1] = '\0'; + } + strcat(buffer, jit::getOperatorName(ope)); + return buffer; + } + +} // namespace jit +} // namespace binops +} // namespace gdf diff --git a/cpp/src/binary/jit/util/operator.h b/cpp/src/binary/jit/util/operator.h new file mode 100644 index 000000000000..96f1497af6f1 --- /dev/null +++ b/cpp/src/binary/jit/util/operator.h @@ -0,0 +1,48 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_BINARY_OPERATION_JIT_UTIL_OPERATOR_H +#define GDF_BINARY_OPERATION_JIT_UTIL_OPERATOR_H + +#include "cudf.h" + +namespace gdf { +namespace binops { +namespace jit { + + class Operator { + public: + enum class Type { + Direct, + Reverse + }; + + public: + Operator(); + + public: + char* getOperatorName(gdf_binary_operator ope, Operator::Type type); + + private: + char buffer[16]; + }; + +} // namespace jit +} // namespace binops +} // namespace gdf + +#endif diff --git a/cpp/src/binary/jit/util/type.cpp b/cpp/src/binary/jit/util/type.cpp new file mode 100644 index 000000000000..873baca3db86 --- /dev/null +++ b/cpp/src/binary/jit/util/type.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "binary/jit/util/type.h" + +namespace gdf { +namespace binops { +namespace jit { + + const char* getTypeName(gdf_dtype type) { + switch (type) { + case GDF_INT8: + return "int8_t"; + case GDF_INT16: + return "int16_t"; + case GDF_INT32: + case GDF_DATE32: + return "int32_t"; + case GDF_INT64: + case GDF_DATE64: + case GDF_TIMESTAMP: + return "int64_t"; + case GDF_UINT8: + return "uint8_t"; + case GDF_UINT16: + return "uint16_t"; + case GDF_UINT32: + return "uint32_t"; + case GDF_UINT64: + return "uint64_t"; + case GDF_FLOAT32: + return "float"; + case GDF_FLOAT64: + return "double"; + default: + return "double"; + } + } + + const char* getOperatorName(gdf_binary_operator ope) { + switch (ope) { + case GDF_ADD: + return "Add"; + case GDF_SUB: + return "Sub"; + case GDF_MUL: + return "Mul"; + case GDF_DIV: + return "Div"; + case GDF_TRUE_DIV: + return "TrueDiv"; + case GDF_FLOOR_DIV: + return "FloorDiv"; + case GDF_MOD: + return "Mod"; + case GDF_POW: + return "Pow"; + //case GDF_COMBINE: + //case GDF_COMBINE_FIRST: + //case GDF_ROUND: + case GDF_EQUAL: + return "Equal"; + case GDF_NOT_EQUAL: + return "NotEqual"; + case GDF_LESS: + return "Less"; + case GDF_GREATER: + return "Greater"; + case GDF_LESS_EQUAL: + return "LessEqual"; + case GDF_GREATER_EQUAL: + return "GreaterEqual"; + //GDF_PRODUCT, + //GDF_DOT + default: + return "None"; + } + } + +} // namespace jit +} // namespace binops +} // namespace gdf diff --git a/cpp/src/binary/jit/util/type.h b/cpp/src/binary/jit/util/type.h new file mode 100644 index 000000000000..78fe34334e58 --- /dev/null +++ b/cpp/src/binary/jit/util/type.h @@ -0,0 +1,35 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_BINARY_OPERATION_JIT_UTIL_TYPE_H +#define GDF_BINARY_OPERATION_JIT_UTIL_TYPE_H + +#include "cudf.h" + +namespace gdf { +namespace binops { +namespace jit { + + const char* getTypeName(gdf_dtype type); + + const char* getOperatorName(gdf_binary_operator ope); + +} +} +} + +#endif diff --git a/thirdparty/jitify b/thirdparty/jitify new file mode 160000 index 000000000000..727b1ebf06c5 --- /dev/null +++ b/thirdparty/jitify @@ -0,0 +1 @@ +Subproject commit 727b1ebf06c598f7584fa076032359236530e0a6 From d66bfda8bee6d0d37b8ddc063b96f1a04ea7369d Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Feb 2019 22:11:52 +0530 Subject: [PATCH 02/51] Jitify binops google tests. --- cpp/tests/CMakeLists.txt | 11 + cpp/tests/binary/integration/assert-binops.h | 247 ++++++++ .../binary-operation-integration-test.cpp | 453 ++++++++++++++ .../binary-operation-operands-null-test.cpp | 514 ++++++++++++++++ .../binary/unit/binop-verify-input-test.cpp | 571 ++++++++++++++++++ cpp/tests/binary/util/field.h | 113 ++++ cpp/tests/binary/util/operation.h | 111 ++++ cpp/tests/binary/util/scalar.h | 108 ++++ cpp/tests/binary/util/types.cpp | 137 +++++ cpp/tests/binary/util/types.h | 199 ++++++ cpp/tests/binary/util/vector.h | 185 ++++++ 11 files changed, 2649 insertions(+) create mode 100644 cpp/tests/binary/integration/assert-binops.h create mode 100644 cpp/tests/binary/integration/binary-operation-integration-test.cpp create mode 100644 cpp/tests/binary/integration/binary-operation-operands-null-test.cpp create mode 100644 cpp/tests/binary/unit/binop-verify-input-test.cpp create mode 100644 cpp/tests/binary/util/field.h create mode 100644 cpp/tests/binary/util/operation.h create mode 100644 cpp/tests/binary/util/scalar.h create mode 100644 cpp/tests/binary/util/types.cpp create mode 100644 cpp/tests/binary/util/types.h create mode 100644 cpp/tests/binary/util/vector.h diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 97da6b3edd8d..a0e7d476318e 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -159,6 +159,17 @@ set(UNARY_TEST_SRC ConfigureTest(UNARY_TEST "${UNARY_TEST_SRC}") +################################################################################################### +# - binary tests ---------------------------------------------------------------------------------- + +set(BINARY_TEST_SRC + "${CMAKE_CURRENT_SOURCE_DIR}/binary/util/types.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/binary/unit/binop-verify-input-test.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/binary/integration/binary-operation-integration-test.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/binary/integration/binary-operation-operands-null-test.cpp") + +ConfigureTest(BINARY_TEST "${BINARY_TEST_SRC}") + ################################################################################################### # - csv tests ------------------------------------------------------------------------------------- diff --git a/cpp/tests/binary/integration/assert-binops.h b/cpp/tests/binary/integration/assert-binops.h new file mode 100644 index 000000000000..e906821a4d3e --- /dev/null +++ b/cpp/tests/binary/integration/assert-binops.h @@ -0,0 +1,247 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_TESTS_BINARY_OPERATION_INTEGRATION_ASSERT_BINOPS_H +#define GDF_TESTS_BINARY_OPERATION_INTEGRATION_ASSERT_BINOPS_H + +#include "gtest/gtest.h" +#include "tests/binary/util/scalar.h" +#include "tests/binary/util/vector.h" +#include "tests/binary/util/operation.h" + +namespace gdf { +namespace test { +namespace binop { + +template +void ASSERT_BINOP(gdf::library::Vector& out, + gdf::library::Scalar& vax, + gdf::library::Vector& vay, + TypeOpe&& ope) { + ASSERT_TRUE(out.dataSize() == vay.dataSize()); + for (int index = 0; index < out.dataSize(); ++index) { + ASSERT_TRUE(out.data[index] == (TypeOut)(ope((TypeVay) vax.getValue(), vay.data[index]))); + } + + uint32_t vax_valid = (vax.isValid() ? UINT32_MAX : 0); + ASSERT_TRUE(out.validSize() == vay.validSize()); + for (int index = 0; index < out.validSize(); ++index) { + ASSERT_TRUE(out.valid[index] == (vax_valid & vay.valid[index])); + } +} + +template +void ASSERT_BINOP(gdf::library::Vector& out, + gdf::library::Vector& vax, + gdf::library::Scalar& vay, + TypeOpe&& ope) { + ASSERT_TRUE(out.dataSize() == vax.dataSize()); + for (int index = 0; index < out.dataSize(); ++index) { + ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax.data[index], (TypeVay) vay.getValue()))); + } + + uint32_t vay_valid = (vay.isValid() ? UINT32_MAX : 0); + ASSERT_TRUE(out.validSize() == vax.validSize()); + for (int index = 0; index < out.validSize(); ++index) { + ASSERT_TRUE(out.valid[index] == (vax.valid[index] & vay_valid)); + } +} + +template +void ASSERT_BINOP(gdf::library::Vector& out, + gdf::library::Vector& vax, + gdf::library::Vector& vay, + TypeOpe&& ope) { + ASSERT_TRUE(out.dataSize() == vax.dataSize()); + ASSERT_TRUE(out.dataSize() == vay.dataSize()); + for (int index = 0; index < out.dataSize(); ++index) { + ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax.data[index], vay.data[index]))); + } + + ASSERT_TRUE(out.validSize() == vax.validSize()); + ASSERT_TRUE(out.validSize() == vay.validSize()); + for (int index = 0; index < out.validSize(); ++index) { + ASSERT_TRUE(out.valid[index] == vax.valid[index] | vay.valid[index]); + } +} + +/** + * According to CUDA Programming Guide, 'E.1. Standard Functions', 'Table 7 - Double-Precision + * Mathematical Standard Library Functions with Maximum ULP Error' + * The pow function has 2 (full range) maximum ulp error. + */ +template +void ASSERT_BINOP(gdf::library::Vector& out, + gdf::library::Vector& vax, + gdf::library::Vector& vay, + gdf::library::operation::Pow&& ope) { + const int ULP = 2.0; + ASSERT_TRUE(out.dataSize() == vax.dataSize()); + ASSERT_TRUE(out.dataSize() == vay.dataSize()); + for (int index = 0; index < out.dataSize(); ++index) { + ASSERT_TRUE(abs(out.data[index] - (TypeOut)(ope(vax.data[index], vay.data[index]))) < ULP); + } + + ASSERT_TRUE(out.validSize() == vax.validSize()); + ASSERT_TRUE(out.validSize() == vay.validSize()); + for (int index = 0; index < out.validSize(); ++index) { + ASSERT_TRUE(out.valid[index] == (vax.valid[index] & vay.valid[index])); + } +} + +template +void ASSERT_BINOP(gdf::library::Vector& out, + gdf::library::Scalar& vax, + gdf::library::Vector& vay, + gdf::library::Scalar& def, + TypeOpe&& ope) { + using ValidType = typename gdf::library::Vector::ValidType; + int ValidSize = gdf::library::Vector::ValidSize; + + ASSERT_TRUE(out.dataSize() == vay.dataSize()); + ASSERT_TRUE(out.validSize() == vay.validSize()); + + ValidType mask = 1; + int index_valid = 0; + for (int index = 0; index < out.dataSize(); ++index) { + if (!(index % ValidSize)) { + mask = 1; + index_valid = index / ValidSize; + } else { + mask <<= 1; + } + + TypeVay vax_aux = (TypeVay)vax; + if (!vax.isValid()) { + vax_aux = (TypeVay)((TypeVal) def.getValue()); + } + + TypeVax vay_aux = vay.data[index]; + if ((vay.valid[index_valid] & mask) == 0) { + vay_aux = (TypeVal) def.getValue(); + } + + ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax_aux, vay_aux))); + } + + uint32_t vax_valid = (vax.isValid() ? UINT32_MAX : 0); + uint32_t def_valid = (def.isValid() ? UINT32_MAX : 0); + ASSERT_TRUE(out.validSize() == vay.validSize()); + for (int index = 0; index < out.validSize(); ++index) { + uint32_t output = (vay.valid[index] & vax_valid) | + (vay.valid[index] & def_valid) | + (vax_valid & def_valid); + ASSERT_TRUE(out.valid[index] == output); + } +} + +template +void ASSERT_BINOP(gdf::library::Vector& out, + gdf::library::Vector& vax, + gdf::library::Scalar& vay, + gdf::library::Scalar& def, + TypeOpe&& ope) { + using ValidType = typename gdf::library::Vector::ValidType; + int ValidSize = gdf::library::Vector::ValidSize; + + ASSERT_TRUE(out.dataSize() == vax.dataSize()); + ASSERT_TRUE(out.validSize() == vax.validSize()); + + ValidType mask = 1; + int index_valid = 0; + for (int index = 0; index < out.dataSize(); ++index) { + if (!(index % ValidSize)) { + mask = 1; + index_valid = index / ValidSize; + } else { + mask <<= 1; + } + + TypeVax vax_aux = vax.data[index]; + if ((vax.valid[index_valid] & mask) == 0) { + vax_aux = (TypeVal) def.getValue(); + } + + TypeVay vay_aux = (TypeVay)vay; + if (!vay.isValid()) { + vay_aux = (TypeVay)((TypeVal) def.getValue()); + } + + ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax_aux, vay_aux))); + } + + uint32_t vay_valid = (vay.isValid() ? UINT32_MAX : 0); + uint32_t def_valid = (def.isValid() ? UINT32_MAX : 0); + ASSERT_TRUE(out.validSize() == vax.validSize()); + for (int index = 0; index < out.validSize(); ++index) { + uint32_t output = (vax.valid[index] & vay_valid) | + (vax.valid[index] & def_valid) | + (vay_valid & def_valid); + ASSERT_TRUE(out.valid[index] == output); + } +} + +template +void ASSERT_BINOP(gdf::library::Vector& out, + gdf::library::Vector& vax, + gdf::library::Vector& vay, + gdf::library::Scalar& def, + TypeOpe&& ope) { + using ValidType = typename gdf::library::Vector::ValidType; + int ValidSize = gdf::library::Vector::ValidSize; + + ASSERT_TRUE(out.dataSize() == vax.dataSize()); + ASSERT_TRUE(out.dataSize() == vay.dataSize()); + + ValidType mask = 1; + int index_valid = 0; + for (int index = 0; index < out.dataSize(); ++index) { + if (!(index % ValidSize)) { + mask = 1; + index_valid = index / ValidSize; + } else { + mask <<= 1; + } + + TypeVax vax_aux = vax.data[index]; + if ((vax.valid[index_valid] & mask) == 0) { + vax_aux = (TypeVax) def.getValue(); + } + + TypeVay vay_aux = vay.data[index]; + if ((vay.valid[index_valid] & mask) == 0) { + vay_aux = (TypeVay) def.getValue(); + } + + ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax_aux, vay_aux))); + } + + uint32_t def_valid = (def.isValid() ? UINT32_MAX : 0); + ASSERT_TRUE(out.validSize() == vax.validSize()); + ASSERT_TRUE(out.validSize() == vay.validSize()); + for (int index = 0; index < out.validSize(); ++index) { + ASSERT_TRUE(out.valid[index] == ((vax.valid[index] & vay.valid[index]) | + (vax.valid[index] & def_valid) | + (vay.valid[index] & def_valid))); + } +} + +} // namespace binop +} // namespace test +} // namespace gdf + +#endif diff --git a/cpp/tests/binary/integration/binary-operation-integration-test.cpp b/cpp/tests/binary/integration/binary-operation-integration-test.cpp new file mode 100644 index 000000000000..7124f6f52a3b --- /dev/null +++ b/cpp/tests/binary/integration/binary-operation-integration-test.cpp @@ -0,0 +1,453 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "tests/binary/integration/assert-binops.h" + +namespace gdf { +namespace test { +namespace binop { + +struct BinaryOperationIntegrationTest : public ::testing::Test { + BinaryOperationIntegrationTest() { + } + + virtual ~BinaryOperationIntegrationTest() { + } + + virtual void SetUp() { + } + + virtual void TearDown() { + } +}; + + +TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_SI32_FP32_UI32) { + using SI32 = gdf::library::GdfEnumType; + using FP32 = gdf::library::GdfEnumType; + using UI32 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Scalar vax; + gdf::library::Vector vay; + + vay.rangeData(0, 100000, 1) + .rangeValid(false, 0, 4); + vax.setValue(100); + out.emplaceVector(vay.dataSize()); + + auto result = gdf_binary_operation_v_s_v(out.column(), vax.scalar(), vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_SI32_FP32_UI32) { + using SI32 = gdf::library::GdfEnumType; + using FP32 = gdf::library::GdfEnumType; + using UI32 = gdf::library::GdfEnumType; + using SUB = gdf::library::operation::Sub; + + gdf::library::Vector out; + gdf::library::Scalar vax; + gdf::library::Vector vay; + + vay.rangeData(0, 100000, 1) + .rangeValid(false, 0, 4); + vax.setValue(10000); + out.emplaceVector(vay.dataSize()); + + auto result = gdf_binary_operation_v_s_v(out.column(), vax.scalar(), vay.column(), GDF_SUB); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, SUB()); +} + + +TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_SI08_UI16_SI16) { + using SI08 = gdf::library::GdfEnumType; + using UI16 = gdf::library::GdfEnumType; + using SI16 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 6); + vay.setValue(100); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_UI32_FP64_SI08) { + using UI32 = gdf::library::GdfEnumType; + using FP64 = gdf::library::GdfEnumType; + using SI08 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(0.0, 200.0, 2.0) + .rangeValid(false, 0, 3); + vay.rangeData(0, 100, 1) + .rangeValid(false, 0, 4); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_Default_SI32_SI16_UI64_SI64) { + using SI32 = gdf::library::GdfEnumType; + using SI16 = gdf::library::GdfEnumType; + using UI64 = gdf::library::GdfEnumType; + using SI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Scalar vax; + gdf::library::Vector vay; + gdf::library::Scalar def; + + vax.setValue(50); + vay.rangeData(0, 10000, 2) + .rangeValid(false, 0, 4); + def.setValue(1000); + out.emplaceVector(vay.dataSize()); + + auto result = gdf_binary_operation_v_s_v_d(out.column(), vax.scalar(), vay.column(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_Default_SI32_SI16_UI64_SI64) { + using SI32 = gdf::library::GdfEnumType; + using SI16 = gdf::library::GdfEnumType; + using UI64 = gdf::library::GdfEnumType; + using SI64 = gdf::library::GdfEnumType; + using SUB = gdf::library::operation::Sub; + + gdf::library::Vector out; + gdf::library::Scalar vax; + gdf::library::Vector vay; + gdf::library::Scalar def; + + vax.setValue(500); + vay.rangeData(0, 10000, 2) + .rangeValid(false, 0, 4); + def.setValue(1000); + out.emplaceVector(vay.dataSize()); + + auto result = gdf_binary_operation_v_s_v_d(out.column(), vax.scalar(), vay.column(), def.scalar(), GDF_SUB); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, SUB()); +} + + +TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_Default_FP32_SI16_UI08_UI32) { + using FP32 = gdf::library::GdfEnumType; + using SI16 = gdf::library::GdfEnumType; + using UI08 = gdf::library::GdfEnumType; + using UI32 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 30000, 3) + .rangeValid(false, 0, 4); + vay.setValue(50); + def.setValue(150); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_Default_FP64_SI32_UI32_UI16) { + using FP64 = gdf::library::GdfEnumType; + using SI32 = gdf::library::GdfEnumType; + using UI32 = gdf::library::GdfEnumType; + using UI16 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100000, 1) + .rangeValid(false, 0, 3); + vay.rangeData(0, 200000, 2) + .rangeValid(false, 0, 4); + def.setValue(150); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using SUB = gdf::library::operation::Sub; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(100000, 200000, 2) + .rangeValid(true, 0, 4); + vay.rangeData(50000, 100000, 1) + .rangeValid(false, 0, 3); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_SUB); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, SUB()); +} + + +TEST_F(BinaryOperationIntegrationTest, Mul_Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using MUL = gdf::library::operation::Mul; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(100000, 200000, 2) + .rangeValid(false, 0 , 3); + vay.rangeData(50000, 100000, 1) + .rangeValid(false, 0, 4); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MUL); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, MUL()); +} + + +TEST_F(BinaryOperationIntegrationTest, Div_Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using DIV = gdf::library::operation::Div; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(100000, 200000, 2) + .rangeValid(false, 0, 6); + vay.rangeData(50000, 100000, 1) + .rangeValid(false, 0, 8); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_DIV); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, DIV()); +} + + +TEST_F(BinaryOperationIntegrationTest, TrueDiv_Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using TRUEDIV = gdf::library::operation::TrueDiv; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(100000, 200000, 2) + .rangeValid(true, 0, 3); + vay.rangeData(50000, 100000, 1) + .rangeValid(true, 0, 4); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_TRUE_DIV); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, TRUEDIV()); +} + + +TEST_F(BinaryOperationIntegrationTest, FloorDiv_Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using FLOORDIV = gdf::library::operation::FloorDiv; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(100000, 200000, 2) + .rangeValid(false, 0, 6); + vay.rangeData(50000, 100000, 1) + .rangeValid(false, 0, 8); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_FLOOR_DIV); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, FLOORDIV()); +} + + +TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using MOD = gdf::library::operation::Mod; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(120, 220, 2) + .rangeValid(false, 0, 3); + vay.rangeData(50, 100, 1) + .rangeValid(false, 0, 5); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, MOD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP32) { + using FP32 = gdf::library::GdfEnumType; + using MOD = gdf::library::operation::Mod; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(120, 220, 2) + .rangeValid(false, 0, 4); + vay.rangeData(50, 100, 1) + .rangeValid(false, 0, 6); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, MOD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP64) { + using FP64 = gdf::library::GdfEnumType; + using MOD = gdf::library::operation::Mod; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(120, 220, 2) + .rangeValid(true, 0, 3); + vay.rangeData(50, 100, 1) + .rangeValid(false, 0, 4); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, MOD()); +} + + +TEST_F(BinaryOperationIntegrationTest, Pow_Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using POW = gdf::library::operation::Pow; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(0, 500, 1) + .rangeValid(false, 0, 6); + vay.fillData(500, 2) + .rangeValid(false, 0, 4); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_POW); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, POW()); +} + +} // namespace binop +} // namespace test +} // namespace gdf diff --git a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp new file mode 100644 index 000000000000..52192d05dd3c --- /dev/null +++ b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp @@ -0,0 +1,514 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "tests/binary/integration/assert-binops.h" + +namespace gdf { +namespace test { +namespace binop { + +struct BinaryOperationOperandsNullTest : public ::testing::Test { + BinaryOperationOperandsNullTest() { + } + + virtual ~BinaryOperationOperandsNullTest() { + } + + virtual void SetUp() { + } + + virtual void TearDown() { + } +}; + +/* + * Kernels v_v_s, using UI64 + * Output:Vector, OperandX:Vector, OperandY:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_UI64_WithScalarOperandNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.setValue(500) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_UI64_WithScalarOperandNotNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.setValue(500) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + +/* + * Kernels v_v_s, using FP64 + * Output:Vector, OperandX:Vector, OperandY:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNull) { + using FP64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.setValue(500.0) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNotNull) { + using FP64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.setValue(500.0) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + +/* + * Kernels v_v_v, using UI64 + * Output:Vector, OperandX:Vector, OperandY:Vector + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_UI64) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.rangeData(0, 200, 2) + .rangeValid(false, 0, 4); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + +/* + * Kernels v_v_v, using FP64 + * Output:Vector, OperandX:Vector, OperandY:Vector + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64) { + using FP64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.rangeData(0, 200.0, 2.0) + .rangeValid(false, 0, 4); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, ADD()); +} + +/* + * Kernels v_v_s_d, using UI64 + * Output:Vector, OperandX:Vector, OperandY:Scalar, OperandDefault:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithAllOperandsNotNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.setValue(222) + .setValid(true); + def.setValue(555) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithScalarOperandNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.setValue(1000) + .setValid(false); + def.setValue(500) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithDefaultOperandNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.setValue(250) + .setValid(true); + def.setValue(750) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithAllOperandsNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.setValue(500) + .setValid(false); + def.setValue(1000) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + +/* + * Kernels v_v_s_d, using FP32 + * Output:Vector, OperandX:Vector, OperandY:Scalar, OperandDefault:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithAllOperandsNotNull) { + using FP32 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.setValue(222.0) + .setValid(true); + def.setValue(555.0) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithScalarOperandNull) { + using FP32 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.setValue(1000.0) + .setValid(false); + def.setValue(500.0) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithDefaultOperandNull) { + using FP32 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.setValue(250.0) + .setValid(true); + def.setValue(750.0) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithAllOperandsNull) { + using FP32 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Scalar vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.setValue(500.0) + .setValid(false); + def.setValue(1000.0) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + +/* + * Kernels v_v_v_d, using UI64 + * Output:Vector, OperandX:Vector, OperandY:Vector, OperandDefault:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_Default_UI64_WithDefaultOperandNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.rangeData(0, 200, 2) + .rangeValid(false, 0, 4); + def.setValue(666) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_Default_UI64_WithDefaultOperandNotNull) { + using UI64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100, 1) + .rangeValid(false, 0, 3); + vay.rangeData(0, 200, 2) + .rangeValid(false, 0, 4); + def.setValue(222) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + +/* + * Kernels v_v_v_d, using FP64 + * Output:Vector, OperandX:Vector, OperandY:Vector, OperandDefault:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP64_WithDefaultOperandNull) { + using FP64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.rangeData(0, 200.0, 2.0) + .rangeValid(false, 0, 4); + def.setValue(555.0) + .setValid(false); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_Default_FP64_WithDefaultOperandNotNull) { + using FP64 = gdf::library::GdfEnumType; + using ADD = gdf::library::operation::Add; + + gdf::library::Vector out; + gdf::library::Vector vax; + gdf::library::Vector vay; + gdf::library::Scalar def; + + vax.rangeData(0, 100.0, 1.0) + .rangeValid(false, 0, 3); + vay.rangeData(0, 200.0, 2.0) + .rangeValid(false, 0, 4); + def.setValue(555.0) + .setValid(true); + out.emplaceVector(vax.dataSize()); + + auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + out.readVector(); + + ASSERT_BINOP(out, vax, vay, def, ADD()); +} + +} // namespace binop +} // namespace test +} // namespace gdf diff --git a/cpp/tests/binary/unit/binop-verify-input-test.cpp b/cpp/tests/binary/unit/binop-verify-input-test.cpp new file mode 100644 index 000000000000..2d8acba1e195 --- /dev/null +++ b/cpp/tests/binary/unit/binop-verify-input-test.cpp @@ -0,0 +1,571 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "gtest/gtest.h" +#include "tests/binary/util/scalar.h" +#include "tests/binary/util/vector.h" + +struct BinopVerifyInputTest : public ::testing::Test { + BinopVerifyInputTest() { + } + + virtual ~BinopVerifyInputTest() { + } + + virtual void SetUp() { + } + + virtual void TearDown() { + } +}; + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.fillData(0, 0); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.fillData(0, 0); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorNull) { + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + auto result = gdf_binary_operation_v_v_s(nullptr, vector_vax.column(), scalar.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + auto result = gdf_binary_operation_v_v_s(vector_out.column(), nullptr, scalar.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), nullptr, GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + vector_out.column()->dtype = (gdf_dtype)100; + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + vector_vax.column()->dtype = (gdf_dtype)100; + + gdf::library::Scalar scalar; + scalar.setValue(100); + + auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + scalar.scalar()->dtype = (gdf_dtype)100; + + auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.fillData(0, 0); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.fillData(0, 0); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.fillData(0, 0); + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorNull) { + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_v(nullptr, vector_vax.column(), vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), nullptr, vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), nullptr, GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + vector_out.column()->dtype = (gdf_dtype)100; + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + vector_vax.column()->dtype = (gdf_dtype)100; + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + vector_vay.column()->dtype = (gdf_dtype)100; + + auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOutputVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.fillData(0, 0); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.fillData(0, 0); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOutputVectorNull) { + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(nullptr, vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandVectorNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), nullptr, scalar.scalar(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandScalarNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), nullptr, defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOutputVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + vector_out.column()->dtype = (gdf_dtype)100; + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + vector_vax.column()->dtype = (gdf_dtype)100; + + gdf::library::Scalar scalar; + scalar.setValue(100); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandScalarType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar scalar; + scalar.setValue(100); + scalar.scalar()->dtype = (gdf_dtype)100; + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorOutputVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.fillData(0, 0); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorFirstOperandVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.fillData(0, 0); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorSecondOperandVectorZeroSize) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.fillData(0, 0); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorOutputVectorNull) { + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(nullptr, vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorFirstOperandVectorNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), nullptr, vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorSecondOperandVectorNull) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), nullptr, defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_DATASET_EMPTY); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorOutputVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + vector_out.column()->dtype = (gdf_dtype)100; + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorFirstOperandVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + vector_vax.column()->dtype = (gdf_dtype)100; + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} + + +TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorSecondOperandVectorType) { + gdf::library::Vector vector_out; + vector_out.rangeData(1, 10, 1); + + gdf::library::Vector vector_vax; + vector_vax.rangeData(1, 10, 1); + + gdf::library::Vector vector_vay; + vector_vay.rangeData(1, 10, 1); + vector_vay.column()->dtype = (gdf_dtype)100; + + gdf::library::Scalar defvalue; + defvalue.setValue(100); + + auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); +} diff --git a/cpp/tests/binary/util/field.h b/cpp/tests/binary/util/field.h new file mode 100644 index 000000000000..47d8016dd68f --- /dev/null +++ b/cpp/tests/binary/util/field.h @@ -0,0 +1,113 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_TESTS_BINARY_OPERATION_UTIL_FIELD_H +#define GDF_TESTS_BINARY_OPERATION_UTIL_FIELD_H + +#include +#include +#include + +namespace gdf { +namespace library { + + template + class Field { + public: + ~Field() { + destroy(); + } + + public: + void clear() { + mCpuData.clear(); + destroy(); + } + + void resize(int size) { + int sizeBytes = size * sizeof(Type); + if (sizeBytes != mSizeAllocBytes) { + mCpuData.resize(size); + destroy(); + create(size); + } + } + + public: + auto getGpuData() -> Type* { + return mGpuData; + } + + public: + auto begin() -> typename std::vector::iterator { + return mCpuData.begin(); + } + + auto end() -> typename std::vector::iterator { + return mCpuData.end(); + } + + auto back() -> typename std::vector::reference { + return mCpuData.back(); + } + + public: + auto size() -> std::size_t { + return mCpuData.size(); + } + + auto operator[](int index) -> Type& { + assert(index < mCpuData.size()); + return mCpuData[index]; + } + + public: + void write() { + if (mSizeAllocBytes) { + cudaMemcpy(mGpuData, mCpuData.data(), mSizeAllocBytes, cudaMemcpyHostToDevice); + } + } + + void read() { + if (mSizeAllocBytes) { + cudaMemcpy(mCpuData.data(), mGpuData, mSizeAllocBytes, cudaMemcpyDeviceToHost); + } + } + + protected: + void create(int size) { + mSizeAllocBytes = size * sizeof(Type); + cudaMalloc((void**)&(mGpuData), mSizeAllocBytes); + } + + void destroy() { + if (mSizeAllocBytes) { + mSizeAllocBytes = 0; + cudaFree(mGpuData); + } + } + + private: + int mSizeAllocBytes {0}; + Type* mGpuData {nullptr}; + std::vector mCpuData; + }; + +} // namespace library +} // namespace gdf + +#endif diff --git a/cpp/tests/binary/util/operation.h b/cpp/tests/binary/util/operation.h new file mode 100644 index 000000000000..4db30d049c94 --- /dev/null +++ b/cpp/tests/binary/util/operation.h @@ -0,0 +1,111 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_TESTS_BINARY_OPERATION_UTIL_OPERATION_H +#define GDF_TESTS_BINARY_OPERATION_UTIL_OPERATION_H + +#include + +namespace gdf { +namespace library { +namespace operation { + + template + struct Add { + TypeOut operator()(TypeVax vax, TypeVay vay) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)vax + (TypeCommon)vay); + } + }; + + template + struct Sub { + TypeOut operator()(TypeVax vax, TypeVay vay) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)vax - (TypeCommon)vay); + } + }; + + template + struct Mul { + TypeOut operator()(TypeVax vax, TypeVay vay) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)vax * (TypeCommon)vay); + } + }; + + template + struct Div { + TypeOut operator()(TypeVax vax, TypeVay vay) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)vax / (TypeCommon)vay); + } + }; + + template + struct TrueDiv { + TypeOut operator()(TypeVax vax, TypeVay vay) { + return (TypeOut)((double)vax / (double)vay); + } + }; + + template + struct FloorDiv { + TypeOut operator()(TypeVax vax, TypeVay vay) { + return (TypeOut)floor((double)vax / (double)vay); + } + }; + + template ::type> + struct Mod; + + template + struct Mod { + TypeOut operator()(TypeVax x, TypeVay y) { + return (TypeOut)((uint64_t)x % (uint64_t)y); + } + }; + + template + struct Mod { + TypeOut operator()(TypeVax x, TypeVay y) { + return (TypeOut)fmod((float)x, (float)y); + } + }; + + template + struct Mod { + TypeOut operator()(TypeVax x, TypeVay y) { + return (TypeOut)fmod((double)x, (double)y); + } + }; + + template + struct Pow { + TypeOut operator()(TypeVax vax, TypeVay vay) { + return (TypeOut)pow((double)vax, (double)vay); + } + }; + +} // namespace operation +} // namespace library +} // namespace gdf + +#endif diff --git a/cpp/tests/binary/util/scalar.h b/cpp/tests/binary/util/scalar.h new file mode 100644 index 000000000000..92c0b76bcf77 --- /dev/null +++ b/cpp/tests/binary/util/scalar.h @@ -0,0 +1,108 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_TESTS_BINARY_OPERATION_UTIL_SCALAR_H +#define GDF_TESTS_BINARY_OPERATION_UTIL_SCALAR_H + +#include "tests/binary/util/types.h" +#include "cudf.h" + +namespace gdf { +namespace library { + + template + class Scalar { + public: + Scalar& setValue(Type value) { + mScalar.dtype = gdf::library::GdfDataType::Value; + gdf::library::setScalar(mScalar, value); + mScalar.is_valid = true; + return *this; + } + + Scalar& setValid(bool value) { + mScalar.is_valid = value; + return *this; + } + + public: + Type getValue() { + return (Type)*this; + } + + gdf_dtype getType() { + return mScalar.dtype; + } + + bool isValid() { + return mScalar.is_valid; + } + + public: + gdf_scalar* scalar() { + return &mScalar; + } + + public: + operator int8_t() const { + return mScalar.data.si08; + } + + operator int16_t() const { + return mScalar.data.si16; + } + + operator int32_t() const { + return mScalar.data.si32; + } + + operator int64_t() const { + return mScalar.data.si64; + } + + operator uint8_t() const { + return mScalar.data.ui08; + } + + operator uint16_t() const { + return mScalar.data.ui16; + } + + operator uint32_t() const { + return mScalar.data.ui32; + } + + operator uint64_t() const { + return mScalar.data.ui64; + } + + operator float() const { + return mScalar.data.fp32; + } + + operator double() const { + return mScalar.data.fp64; + } + + private: + gdf_scalar mScalar; + }; + +} // namespace library +} // namespace gdf + +#endif diff --git a/cpp/tests/binary/util/types.cpp b/cpp/tests/binary/util/types.cpp new file mode 100644 index 000000000000..dce691a68365 --- /dev/null +++ b/cpp/tests/binary/util/types.cpp @@ -0,0 +1,137 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "tests/binary/util/types.h" + +namespace gdf { +namespace library { + + const char* getTypeName(gdf_dtype type) { + switch (type) { + case GDF_INT8: + return "GDF_INT8"; + case GDF_INT16: + return "GDF_INT16"; + case GDF_INT32: + return "GDF_INT32"; + case GDF_INT64: + return "GDF_INT64"; + case GDF_UINT8: + return "GDF_UINT8"; + case GDF_UINT16: + return "GDF_UINT16"; + case GDF_UINT32: + return "GDF_UINT32"; + case GDF_UINT64: + return "GDF_UINT64"; + case GDF_FLOAT32: + return "GDF_FLOAT32"; + case GDF_FLOAT64: + return "GDF_FLOAT64"; + case GDF_DATE32: + return "GDF_DATE32"; + case GDF_DATE64: + return "GDF_DATE64"; + case GDF_TIMESTAMP: + return "GDF_TIMESTAMP"; + } + } + + namespace helper { + void setScalar(gdf_scalar& scalar, int8_t value) { + scalar.data.si08 = value; + } + + void setScalar(gdf_scalar& scalar, int16_t value) { + scalar.data.si16 = value; + } + + void setScalar(gdf_scalar& scalar, int32_t value) { + scalar.data.si32 = value; + } + + void setScalar(gdf_scalar& scalar, int64_t value) { + scalar.data.si64 = value; + } + + void setScalar(gdf_scalar& scalar, uint8_t value) { + scalar.data.ui08 = value; + } + + void setScalar(gdf_scalar& scalar, uint16_t value) { + scalar.data.ui16 = value; + } + + void setScalar(gdf_scalar& scalar, uint32_t value) { + scalar.data.ui32 = value; + } + + void setScalar(gdf_scalar& scalar, uint64_t value) { + scalar.data.ui64 = value; + } + + void setScalar(gdf_scalar& scalar, float value) { + scalar.data.fp32 = value; + } + + void setScalar(gdf_scalar& scalar, double value) { + scalar.data.fp64 = value; + } + } + + int8_t getScalar(int8_t, gdf_scalar* scalar) { + return scalar->data.si08; + } + + int16_t getScalar(int16_t, gdf_scalar* scalar) { + return scalar->data.si16; + } + + int32_t getScalar(int32_t, gdf_scalar* scalar) { + return scalar->data.si32; + } + + int64_t getScalar(int64_t, gdf_scalar* scalar) { + return scalar->data.si64; + } + + uint8_t getScalar(uint8_t, gdf_scalar* scalar) { + return scalar->data.ui08; + } + + uint16_t getScalar(uint16_t, gdf_scalar* scalar) { + return scalar->data.ui16; + } + + uint32_t getScalar(uint32_t, gdf_scalar* scalar) { + return scalar->data.ui32; + } + + uint64_t getScalar(uint64_t, gdf_scalar* scalar) { + return scalar->data.ui64; + } + + float getScalar(float, gdf_scalar* scalar) { + return scalar->data.fp32; + } + + double getScalar(double, gdf_scalar* scalar) { + return scalar->data.fp64; + } + +} // namespace library +} // namespace gdf diff --git a/cpp/tests/binary/util/types.h b/cpp/tests/binary/util/types.h new file mode 100644 index 000000000000..a553c2ebf336 --- /dev/null +++ b/cpp/tests/binary/util/types.h @@ -0,0 +1,199 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_TESTS_BINARY_OPERATION_UTIL_TYPES_H +#define GDF_TESTS_BINARY_OPERATION_UTIL_TYPES_H + +#include "cudf.h" + +namespace gdf { +namespace library { + + namespace helper { + void setScalar(gdf_scalar& scalar, int8_t value); + + void setScalar(gdf_scalar& scalar, int16_t value); + + void setScalar(gdf_scalar& scalar, int32_t value); + + void setScalar(gdf_scalar& scalar, int64_t value); + + void setScalar(gdf_scalar& scalar, uint8_t value); + + void setScalar(gdf_scalar& scalar, uint16_t value); + + void setScalar(gdf_scalar& scalar, uint32_t value); + + void setScalar(gdf_scalar& scalar, uint64_t value); + + void setScalar(gdf_scalar& scalar, float value); + + void setScalar(gdf_scalar& scalar, double value); + } + + namespace helper { + template + struct GdfEnumType; + + template <> + struct GdfEnumType { + using Type = void; + }; + + template <> + struct GdfEnumType { + using Type = int8_t; + }; + + template <> + struct GdfEnumType { + using Type = int16_t; + }; + + template <> + struct GdfEnumType { + using Type = int32_t; + }; + + template <> + struct GdfEnumType { + using Type = int64_t; + }; + + template <> + struct GdfEnumType { + using Type = uint8_t; + }; + + template <> + struct GdfEnumType { + using Type = uint16_t; + }; + + template <> + struct GdfEnumType { + using Type = uint32_t; + }; + + template <> + struct GdfEnumType { + using Type = uint64_t; + }; + + template <> + struct GdfEnumType { + using Type = float; + }; + + template <> + struct GdfEnumType { + using Type = double; + }; + } + + namespace helper { + template + struct GdfDataType; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_INT8; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_INT16; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_INT32; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_INT64; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_UINT8; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_UINT16; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_UINT32; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_UINT64; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_FLOAT32; + }; + + template <> + struct GdfDataType { + static constexpr gdf_dtype Value = GDF_FLOAT64; + }; + } + + template + using GdfEnumType = typename helper::GdfEnumType::Type; + + template + using GdfDataType = helper::GdfDataType; + + template + void setScalar(gdf_scalar& scalar, Type value) { + helper::setScalar(scalar, value); + } + + const char* getTypeName(gdf_dtype type); + + int8_t getScalar(int8_t, gdf_scalar* scalar); + + int16_t getScalar(int16_t, gdf_scalar* scalar); + + int32_t getScalar(int32_t, gdf_scalar* scalar); + + int64_t getScalar(int64_t, gdf_scalar* scalar); + + uint8_t getScalar(uint8_t, gdf_scalar* scalar); + + uint16_t getScalar(uint16_t, gdf_scalar* scalar); + + uint32_t getScalar(uint32_t, gdf_scalar* scalar); + + uint64_t getScalar(uint64_t, gdf_scalar* scalar); + + float getScalar(float, gdf_scalar* scalar); + + double getScalar(double, gdf_scalar* scalar); + +} // namespace library +} // namespace gdf + +#endif diff --git a/cpp/tests/binary/util/vector.h b/cpp/tests/binary/util/vector.h new file mode 100644 index 000000000000..3974daaa1731 --- /dev/null +++ b/cpp/tests/binary/util/vector.h @@ -0,0 +1,185 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 GDF_TESTS_BINARY_OPERATION_UTIL_VECTOR_H +#define GDF_TESTS_BINARY_OPERATION_UTIL_VECTOR_H + +#include "tests/binary/util/types.h" +#include "tests/binary/util/field.h" +#include "cudf.h" + +namespace gdf { +namespace library { + + template + class Vector { + public: + using ValidType = int32_t; + static constexpr int ValidSize = 32; + + private: + template + class InnerWrapper { + public: + InnerWrapper(Field& container) + : mField (container) + { } + + T operator[](int index) { + return mField[index]; + } + + private: + Field& mField; + }; + + public: + ~Vector() { + eraseGpu(); + } + + Vector& clearGpu() { + eraseGpu(); + return *this; + } + + Vector& rangeData(Type init, Type final, Type step) { + assert((Type)0 < step); + assert(init < final); + + int size = (final - init) / step; + mData.resize(size); + for (int k = 0; k < size; ++k) { + mData[k] = init; + init += step; + } + mData.write(); + updateData(); + return *this; + } + + Vector& fillData(int size, Type value) { + mData.resize(size); + std::fill(mData.begin(), mData.end(), value); + mData.write(); + updateData(); + return *this; + } + + Vector& rangeValid(bool value) { + int size = (mData.size() / ValidSize) + ((mData.size() % ValidSize) ? 1 : 0); + mValid.resize(size); + + std::generate(mValid.begin(), mValid.end(), [value] { return -(ValidType)value; }); + clearPaddingBits(); + + mValid.write(); + updateValid(); + return *this; + } + + Vector& rangeValid(bool value, int init, int step) { + int final = mData.size(); + int size = (final / ValidSize) + ((final % ValidSize) ? 1 : 0); + mValid.resize(size); + + for (int index = 0; index < size; ++index) { + ValidType val = 0; + while (((init / ValidSize) == index) && (init < final)) { + val |= (1 << (init % ValidSize)); + init += step; + } + if (value) { + mValid[index] = val; + } else { + mValid[index] = ~val; + } + } + clearPaddingBits(); + + mValid.write(); + updateValid(); + return *this; + } + + void emplaceVector(int size) { + int validSize = (size / ValidSize) + ((size % ValidSize) ? 1 : 0); + mData.resize(size); + mValid.resize(validSize); + updateData(); + updateValid(); + } + + void readVector() { + mData.read(); + mValid.read(); + } + + public: + int dataSize() { + return mData.size(); + } + + int validSize() { + return mValid.size(); + } + + gdf_column* column() { + return &mColumn; + } + + public: + InnerWrapper data{mData}; + + InnerWrapper valid{mValid}; + + private: + void eraseGpu() { + mData.clear(); + mValid.clear(); + } + + void updateData() { + mColumn.size = mData.size(); + mColumn.dtype = GdfDataType::Value; + mColumn.data = (void*)mData.getGpuData(); + } + + void updateValid() { + mColumn.valid = (gdf_valid_type*)mValid.getGpuData(); + } + + void clearPaddingBits() { + int padding = mData.size() % ValidSize; + if (padding) { + padding = (1 << padding) - 1; + mValid.back() &= padding; + } + } + + private: + gdf_column mColumn; + + private: + Field mData; + Field mValid; + }; + +} // namespace library +} // namespace gdf + +#endif From c23fda506c116367f756c5a6f69fce2b53b35c2d Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Fri, 8 Feb 2019 03:19:03 +0530 Subject: [PATCH 03/51] Cleanups - Removed APIs that allowed for a default value - Removed custom vector implementation from unit test - Added Changelog --- CHANGELOG.md | 1 + cpp/include/cudf/functions.h | 86 +-- cpp/src/binary/jit/code/kernel.cpp | 72 --- cpp/src/binary/jit/core/binop.cpp | 77 +-- cpp/src/binary/jit/core/launcher.cpp | 29 - cpp/tests/binary/integration/assert-binops.h | 137 ----- .../binary-operation-integration-test.cpp | 135 +---- .../binary-operation-operands-null-test.cpp | 336 +---------- .../binary/unit/binop-verify-input-test.cpp | 527 +++++------------- 9 files changed, 160 insertions(+), 1240 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dd539be2623..6beb02f7bf20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ## Improvements +- PR #892 Add support for heterogeneous types in binary ops with JIT - PR #730 Improve performance of `gdf_table` constructor - PR #822 Add support for `__cuda_array_interface__` for ingest - PR #756 Consolidate common helper functions from unordered map and multimap diff --git a/cpp/include/cudf/functions.h b/cpp/include/cudf/functions.h index ff48928df83a..32b3c8e1dfe0 100644 --- a/cpp/include/cudf/functions.h +++ b/cpp/include/cudf/functions.h @@ -611,7 +611,7 @@ gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output); * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ -gdf_error gdf_binary_operation_v_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope); +gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope); /** * @brief Binary operation function between gdf_column and gdf_scalar structs. @@ -632,7 +632,7 @@ gdf_error gdf_binary_operation_v_s_v(gdf_column* out, gdf_scalar* vax, gdf_colum * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ -gdf_error gdf_binary_operation_v_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope); +gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope); /** * @brief Binary operation function between two gdf_column structs. @@ -652,88 +652,8 @@ gdf_error gdf_binary_operation_v_v_s(gdf_column* out, gdf_column* vax, gdf_scala * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ -gdf_error gdf_binary_operation_v_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope); +gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope); -/** - * @brief Binary operation function between gdf_scalar and gdf_column structs. - * - * The function performs the binary operation of a gdf_scalar operand and a - * gdf_column operand. A default scalar operand is used to replace an operand - * in the binary operation when such operand is null. - * - * Whether any operand (vax or vay) is null, then it will be replaced with the - * default scalar operand value (def). In case both operands (vax and vay) are - * null, each of them will be replaced with the default scalar operand value. - * - * The valid field in the gdf_column output will be 1 (by bit) when two or three - * operands (vax, vay and def) are not null. Otherwise, it will be 0 (by bit). - * - * It is required to set in an appropriate manner the fields in the gdf_scalar and - * gdf_column structs due to that the binary operation will not be performed. - * - * @param out (gdf_column) Output of the operation. - * @param vax (gdf_column) First operand of the operation. - * @param vay (gdf_scalar) Second operand of the operation - gdf_scalar. - * @param def (gdf_scalar) Default operand used to replace a null operand. - * @param ope (enum) The binary operator that is going to be used in the operation. - * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate - * error code - */ -gdf_error gdf_binary_operation_v_s_v_d(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope); - -/** - * @brief Binary operation function between gdf_column and gdf_scalar structs. - * - * The function performs the binary operation of a gdf_column operand and a - * gdf_scalar operand. A default scalar operand is used to replace an operand - * in the binary operation when such operand is null. - * - * Whether any operand (vax or vay) is null, then it will be replaced with the - * default scalar operand value (def). In case both operands (vax and vay) are - * null, each of them will be replaced with the default scalar operand value. - * - * The valid field in the gdf_column output will be 1 (by bit) when two or three - * operands (vax, vay and def) are not null. Otherwise, it will be 0 (by bit). - * - * It is required to set in an appropriate manner the fields in the gdf_scalar and - * gdf_column structs due to that the binary operation will not be performed. - * - * @param out (gdf_column) Output of the operation. - * @param vax (gdf_column) First operand of the operation. - * @param vay (gdf_scalar) Second operand of the operation - gdf_scalar. - * @param def (gdf_scalar) Default operand used to replace a null operand. - * @param ope (enum) The binary operator that is going to be used in the operation. - * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate - * error code - */ -gdf_error gdf_binary_operation_v_v_s_d(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def, gdf_binary_operator ope); - -/** - * @brief Binary operation function between two gdf_column structs. - * - * The function performs the binary operation of two gdf_column operands. A default - * scalar operand is used to replace an operand in the binary operation when such - * operand is null. - * - * Whether any gdf_column (vax or vay) is null, then it will be replaced with the - * default scalar operand value (def). In case both operands (vax and vay) are null, - * each of them will be replaced with the default scalar operand value. - * - * The valid field in the gdf_column output will be 1 (by bit) when two or three - * operands (vax, vay and def) are not null. Otherwise, it will be 0 (by bit). - * - * It is required to set in an appropriate manner the fields in the gdf_scalar and - * gdf_column structs due to that the binary operation will not be performed. - * - * @param out (gdf_column) Output of the operation. - * @param vax (gdf_column) First operand of the operation. - * @param vay (gdf_column) Second operand of the operation. - * @param def (gdf_scalar) Default operand used to replace a null operand. - * @param ope (enum) The binary operator that is going to be used in the operation. - * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate - * error code. - */ -gdf_error gdf_binary_operation_v_v_v_d(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope); /* arith */ diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 72c44b8ac259..22bfa7453800 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -73,78 +73,6 @@ R"***( } } } - - template - __global__ - void kernel_v_s_d(int size, - TypeOut* out_data, TypeVax* vax_data, gdf_data vay_data, gdf_data def_data, - uint32_t* out_valid, uint32_t* vax_valid, uint32_t vay_valid, uint32_t def_valid) { - int tid = threadIdx.x; - int blkid = blockIdx.x; - int blksz = blockDim.x; - int gridsz = gridDim.x; - - int start = tid + blkid * blksz; - int step = blksz * gridsz; - - for (int i=start; i> position) & 1; - TypeVax vax_data_aux = ((TypeVax)sel_vax * vax_data[i]) + - ((TypeVax)(sel_vax ^ 1) * (TypeVax)((TypeVal)def_data)); - - TypeVay vay_data_aux = ((TypeVay)(vay_valid & 1) * (TypeVay)vay_data) + - ((TypeVay)(vay_valid + 1) * (TypeVay)((TypeVal)def_data)); - - out_data[i] = TypeOpe::template operate(vax_data_aux, vay_data_aux); - - if ((i % warpSize) == 0) { - out_valid[index] = (vax_valid[index] & vay_valid) | - (vax_valid[index] & def_valid) | - (vay_valid & def_valid); - } - } - } - - template - __global__ - void kernel_v_v_d(int size, - TypeOut* out_data, TypeVax* vax_data, TypeVay* vay_data, gdf_data def_data, - uint32_t* out_valid, uint32_t* vax_valid, uint32_t* vay_valid, uint32_t def_valid) { - int tid = threadIdx.x; - int blkid = blockIdx.x; - int blksz = blockDim.x; - int gridsz = gridDim.x; - - int start = tid + blkid * blksz; - int step = blksz * gridsz; - - for (int i=start; i> position) & 1; - TypeVax vax_data_aux = ((TypeVax)sel_vax * vax_data[i]) + - ((TypeVax)(sel_vax ^ 1) * (TypeVax)((TypeVal)def_data)); - - uint32_t sel_vay = (is_vay_valid >> position) & 1; - TypeVay vay_data_aux = ((TypeVay)sel_vay * vay_data[i]) + - ((TypeVay)(sel_vay ^ 1) * (TypeVay)((TypeVal)def_data)); - - out_data[i] = TypeOpe::template operate(vax_data_aux, vay_data_aux); - - if ((i % warpSize) == 0) { - out_valid[index] = (vax_valid[index] & vay_valid[index]) | - (vax_valid[index] & def_valid) | - (vay_valid[index] & def_valid); - } - } - } )***"; } // namespace code diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index da23acd18fd6..00122b566c69 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -148,90 +148,19 @@ namespace jit { return GDF_SUCCESS; } - gdf_error binary_operation(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { - auto option_column = verify_column(out, vay); - if (!option_column) { - return option_column.get_gdf_error(); - } - auto option_scalar_vax = verify_scalar(vax); - if (!option_scalar_vax) { - return option_scalar_vax.get_gdf_error(); - } - auto option_scalar_def = verify_scalar(def); - if (!option_scalar_def) { - return option_scalar_def.get_gdf_error(); - } - - Launcher::launch().kernel("kernel_v_s_d") - .instantiate(ope, Operator::Type::Reverse, out, vay, vax, def) - .launch(out, vay, vax, def); - - return GDF_SUCCESS; - } - - gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def, gdf_binary_operator ope) { - auto option_column = verify_column(out, vax); - if (!option_column) { - return option_column.get_gdf_error(); - } - auto option_scalar_vax = verify_scalar(vay); - if (!option_scalar_vax) { - return option_scalar_vax.get_gdf_error(); - } - auto option_scalar_def = verify_scalar(def); - if (!option_scalar_def) { - return option_scalar_def.get_gdf_error(); - } - - Launcher::launch().kernel("kernel_v_s_d") - .instantiate(ope, Operator::Type::Direct, out, vax, vay, def) - .launch(out, vax, vay, def); - - return GDF_SUCCESS; - } - - gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { - auto option_column = verify_column(out, vax, vay); - if (!option_column) { - return option_column.get_gdf_error(); - } - auto option_scalar = verify_scalar(def); - if (!option_scalar) { - return option_scalar.get_gdf_error(); - } - - Launcher::launch().kernel("kernel_v_v_d") - .instantiate(ope, Operator::Type::Direct, out, vax, vay, def) - .launch(out, vax, vay, def); - - return GDF_SUCCESS; - } - } // namespace jit } // namespace binops } // namespace gdf -gdf_error gdf_binary_operation_v_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) { +gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) { return gdf::binops::jit::binary_operation(out, vax, vay, ope); } -gdf_error gdf_binary_operation_v_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) { +gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) { return gdf::binops::jit::binary_operation(out, vax, vay, ope); } -gdf_error gdf_binary_operation_v_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) { +gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) { return gdf::binops::jit::binary_operation(out, vax, vay, ope); } - -gdf_error gdf_binary_operation_v_s_v_d(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, vax, vay, def, ope); -} - -gdf_error gdf_binary_operation_v_v_s_d(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, vax, vay, def, ope); -} - -gdf_error gdf_binary_operation_v_v_v_d(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, vax, vay, def, ope); -} diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index 8a1811e454bc..990201d2062c 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -78,35 +78,6 @@ namespace jit { return GDF_SUCCESS; } - gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def) - { - uint32_t vay_valid = (vay->is_valid ? UINT32_MAX : 0); - uint32_t def_valid = (def->is_valid ? UINT32_MAX : 0); - - program.kernel(kernelName) - .instantiate(arguments) - .configure_1d_max_occupancy() - .launch(out->size, - out->data, vax->data, vay->data, def->data, - out->valid, vax->valid, vay_valid, def_valid); - - return GDF_SUCCESS; - } - - gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def) - { - uint32_t def_valid = (def->is_valid ? UINT32_MAX : 0); - - program.kernel(kernelName) - .instantiate(arguments) - .configure_1d_max_occupancy() - .launch(out->size, - out->data, vax->data, vay->data, def->data, - out->valid, vax->valid, vay->valid, def_valid); - - return GDF_SUCCESS; - } - } // namespace jit } // namespace binops } // namespace gdf diff --git a/cpp/tests/binary/integration/assert-binops.h b/cpp/tests/binary/integration/assert-binops.h index e906821a4d3e..b1c5dae99bd6 100644 --- a/cpp/tests/binary/integration/assert-binops.h +++ b/cpp/tests/binary/integration/assert-binops.h @@ -103,143 +103,6 @@ void ASSERT_BINOP(gdf::library::Vector& out, } } -template -void ASSERT_BINOP(gdf::library::Vector& out, - gdf::library::Scalar& vax, - gdf::library::Vector& vay, - gdf::library::Scalar& def, - TypeOpe&& ope) { - using ValidType = typename gdf::library::Vector::ValidType; - int ValidSize = gdf::library::Vector::ValidSize; - - ASSERT_TRUE(out.dataSize() == vay.dataSize()); - ASSERT_TRUE(out.validSize() == vay.validSize()); - - ValidType mask = 1; - int index_valid = 0; - for (int index = 0; index < out.dataSize(); ++index) { - if (!(index % ValidSize)) { - mask = 1; - index_valid = index / ValidSize; - } else { - mask <<= 1; - } - - TypeVay vax_aux = (TypeVay)vax; - if (!vax.isValid()) { - vax_aux = (TypeVay)((TypeVal) def.getValue()); - } - - TypeVax vay_aux = vay.data[index]; - if ((vay.valid[index_valid] & mask) == 0) { - vay_aux = (TypeVal) def.getValue(); - } - - ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax_aux, vay_aux))); - } - - uint32_t vax_valid = (vax.isValid() ? UINT32_MAX : 0); - uint32_t def_valid = (def.isValid() ? UINT32_MAX : 0); - ASSERT_TRUE(out.validSize() == vay.validSize()); - for (int index = 0; index < out.validSize(); ++index) { - uint32_t output = (vay.valid[index] & vax_valid) | - (vay.valid[index] & def_valid) | - (vax_valid & def_valid); - ASSERT_TRUE(out.valid[index] == output); - } -} - -template -void ASSERT_BINOP(gdf::library::Vector& out, - gdf::library::Vector& vax, - gdf::library::Scalar& vay, - gdf::library::Scalar& def, - TypeOpe&& ope) { - using ValidType = typename gdf::library::Vector::ValidType; - int ValidSize = gdf::library::Vector::ValidSize; - - ASSERT_TRUE(out.dataSize() == vax.dataSize()); - ASSERT_TRUE(out.validSize() == vax.validSize()); - - ValidType mask = 1; - int index_valid = 0; - for (int index = 0; index < out.dataSize(); ++index) { - if (!(index % ValidSize)) { - mask = 1; - index_valid = index / ValidSize; - } else { - mask <<= 1; - } - - TypeVax vax_aux = vax.data[index]; - if ((vax.valid[index_valid] & mask) == 0) { - vax_aux = (TypeVal) def.getValue(); - } - - TypeVay vay_aux = (TypeVay)vay; - if (!vay.isValid()) { - vay_aux = (TypeVay)((TypeVal) def.getValue()); - } - - ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax_aux, vay_aux))); - } - - uint32_t vay_valid = (vay.isValid() ? UINT32_MAX : 0); - uint32_t def_valid = (def.isValid() ? UINT32_MAX : 0); - ASSERT_TRUE(out.validSize() == vax.validSize()); - for (int index = 0; index < out.validSize(); ++index) { - uint32_t output = (vax.valid[index] & vay_valid) | - (vax.valid[index] & def_valid) | - (vay_valid & def_valid); - ASSERT_TRUE(out.valid[index] == output); - } -} - -template -void ASSERT_BINOP(gdf::library::Vector& out, - gdf::library::Vector& vax, - gdf::library::Vector& vay, - gdf::library::Scalar& def, - TypeOpe&& ope) { - using ValidType = typename gdf::library::Vector::ValidType; - int ValidSize = gdf::library::Vector::ValidSize; - - ASSERT_TRUE(out.dataSize() == vax.dataSize()); - ASSERT_TRUE(out.dataSize() == vay.dataSize()); - - ValidType mask = 1; - int index_valid = 0; - for (int index = 0; index < out.dataSize(); ++index) { - if (!(index % ValidSize)) { - mask = 1; - index_valid = index / ValidSize; - } else { - mask <<= 1; - } - - TypeVax vax_aux = vax.data[index]; - if ((vax.valid[index_valid] & mask) == 0) { - vax_aux = (TypeVax) def.getValue(); - } - - TypeVay vay_aux = vay.data[index]; - if ((vay.valid[index_valid] & mask) == 0) { - vay_aux = (TypeVay) def.getValue(); - } - - ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax_aux, vay_aux))); - } - - uint32_t def_valid = (def.isValid() ? UINT32_MAX : 0); - ASSERT_TRUE(out.validSize() == vax.validSize()); - ASSERT_TRUE(out.validSize() == vay.validSize()); - for (int index = 0; index < out.validSize(); ++index) { - ASSERT_TRUE(out.valid[index] == ((vax.valid[index] & vay.valid[index]) | - (vax.valid[index] & def_valid) | - (vay.valid[index] & def_valid))); - } -} - } // namespace binop } // namespace test } // namespace gdf diff --git a/cpp/tests/binary/integration/binary-operation-integration-test.cpp b/cpp/tests/binary/integration/binary-operation-integration-test.cpp index 7124f6f52a3b..56fd783eb4c8 100644 --- a/cpp/tests/binary/integration/binary-operation-integration-test.cpp +++ b/cpp/tests/binary/integration/binary-operation-integration-test.cpp @@ -51,7 +51,7 @@ TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_SI32_FP32_UI32) { vax.setValue(100); out.emplaceVector(vay.dataSize()); - auto result = gdf_binary_operation_v_s_v(out.column(), vax.scalar(), vay.column(), GDF_ADD); + auto result = gdf_binary_operation_s_v(out.column(), vax.scalar(), vay.column(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -75,7 +75,7 @@ TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_SI32_FP32_UI32) { vax.setValue(10000); out.emplaceVector(vay.dataSize()); - auto result = gdf_binary_operation_v_s_v(out.column(), vax.scalar(), vay.column(), GDF_SUB); + auto result = gdf_binary_operation_s_v(out.column(), vax.scalar(), vay.column(), GDF_SUB); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -99,7 +99,7 @@ TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_SI08_UI16_SI16) { vay.setValue(100); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -124,7 +124,7 @@ TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_UI32_FP64_SI08) { .rangeValid(false, 0, 4); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -133,115 +133,6 @@ TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_UI32_FP64_SI08) { } -TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_Default_SI32_SI16_UI64_SI64) { - using SI32 = gdf::library::GdfEnumType; - using SI16 = gdf::library::GdfEnumType; - using UI64 = gdf::library::GdfEnumType; - using SI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Scalar vax; - gdf::library::Vector vay; - gdf::library::Scalar def; - - vax.setValue(50); - vay.rangeData(0, 10000, 2) - .rangeValid(false, 0, 4); - def.setValue(1000); - out.emplaceVector(vay.dataSize()); - - auto result = gdf_binary_operation_v_s_v_d(out.column(), vax.scalar(), vay.column(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_Default_SI32_SI16_UI64_SI64) { - using SI32 = gdf::library::GdfEnumType; - using SI16 = gdf::library::GdfEnumType; - using UI64 = gdf::library::GdfEnumType; - using SI64 = gdf::library::GdfEnumType; - using SUB = gdf::library::operation::Sub; - - gdf::library::Vector out; - gdf::library::Scalar vax; - gdf::library::Vector vay; - gdf::library::Scalar def; - - vax.setValue(500); - vay.rangeData(0, 10000, 2) - .rangeValid(false, 0, 4); - def.setValue(1000); - out.emplaceVector(vay.dataSize()); - - auto result = gdf_binary_operation_v_s_v_d(out.column(), vax.scalar(), vay.column(), def.scalar(), GDF_SUB); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, SUB()); -} - - -TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_Default_FP32_SI16_UI08_UI32) { - using FP32 = gdf::library::GdfEnumType; - using SI16 = gdf::library::GdfEnumType; - using UI08 = gdf::library::GdfEnumType; - using UI32 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 30000, 3) - .rangeValid(false, 0, 4); - vay.setValue(50); - def.setValue(150); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_Default_FP64_SI32_UI32_UI16) { - using FP64 = gdf::library::GdfEnumType; - using SI32 = gdf::library::GdfEnumType; - using UI32 = gdf::library::GdfEnumType; - using UI16 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100000, 1) - .rangeValid(false, 0, 3); - vay.rangeData(0, 200000, 2) - .rangeValid(false, 0, 4); - def.setValue(150); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_UI64) { using UI64 = gdf::library::GdfEnumType; using SUB = gdf::library::operation::Sub; @@ -256,7 +147,7 @@ TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_UI64) { .rangeValid(false, 0, 3); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_SUB); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_SUB); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -279,7 +170,7 @@ TEST_F(BinaryOperationIntegrationTest, Mul_Vector_Vector_UI64) { .rangeValid(false, 0, 4); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MUL); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MUL); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -302,7 +193,7 @@ TEST_F(BinaryOperationIntegrationTest, Div_Vector_Vector_UI64) { .rangeValid(false, 0, 8); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_DIV); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_DIV); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -325,7 +216,7 @@ TEST_F(BinaryOperationIntegrationTest, TrueDiv_Vector_Vector_UI64) { .rangeValid(true, 0, 4); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_TRUE_DIV); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_TRUE_DIV); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -348,7 +239,7 @@ TEST_F(BinaryOperationIntegrationTest, FloorDiv_Vector_Vector_UI64) { .rangeValid(false, 0, 8); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_FLOOR_DIV); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_FLOOR_DIV); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -371,7 +262,7 @@ TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_UI64) { .rangeValid(false, 0, 5); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -394,7 +285,7 @@ TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP32) { .rangeValid(false, 0, 6); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -417,7 +308,7 @@ TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP64) { .rangeValid(false, 0, 4); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -440,7 +331,7 @@ TEST_F(BinaryOperationIntegrationTest, Pow_Vector_Vector_UI64) { .rangeValid(false, 0, 4); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_POW); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_POW); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); diff --git a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp index 52192d05dd3c..c52b0c90766b 100644 --- a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp +++ b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp @@ -53,7 +53,7 @@ TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_UI64_WithScalarOperandNull .setValid(false); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -76,7 +76,7 @@ TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_UI64_WithScalarOperandNotN .setValid(true); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -102,7 +102,7 @@ TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNull .setValid(false); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -125,7 +125,7 @@ TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNotN .setValid(true); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -151,7 +151,7 @@ TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_UI64) { .rangeValid(false, 0, 4); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -177,7 +177,7 @@ TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64) { .rangeValid(false, 0, 4); out.emplaceVector(vax.dataSize()); - auto result = gdf_binary_operation_v_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); out.readVector(); @@ -185,330 +185,6 @@ TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64) { ASSERT_BINOP(out, vax, vay, ADD()); } -/* - * Kernels v_v_s_d, using UI64 - * Output:Vector, OperandX:Vector, OperandY:Scalar, OperandDefault:Scalar - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithAllOperandsNotNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.setValue(222) - .setValid(true); - def.setValue(555) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithScalarOperandNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.setValue(1000) - .setValid(false); - def.setValue(500) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithDefaultOperandNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.setValue(250) - .setValid(true); - def.setValue(750) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_UI64_WithAllOperandsNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.setValue(500) - .setValid(false); - def.setValue(1000) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - -/* - * Kernels v_v_s_d, using FP32 - * Output:Vector, OperandX:Vector, OperandY:Scalar, OperandDefault:Scalar - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithAllOperandsNotNull) { - using FP32 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.setValue(222.0) - .setValid(true); - def.setValue(555.0) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithScalarOperandNull) { - using FP32 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.setValue(1000.0) - .setValid(false); - def.setValue(500.0) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithDefaultOperandNull) { - using FP32 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.setValue(250.0) - .setValid(true); - def.setValue(750.0) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP32_WithAllOperandsNull) { - using FP32 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.setValue(500.0) - .setValid(false); - def.setValue(1000.0) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_s_d(out.column(), vax.column(), vay.scalar(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - -/* - * Kernels v_v_v_d, using UI64 - * Output:Vector, OperandX:Vector, OperandY:Vector, OperandDefault:Scalar - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_Default_UI64_WithDefaultOperandNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.rangeData(0, 200, 2) - .rangeValid(false, 0, 4); - def.setValue(666) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_Default_UI64_WithDefaultOperandNotNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.rangeData(0, 200, 2) - .rangeValid(false, 0, 4); - def.setValue(222) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - -/* - * Kernels v_v_v_d, using FP64 - * Output:Vector, OperandX:Vector, OperandY:Vector, OperandDefault:Scalar - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_Default_FP64_WithDefaultOperandNull) { - using FP64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.rangeData(0, 200.0, 2.0) - .rangeValid(false, 0, 4); - def.setValue(555.0) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_Default_FP64_WithDefaultOperandNotNull) { - using FP64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; - gdf::library::Scalar def; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.rangeData(0, 200.0, 2.0) - .rangeValid(false, 0, 4); - def.setValue(555.0) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v_v_d(out.column(), vax.column(), vay.column(), def.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, def, ADD()); -} - } // namespace binop } // namespace test } // namespace gdf diff --git a/cpp/tests/binary/unit/binop-verify-input-test.cpp b/cpp/tests/binary/unit/binop-verify-input-test.cpp index 2d8acba1e195..8074fbbe95b6 100644 --- a/cpp/tests/binary/unit/binop-verify-input-test.cpp +++ b/cpp/tests/binary/unit/binop-verify-input-test.cpp @@ -17,7 +17,9 @@ #include "gtest/gtest.h" #include "tests/binary/util/scalar.h" -#include "tests/binary/util/vector.h" +#include "tests/utilities/cudf_test_utils.cuh" +#include +#include struct BinopVerifyInputTest : public ::testing::Test { BinopVerifyInputTest() { @@ -35,537 +37,276 @@ struct BinopVerifyInputTest : public ::testing::Test { TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.fillData(0, 0); + std::vector vector_out(0, 0); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); gdf::library::Scalar scalar; scalar.setValue(100); - auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.fillData(0, 0); + std::vector vector_vax(0, 0); + auto col_vax = create_gdf_column(vector_vax); gdf::library::Scalar scalar; scalar.setValue(100); - auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorNull) { - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); gdf::library::Scalar scalar; scalar.setValue(100); - auto result = gdf_binary_operation_v_v_s(nullptr, vector_vax.column(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(nullptr, col_vax.get(), scalar.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); gdf::library::Scalar scalar; scalar.setValue(100); - auto result = gdf_binary_operation_v_v_s(vector_out.column(), nullptr, scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(col_out.get(), nullptr, scalar.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); - auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), nullptr, GDF_ADD); + auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), nullptr, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - vector_out.column()->dtype = (gdf_dtype)100; + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); + col_out.get()->dtype = (gdf_dtype)100; - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); gdf::library::Scalar scalar; scalar.setValue(100); - auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - vector_vax.column()->dtype = (gdf_dtype)100; + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); + col_vax.get()->dtype = (gdf_dtype)100; gdf::library::Scalar scalar; scalar.setValue(100); - auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); gdf::library::Scalar scalar; scalar.setValue(100); scalar.scalar()->dtype = (gdf_dtype)100; - auto result = gdf_binary_operation_v_v_s(vector_out.column(), vector_vax.column(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.fillData(0, 0); + std::vector vector_out(0, 0); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); + std::vector vector_vay(10); + std::iota(vector_vay.begin(), vector_vay.end(), 1); + auto col_vay = create_gdf_column(vector_vay); - auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.fillData(0, 0); + std::vector vector_vax(0, 0); + auto col_vax = create_gdf_column(vector_vax); - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); + std::vector vector_vay(10); + std::iota(vector_vay.begin(), vector_vay.end(), 1); + auto col_vay = create_gdf_column(vector_vay); - auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); - gdf::library::Vector vector_vay; - vector_vay.fillData(0, 0); + std::vector vector_vay(0, 0); + auto col_vay = create_gdf_column(vector_vay); - auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorNull) { - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); + std::vector vector_vay(10); + std::iota(vector_vay.begin(), vector_vay.end(), 1); + auto col_vay = create_gdf_column(vector_vay); - auto result = gdf_binary_operation_v_v_v(nullptr, vector_vax.column(), vector_vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(nullptr, col_vax.get(), col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); + std::vector vector_vay(10); + std::iota(vector_vay.begin(), vector_vay.end(), 1); + auto col_vay = create_gdf_column(vector_vay); - auto result = gdf_binary_operation_v_v_v(vector_out.column(), nullptr, vector_vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), nullptr, col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); - auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), nullptr, GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), nullptr, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - vector_out.column()->dtype = (gdf_dtype)100; + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); + col_out.get()->dtype = (gdf_dtype)100; - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); + std::vector vector_vay(10); + std::iota(vector_vay.begin(), vector_vay.end(), 1); + auto col_vay = create_gdf_column(vector_vay); - auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - vector_vax.column()->dtype = (gdf_dtype)100; + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); + col_vax.get()->dtype = (gdf_dtype)100; - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); + std::vector vector_vay(10); + std::iota(vector_vay.begin(), vector_vay.end(), 1); + auto col_vay = create_gdf_column(vector_vay); - auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); + std::vector vector_out(10); + std::iota(vector_out.begin(), vector_out.end(), 1); + auto col_out = create_gdf_column(vector_out); - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); + std::vector vector_vax(10); + std::iota(vector_vax.begin(), vector_vax.end(), 1); + auto col_vax = create_gdf_column(vector_vax); - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - vector_vay.column()->dtype = (gdf_dtype)100; + std::vector vector_vay(10); + std::iota(vector_vay.begin(), vector_vay.end(), 1); + auto col_vay = create_gdf_column(vector_vay); + col_vay.get()->dtype = (gdf_dtype)100; - auto result = gdf_binary_operation_v_v_v(vector_out.column(), vector_vax.column(), vector_vay.column(), GDF_ADD); - ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOutputVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.fillData(0, 0); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Scalar scalar; - scalar.setValue(100); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.fillData(0, 0); - - gdf::library::Scalar scalar; - scalar.setValue(100); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOutputVectorNull) { - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Scalar scalar; - scalar.setValue(100); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(nullptr, vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_DATASET_EMPTY); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandVectorNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Scalar scalar; - scalar.setValue(100); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), nullptr, scalar.scalar(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_DATASET_EMPTY); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandScalarNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), nullptr, defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_DATASET_EMPTY); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOutputVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - vector_out.column()->dtype = (gdf_dtype)100; - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Scalar scalar; - scalar.setValue(100); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - vector_vax.column()->dtype = (gdf_dtype)100; - - gdf::library::Scalar scalar; - scalar.setValue(100); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); -} - - -TEST_F(BinopVerifyInputTest, Vector_Scalar_Default_ErrorOperandScalarType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Scalar scalar; - scalar.setValue(100); - scalar.scalar()->dtype = (gdf_dtype)100; - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_s_d(vector_out.column(), vector_vax.column(), scalar.scalar(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorOutputVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.fillData(0, 0); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorFirstOperandVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.fillData(0, 0); - - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorSecondOperandVectorZeroSize) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Vector vector_vay; - vector_vay.fillData(0, 0); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorOutputVectorNull) { - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(nullptr, vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_DATASET_EMPTY); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorFirstOperandVectorNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), nullptr, vector_vay.column(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_DATASET_EMPTY); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorSecondOperandVectorNull) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), nullptr, defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_DATASET_EMPTY); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorOutputVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - vector_out.column()->dtype = (gdf_dtype)100; - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorFirstOperandVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - vector_vax.column()->dtype = (gdf_dtype)100; - - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); -} - - -TEST_F(BinopVerifyInputTest, Vector_Vector_Default_ErrorSecondOperandVectorType) { - gdf::library::Vector vector_out; - vector_out.rangeData(1, 10, 1); - - gdf::library::Vector vector_vax; - vector_vax.rangeData(1, 10, 1); - - gdf::library::Vector vector_vay; - vector_vay.rangeData(1, 10, 1); - vector_vay.column()->dtype = (gdf_dtype)100; - - gdf::library::Scalar defvalue; - defvalue.setValue(100); - - auto result = gdf_binary_operation_v_v_v_d(vector_out.column(), vector_vax.column(), vector_vay.column(), defvalue.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } From c9791b11517328a39e96ab7c7255491cefe62504 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 13 Feb 2019 02:39:24 +0530 Subject: [PATCH 04/51] Refactored scalar implementation, added a test util to work with scalars. --- cpp/CMakeLists.txt | 1 - cpp/include/cudf/types.h | 26 +---- cpp/src/binary/jit/code/gdf-data.cpp | 85 -------------- cpp/src/binary/jit/code/kernel.cpp | 9 +- cpp/src/binary/jit/core/binop.cpp | 3 + cpp/src/binary/jit/core/launcher.cpp | 4 +- cpp/src/binary/jit/core/launcher.h | 2 +- cpp/tests/utilities/scalar_wrapper.cuh | 148 +++++++++++++++++++++++++ cpp/tests/utilities/tuple_vectors.h | 1 + 9 files changed, 159 insertions(+), 120 deletions(-) delete mode 100644 cpp/src/binary/jit/code/gdf-data.cpp create mode 100644 cpp/tests/utilities/scalar_wrapper.cuh diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 3145b6289bff..2b37fadf179a 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -189,7 +189,6 @@ add_library(cudf SHARED src/groupby/groupby.cu src/groupby/new_groupby.cu src/binary/binary_ops.cu - src/binary/jit/code/gdf-data.cpp src/binary/jit/code/kernel.cpp src/binary/jit/code/operation.cpp src/binary/jit/code/traits.cpp diff --git a/cpp/include/cudf/types.h b/cpp/include/cudf/types.h index d498ae73bedb..aeee1c400bc9 100644 --- a/cpp/include/cudf/types.h +++ b/cpp/include/cudf/types.h @@ -35,29 +35,6 @@ typedef enum { } gdf_dtype; -/** - * @union gdf_data - * @brief Union used for scalar type. - * It stores a unique value for scalar type. - * It has a direct relationship with the gdf_dtype. - */ -typedef union { - int8_t si08; /**< GDF_INT8 */ - int16_t si16; /**< GDF_INT16 */ - int32_t si32; /**< GDF_INT32 */ - int64_t si64; /**< GDF_INT64 */ - uint8_t ui08; /**< GDF_UINT8 */ - uint16_t ui16; /**< GDF_UINT16 */ - uint32_t ui32; /**< GDF_UINT32 */ - uint64_t ui64; /**< GDF_UINT64 */ - float fp32; /**< GDF_FLOAT32 */ - double fp64; /**< GDF_FLOAT64 */ - int32_t dt32; /**< GDF_DATE32 */ - int64_t dt64; /**< GDF_DATE64 */ - int64_t tmst; /**< GDF_TIMESTAMP */ -} gdf_data; - - /* --------------------------------------------------------------------------*/ /** * @Synopsis These are all possible gdf error codes that can be returned from @@ -124,9 +101,8 @@ typedef struct { * @var is_valid A boolean that represents whether the scalar is null. */ typedef struct { - gdf_data data; + void* data; gdf_dtype dtype; - bool is_valid; } gdf_scalar; diff --git a/cpp/src/binary/jit/code/gdf-data.cpp b/cpp/src/binary/jit/code/gdf-data.cpp deleted file mode 100644 index bdc65a225180..000000000000 --- a/cpp/src/binary/jit/code/gdf-data.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2018-2019 BlazingDB, Inc. - * Copyright 2018 Christian Noboa Mardini - * - * 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. - */ - -namespace gdf { -namespace binops { -namespace jit { -namespace code { - -const char* gdf_data = -R"***( -#pragma once - - union gdf_data { - int8_t si08; - int16_t si16; - int32_t si32; - int64_t si64; - uint8_t ui08; - uint16_t ui16; - uint32_t ui32; - uint64_t ui64; - float fp32; - double fp64; - - operator int8_t() const { - return si08; - } - - operator int16_t() const { - return si16; - } - - operator int32_t() const { - return si32; - } - - operator int64_t() const { - return si64; - } - - operator uint8_t() const { - return ui08; - } - - operator uint16_t() const { - return ui16; - } - - operator uint32_t() const { - return ui32; - } - - operator uint64_t() const { - return ui64; - } - - operator float() const { - return fp32; - } - - operator double() const { - return fp64; - } - }; - -)***"; - -} // namespace code -} // namespace jit -} // namespace binops -} // namespace gdf diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 22bfa7453800..95ae1212129b 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -26,13 +26,12 @@ R"***( #include #include "traits.h" #include "operation.h" - #include "gdf_data.h" template __global__ void kernel_v_s(int size, - TypeOut* out_data, TypeVax* vax_data, gdf_data vay_data, - uint32_t* out_valid, uint32_t* vax_valid, uint32_t vay_valid) { + TypeOut* out_data, TypeVax* vax_data, TypeVay* vay_data, + uint32_t* out_valid, uint32_t* vax_valid) { int tid = threadIdx.x; int blkid = blockIdx.x; int blksz = blockDim.x; @@ -42,11 +41,11 @@ R"***( int step = blksz * gridsz; for (int i=start; i(vax_data[i], (TypeVay)vay_data); + out_data[i] = TypeOpe::template operate(vax_data[i], vay_data[0]); if ((i % warpSize) == 0) { int index = i / warpSize; - out_valid[index] = vax_valid[index] & vay_valid; + out_valid[index] = vax_valid[index]; } } } diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index 00122b566c69..3231157f9b41 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -45,6 +45,9 @@ namespace jit { if (scalar == nullptr) { return Option(false, GDF_DATASET_EMPTY); } + if (scalar->data == nullptr) { + return Option(false, GDF_DATASET_EMPTY); + } if ((scalar->dtype <= GDF_invalid) || (N_GDF_TYPES <= scalar->dtype)) { return Option(false, GDF_UNSUPPORTED_DTYPE); } diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index 990201d2062c..096e1b46b18d 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -55,14 +55,12 @@ namespace jit { } gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay) { - uint32_t vay_valid = (vay->is_valid ? UINT32_MAX : 0); - program.kernel(kernelName.c_str()) .instantiate(arguments) .configure_1d_max_occupancy() .launch(out->size, out->data, vax->data, vay->data, - out->valid, vax->valid, vay_valid); + out->valid, vax->valid); return GDF_SUCCESS; } diff --git a/cpp/src/binary/jit/core/launcher.h b/cpp/src/binary/jit/core/launcher.h index 36774d39bbf9..187d6320ce35 100644 --- a/cpp/src/binary/jit/core/launcher.h +++ b/cpp/src/binary/jit/core/launcher.h @@ -66,7 +66,7 @@ namespace jit { private: std::vector compilerFlags { "-std=c++14" }; - std::vector headersName { "operation.h" , "traits.h" , "gdf_data.h" }; + std::vector headersName { "operation.h" , "traits.h" }; private: jitify::Program program; diff --git a/cpp/tests/utilities/scalar_wrapper.cuh b/cpp/tests/utilities/scalar_wrapper.cuh new file mode 100644 index 000000000000..3e62917c787c --- /dev/null +++ b/cpp/tests/utilities/scalar_wrapper.cuh @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. + * + * 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 SCALAR_WRAPPER_H +#define SCALAR_WRAPPER_H + +#include +#include +#include +#include "cudf.h" +#include "cudf_test_utils.cuh" +#include "rmm/rmm.h" +#include "utilities/bit_util.cuh" +#include "utilities/type_dispatcher.hpp" + +#ifndef CUDA_RT_CALL +#define CUDA_RT_CALL(call) \ + do { \ + cudaError_t cudaStatus = (call); \ + if (cudaSuccess != cudaStatus) { \ + fprintf(stderr, \ + "ERROR: CUDA RT call \"%s\" in line %d of file %s failed with " \ + "%s (%d).\n", \ + #call, __LINE__, __FILE__, cudaGetErrorString(cudaStatus), \ + cudaStatus); \ + exit(1); \ + } \ + } while (0) +#endif + +namespace cudf { +namespace test { + +/**---------------------------------------------------------------------------* + * @brief Wrapper for a gdf_scalar used for unit testing. + * + * An abstraction on top of a gdf_scalar that provides functionality for + * allocating, intiailizing, and otherwise managing gdf_scalar's for passing to + * libcudf APIs in unit testing. + * + * @tparam ColumnType The underlying data type of the scalar + *---------------------------------------------------------------------------**/ +template +struct scalar_wrapper { + /**---------------------------------------------------------------------------* + * @brief Construct a new scalar wrapper object + * + * Constructs a scalar_wrapper using a ref value for the host data. + * + * @param host_data The value to use for the scalar + *---------------------------------------------------------------------------**/ + scalar_wrapper(ScalarType const& host_data) { + initialize_with_host_data(host_data); + } + + ~scalar_wrapper() { + RMM_FREE(the_scalar.data, 0); + } + + /**---------------------------------------------------------------------------* + * @brief Returns a pointer to the underlying gdf_scalar. + * + *---------------------------------------------------------------------------**/ + gdf_scalar* get() { return &the_scalar; } + gdf_scalar const* get() const { return &the_scalar; } + + /**---------------------------------------------------------------------------* + * @brief Copies the underying gdf_scalar's data to the host. + * + * Returns the value of the scalar + * + *---------------------------------------------------------------------------**/ + auto to_host() const { + ScalarType host_data; + + if (nullptr != the_scalar.data) { + CUDA_RT_CALL(cudaMemcpy(&host_data, the_scalar.data, + sizeof(ScalarType), + cudaMemcpyDeviceToHost)); + } + + return host_data; + } + + /**---------------------------------------------------------------------------* + * @brief Prints the value of the underlying gdf_scalar. + * + *---------------------------------------------------------------------------**/ + void print() const { + ScalarType value = this->to_host(); + std::cout << value << std::endl; + } + + /**---------------------------------------------------------------------------* + * @brief Compares if another scalar_wrapper is equal to this wrapper. + * + * @param rhs The other scalar_wrapper to check for equality + * @return true The two scalars are equal + * @return false The two scalars are not equal + *---------------------------------------------------------------------------**/ + bool operator==(scalar_wrapper const& rhs) const { + if (the_scalar.dtype != rhs.the_scalar.dtype) return false; + + if (!(the_scalar.data && rhs.the_scalar.data)) + return false; // if one is null but not both + + return (this->to_host() == rhs.to_host()); + } + + private: + /**---------------------------------------------------------------------------* + * @brief Allocates and initializes the underyling gdf_scalar with host data. + * + * Creates a gdf_scalar and copies data from the host for it's data. + * Sets the corresponding dtype based on the scalar_wrapper's ColumnType. + * + * @param host_data The host data to copy to device for the scalar's data + *---------------------------------------------------------------------------**/ + void initialize_with_host_data(ScalarType const& host_data) { + // Allocate device storage for gdf_scalar and copy contents from host_data + RMM_ALLOC(&(the_scalar.data), sizeof(ScalarType), 0); + CUDA_RT_CALL(cudaMemcpy(the_scalar.data, &host_data, + sizeof(ScalarType), + cudaMemcpyHostToDevice)); + + // Fill the gdf_scalar members + the_scalar.dtype = cudf::type_to_gdf_dtype::value; + } + + gdf_scalar the_scalar; +}; + +} // namespace test +} // namespace cudf +#endif diff --git a/cpp/tests/utilities/tuple_vectors.h b/cpp/tests/utilities/tuple_vectors.h index 25d4aebcfe10..2bb150404ecb 100644 --- a/cpp/tests/utilities/tuple_vectors.h +++ b/cpp/tests/utilities/tuple_vectors.h @@ -20,6 +20,7 @@ #include #include #include +#include template using VTuple = std::tuple...>; From 9017317d19baf047a95605f03e7dc1c10e916550 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 14 Feb 2019 01:59:12 +0530 Subject: [PATCH 05/51] The tests are all clean now and only use our own utils. --- cpp/src/binary/jit/code/code.h | 1 - cpp/src/binary/jit/core/launcher.cpp | 4 - cpp/tests/CMakeLists.txt | 4 +- cpp/tests/binary/integration/assert-binops.h | 128 ++++--- .../binary-operation-integration-test.cpp | 324 +++++++----------- .../binary-operation-operands-null-test.cpp | 190 ---------- .../binary/unit/binop-verify-input-test.cpp | 284 ++++++++------- cpp/tests/binary/util/field.h | 113 ------ cpp/tests/binary/util/operation.h | 6 +- cpp/tests/binary/util/scalar.h | 108 ------ cpp/tests/binary/util/types.cpp | 137 -------- cpp/tests/binary/util/types.h | 199 ----------- cpp/tests/binary/util/vector.h | 185 ---------- cpp/tests/utilities/scalar_wrapper.cuh | 21 +- 14 files changed, 366 insertions(+), 1338 deletions(-) delete mode 100644 cpp/tests/binary/integration/binary-operation-operands-null-test.cpp delete mode 100644 cpp/tests/binary/util/field.h delete mode 100644 cpp/tests/binary/util/scalar.h delete mode 100644 cpp/tests/binary/util/types.cpp delete mode 100644 cpp/tests/binary/util/types.h delete mode 100644 cpp/tests/binary/util/vector.h diff --git a/cpp/src/binary/jit/code/code.h b/cpp/src/binary/jit/code/code.h index e714bae027eb..1ca7d8369de5 100644 --- a/cpp/src/binary/jit/code/code.h +++ b/cpp/src/binary/jit/code/code.h @@ -26,7 +26,6 @@ namespace code { extern const char* kernel; extern const char* traits; extern const char* operation; - extern const char* gdf_data; } } diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index 096e1b46b18d..934992b83baf 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -34,10 +34,6 @@ namespace jit { stream << code::traits; return &stream; } - if (filename == "gdf_data.h") { - stream << code::gdf_data; - return &stream; - } return nullptr; } diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 4a8e0aa22354..fa948fdd4933 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -163,10 +163,8 @@ ConfigureTest(UNARY_TEST "${UNARY_TEST_SRC}") # - binary tests ---------------------------------------------------------------------------------- set(BINARY_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/binary/util/types.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/binary/unit/binop-verify-input-test.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/binary/integration/binary-operation-integration-test.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/binary/integration/binary-operation-operands-null-test.cpp") + "${CMAKE_CURRENT_SOURCE_DIR}/binary/integration/binary-operation-integration-test.cpp") ConfigureTest(BINARY_TEST "${BINARY_TEST_SRC}") diff --git a/cpp/tests/binary/integration/assert-binops.h b/cpp/tests/binary/integration/assert-binops.h index b1c5dae99bd6..8ddd48af2383 100644 --- a/cpp/tests/binary/integration/assert-binops.h +++ b/cpp/tests/binary/integration/assert-binops.h @@ -18,64 +18,91 @@ #ifndef GDF_TESTS_BINARY_OPERATION_INTEGRATION_ASSERT_BINOPS_H #define GDF_TESTS_BINARY_OPERATION_INTEGRATION_ASSERT_BINOPS_H -#include "gtest/gtest.h" -#include "tests/binary/util/scalar.h" -#include "tests/binary/util/vector.h" #include "tests/binary/util/operation.h" +#include "tests/utilities/column_wrapper.cuh" +#include "tests/utilities/scalar_wrapper.cuh" +#include "gtest/gtest.h" namespace gdf { namespace test { namespace binop { template -void ASSERT_BINOP(gdf::library::Vector& out, - gdf::library::Scalar& vax, - gdf::library::Vector& vay, +void ASSERT_BINOP(cudf::test::column_wrapper& out, + cudf::test::scalar_wrapper& vax, + cudf::test::column_wrapper& vay, TypeOpe&& ope) { - ASSERT_TRUE(out.dataSize() == vay.dataSize()); - for (int index = 0; index < out.dataSize(); ++index) { - ASSERT_TRUE(out.data[index] == (TypeOut)(ope((TypeVay) vax.getValue(), vay.data[index]))); + auto vax_h = vax.to_host(); + auto vay_h = vay.to_host(); + auto vay_data = std::get<0>(vay_h); + auto out_h = out.to_host(); + auto out_data = std::get<0>(out_h); + + ASSERT_TRUE(out_data.size() == vay_data.size()); + for (int index = 0; index < out_data.size(); ++index) { + ASSERT_TRUE(out_data[index] == (TypeOut)(ope(vax_h, vay_data[index]))); } - uint32_t vax_valid = (vax.isValid() ? UINT32_MAX : 0); - ASSERT_TRUE(out.validSize() == vay.validSize()); - for (int index = 0; index < out.validSize(); ++index) { - ASSERT_TRUE(out.valid[index] == (vax_valid & vay.valid[index])); + auto vay_valid = std::get<1>(vay_h); + auto out_valid = std::get<1>(out_h); + + ASSERT_TRUE(out_valid.size() == vay_valid.size()); + for (int index = 0; index < out_valid.size(); ++index) { + ASSERT_TRUE(out_valid[index] == vay_valid[index]); } } template -void ASSERT_BINOP(gdf::library::Vector& out, - gdf::library::Vector& vax, - gdf::library::Scalar& vay, +void ASSERT_BINOP(cudf::test::column_wrapper& out, + cudf::test::column_wrapper& vax, + cudf::test::scalar_wrapper& vay, TypeOpe&& ope) { - ASSERT_TRUE(out.dataSize() == vax.dataSize()); - for (int index = 0; index < out.dataSize(); ++index) { - ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax.data[index], (TypeVay) vay.getValue()))); + auto vay_h = vay.to_host(); + auto vax_h = vax.to_host(); + auto vax_data = std::get<0>(vax_h); + auto out_h = out.to_host(); + auto out_data = std::get<0>(out_h); + + ASSERT_TRUE(out_data.size() == vax_data.size()); + for (int index = 0; index < out_data.size(); ++index) { + ASSERT_TRUE(out_data[index] == (TypeOut)(ope(vax_data[index], vay_h))); } - uint32_t vay_valid = (vay.isValid() ? UINT32_MAX : 0); - ASSERT_TRUE(out.validSize() == vax.validSize()); - for (int index = 0; index < out.validSize(); ++index) { - ASSERT_TRUE(out.valid[index] == (vax.valid[index] & vay_valid)); + auto vax_valid = std::get<1>(vax_h); + auto out_valid = std::get<1>(out_h); + + ASSERT_TRUE(out_valid.size() == vax_valid.size()); + for (int index = 0; index < out_valid.size(); ++index) { + ASSERT_TRUE(out_valid[index] == (vax_valid[index])); } } template -void ASSERT_BINOP(gdf::library::Vector& out, - gdf::library::Vector& vax, - gdf::library::Vector& vay, +void ASSERT_BINOP(cudf::test::column_wrapper& out, + cudf::test::column_wrapper& vax, + cudf::test::column_wrapper& vay, TypeOpe&& ope) { - ASSERT_TRUE(out.dataSize() == vax.dataSize()); - ASSERT_TRUE(out.dataSize() == vay.dataSize()); - for (int index = 0; index < out.dataSize(); ++index) { - ASSERT_TRUE(out.data[index] == (TypeOut)(ope(vax.data[index], vay.data[index]))); + auto vax_h = vax.to_host(); + auto vax_data = std::get<0>(vax_h); + auto vay_h = vay.to_host(); + auto vay_data = std::get<0>(vay_h); + auto out_h = out.to_host(); + auto out_data = std::get<0>(out_h); + + ASSERT_TRUE(out_data.size() == vax_data.size()); + ASSERT_TRUE(out_data.size() == vay_data.size()); + for (int index = 0; index < out_data.size(); ++index) { + ASSERT_TRUE(out_data[index] == (TypeOut)(ope(vax_data[index], vay_data[index]))); } - ASSERT_TRUE(out.validSize() == vax.validSize()); - ASSERT_TRUE(out.validSize() == vay.validSize()); - for (int index = 0; index < out.validSize(); ++index) { - ASSERT_TRUE(out.valid[index] == vax.valid[index] | vay.valid[index]); + auto vax_valid = std::get<1>(vax_h); + auto vay_valid = std::get<1>(vay_h); + auto out_valid = std::get<1>(out_h); + + ASSERT_TRUE(out_valid.size() == vax_valid.size()); + ASSERT_TRUE(out_valid.size() == vay_valid.size()); + for (int index = 0; index < out_valid.size(); ++index) { + ASSERT_TRUE(out_valid[index] == vax_valid[index] | vay_valid[index]); } } @@ -85,21 +112,32 @@ void ASSERT_BINOP(gdf::library::Vector& out, * The pow function has 2 (full range) maximum ulp error. */ template -void ASSERT_BINOP(gdf::library::Vector& out, - gdf::library::Vector& vax, - gdf::library::Vector& vay, +void ASSERT_BINOP(cudf::test::column_wrapper& out, + cudf::test::column_wrapper& vax, + cudf::test::column_wrapper& vay, gdf::library::operation::Pow&& ope) { + auto vax_h = vax.to_host(); + auto vax_data = std::get<0>(vax_h); + auto vay_h = vay.to_host(); + auto vay_data = std::get<0>(vay_h); + auto out_h = out.to_host(); + auto out_data = std::get<0>(out_h); + const int ULP = 2.0; - ASSERT_TRUE(out.dataSize() == vax.dataSize()); - ASSERT_TRUE(out.dataSize() == vay.dataSize()); - for (int index = 0; index < out.dataSize(); ++index) { - ASSERT_TRUE(abs(out.data[index] - (TypeOut)(ope(vax.data[index], vay.data[index]))) < ULP); + ASSERT_TRUE(out_data.size() == vax_data.size()); + ASSERT_TRUE(out_data.size() == vay_data.size()); + for (int index = 0; index < out_data.size(); ++index) { + ASSERT_TRUE(abs(out_data[index] - (TypeOut)(ope(vax_data[index], vay_data[index]))) < ULP); } - ASSERT_TRUE(out.validSize() == vax.validSize()); - ASSERT_TRUE(out.validSize() == vay.validSize()); - for (int index = 0; index < out.validSize(); ++index) { - ASSERT_TRUE(out.valid[index] == (vax.valid[index] & vay.valid[index])); + auto vax_valid = std::get<1>(vax_h); + auto vay_valid = std::get<1>(vay_h); + auto out_valid = std::get<1>(out_h); + + ASSERT_TRUE(out_valid.size() == vax_valid.size()); + ASSERT_TRUE(out_valid.size() == vay_valid.size()); + for (int index = 0; index < out_valid.size(); ++index) { + ASSERT_TRUE(out_valid[index] == (vax_valid[index] & vay_valid[index])); } } diff --git a/cpp/tests/binary/integration/binary-operation-integration-test.cpp b/cpp/tests/binary/integration/binary-operation-integration-test.cpp index 56fd783eb4c8..493e33821287 100644 --- a/cpp/tests/binary/integration/binary-operation-integration-test.cpp +++ b/cpp/tests/binary/integration/binary-operation-integration-test.cpp @@ -36,306 +36,230 @@ struct BinaryOperationIntegrationTest : public ::testing::Test { }; -TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_SI32_FP32_UI32) { - using SI32 = gdf::library::GdfEnumType; - using FP32 = gdf::library::GdfEnumType; - using UI32 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Scalar vax; - gdf::library::Vector vay; - - vay.rangeData(0, 100000, 1) - .rangeValid(false, 0, 4); - vax.setValue(100); - out.emplaceVector(vay.dataSize()); - - auto result = gdf_binary_operation_s_v(out.column(), vax.scalar(), vay.column(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); +TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_SI32_FP32_SI64) { + using ADD = gdf::library::operation::Add; + + auto vax = cudf::test::scalar_wrapper{100}; + auto vay = cudf::test::column_wrapper{100000, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{vay.get()->size, true}; - out.readVector(); + auto result = gdf_binary_operation_s_v(out.get(), vax.get(), vay.get(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); ASSERT_BINOP(out, vax, vay, ADD()); } -TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_SI32_FP32_UI32) { - using SI32 = gdf::library::GdfEnumType; - using FP32 = gdf::library::GdfEnumType; - using UI32 = gdf::library::GdfEnumType; - using SUB = gdf::library::operation::Sub; - - gdf::library::Vector out; - gdf::library::Scalar vax; - gdf::library::Vector vay; +TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_SI32_FP32_SI64) { + using SUB = gdf::library::operation::Sub; - vay.rangeData(0, 100000, 1) - .rangeValid(false, 0, 4); - vax.setValue(10000); - out.emplaceVector(vay.dataSize()); + auto vax = cudf::test::scalar_wrapper{10000}; + auto vay = cudf::test::column_wrapper{100000, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{vay.get()->size, true}; - auto result = gdf_binary_operation_s_v(out.column(), vax.scalar(), vay.column(), GDF_SUB); + auto result = gdf_binary_operation_s_v(out.get(), vax.get(), vay.get(), GDF_SUB); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, SUB()); } -TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_SI08_UI16_SI16) { - using SI08 = gdf::library::GdfEnumType; - using UI16 = gdf::library::GdfEnumType; - using SI16 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; +TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_SI08_SI16_SI32) { + using ADD = gdf::library::operation::Add; - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 6); - vay.setValue(100); - out.emplaceVector(vax.dataSize()); + auto vax = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 6 > 0);}}; + auto vay = cudf::test::scalar_wrapper{100}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(out.get(), vax.get(), vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, ADD()); } -TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_UI32_FP64_SI08) { - using UI32 = gdf::library::GdfEnumType; - using FP64 = gdf::library::GdfEnumType; - using SI08 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; +TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_SI32_FP64_SI08) { + using ADD = gdf::library::operation::Add; - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; + auto vax = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row * 2.0;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto vay = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row * 1;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - vax.rangeData(0.0, 200.0, 2.0) - .rangeValid(false, 0, 3); - vay.rangeData(0, 100, 1) - .rangeValid(false, 0, 4); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, ADD()); } -TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using SUB = gdf::library::operation::Sub; +TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_SI64) { + using SUB = gdf::library::operation::Sub; - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; + auto vax = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 100000 + row * 2;}, + [](gdf_size_type row) {return (row % 4 == 0);}}; + auto vay = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 50000 + row;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - vax.rangeData(100000, 200000, 2) - .rangeValid(true, 0, 4); - vay.rangeData(50000, 100000, 1) - .rangeValid(false, 0, 3); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_SUB); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_SUB); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, SUB()); } -TEST_F(BinaryOperationIntegrationTest, Mul_Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using MUL = gdf::library::operation::Mul; +TEST_F(BinaryOperationIntegrationTest, Mul_Vector_Vector_SI64) { + using MUL = gdf::library::operation::Mul; - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; + auto vax = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 100000 + row * 2;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto vay = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 50000 + row;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - vax.rangeData(100000, 200000, 2) - .rangeValid(false, 0 , 3); - vay.rangeData(50000, 100000, 1) - .rangeValid(false, 0, 4); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MUL); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MUL); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, MUL()); } -TEST_F(BinaryOperationIntegrationTest, Div_Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using DIV = gdf::library::operation::Div; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; +TEST_F(BinaryOperationIntegrationTest, Div_Vector_Vector_SI64) { + using DIV = gdf::library::operation::Div; - vax.rangeData(100000, 200000, 2) - .rangeValid(false, 0, 6); - vay.rangeData(50000, 100000, 1) - .rangeValid(false, 0, 8); - out.emplaceVector(vax.dataSize()); + auto vax = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 100000 + row * 2;}, + [](gdf_size_type row) {return (row % 6 > 0);}}; + auto vay = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 50000 + row;}, + [](gdf_size_type row) {return (row % 8 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_DIV); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_DIV); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, DIV()); } -TEST_F(BinaryOperationIntegrationTest, TrueDiv_Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using TRUEDIV = gdf::library::operation::TrueDiv; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; +TEST_F(BinaryOperationIntegrationTest, TrueDiv_Vector_Vector_SI64) { + using TRUEDIV = gdf::library::operation::TrueDiv; - vax.rangeData(100000, 200000, 2) - .rangeValid(true, 0, 3); - vay.rangeData(50000, 100000, 1) - .rangeValid(true, 0, 4); - out.emplaceVector(vax.dataSize()); + auto vax = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 100000 + row * 2;}, + [](gdf_size_type row) {return (row % 3 == 0);}}; + auto vay = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 50000 + row;}, + [](gdf_size_type row) {return (row % 4 == 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_TRUE_DIV); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_TRUE_DIV); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, TRUEDIV()); } -TEST_F(BinaryOperationIntegrationTest, FloorDiv_Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using FLOORDIV = gdf::library::operation::FloorDiv; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; +TEST_F(BinaryOperationIntegrationTest, FloorDiv_Vector_Vector_SI64) { + using FLOORDIV = gdf::library::operation::FloorDiv; - vax.rangeData(100000, 200000, 2) - .rangeValid(false, 0, 6); - vay.rangeData(50000, 100000, 1) - .rangeValid(false, 0, 8); - out.emplaceVector(vax.dataSize()); + auto vax = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 100000 + row * 2;}, + [](gdf_size_type row) {return (row % 6 > 0);}}; + auto vay = cudf::test::column_wrapper{50000, + [](gdf_size_type row) {return 50000 + row;}, + [](gdf_size_type row) {return (row % 8 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_FLOOR_DIV); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_FLOOR_DIV); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, FLOORDIV()); } -TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using MOD = gdf::library::operation::Mod; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; +TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_SI64) { + using MOD = gdf::library::operation::Mod; - vax.rangeData(120, 220, 2) - .rangeValid(false, 0, 3); - vay.rangeData(50, 100, 1) - .rangeValid(false, 0, 5); - out.emplaceVector(vax.dataSize()); + auto vax = cudf::test::column_wrapper{50, + [](gdf_size_type row) {return 120 + row * 2;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto vay = cudf::test::column_wrapper{50, + [](gdf_size_type row) {return 50 + row;}, + [](gdf_size_type row) {return (row % 5 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, MOD()); } TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP32) { - using FP32 = gdf::library::GdfEnumType; - using MOD = gdf::library::operation::Mod; + using MOD = gdf::library::operation::Mod; - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; + auto vax = cudf::test::column_wrapper{50, + [](gdf_size_type row) {return 120 + row * 2;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto vay = cudf::test::column_wrapper{50, + [](gdf_size_type row) {return 50 + row;}, + [](gdf_size_type row) {return (row % 6 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - vax.rangeData(120, 220, 2) - .rangeValid(false, 0, 4); - vay.rangeData(50, 100, 1) - .rangeValid(false, 0, 6); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, MOD()); } TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP64) { - using FP64 = gdf::library::GdfEnumType; - using MOD = gdf::library::operation::Mod; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; + using MOD = gdf::library::operation::Mod; - vax.rangeData(120, 220, 2) - .rangeValid(true, 0, 3); - vay.rangeData(50, 100, 1) - .rangeValid(false, 0, 4); - out.emplaceVector(vax.dataSize()); + auto vax = cudf::test::column_wrapper{50, + [](gdf_size_type row) {return 120 + row * 2;}, + [](gdf_size_type row) {return (row % 3 == 0);}}; + auto vay = cudf::test::column_wrapper{50, + [](gdf_size_type row) {return 50 + row;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, MOD()); } -TEST_F(BinaryOperationIntegrationTest, Pow_Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using POW = gdf::library::operation::Pow; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; +TEST_F(BinaryOperationIntegrationTest, Pow_Vector_Vector_SI64) { + using POW = gdf::library::operation::Pow; - vax.rangeData(0, 500, 1) - .rangeValid(false, 0, 6); - vay.fillData(500, 2) - .rangeValid(false, 0, 4); - out.emplaceVector(vax.dataSize()); + auto vax = cudf::test::column_wrapper{500, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 6 > 0);}}; + auto vay = cudf::test::column_wrapper{500, + [](gdf_size_type row) {return 2;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{vax.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_POW); + auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_POW); ASSERT_TRUE(result == GDF_SUCCESS); - out.readVector(); - ASSERT_BINOP(out, vax, vay, POW()); } diff --git a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp deleted file mode 100644 index c52b0c90766b..000000000000 --- a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2018-2019 BlazingDB, Inc. - * Copyright 2018 Christian Noboa Mardini - * - * 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 "tests/binary/integration/assert-binops.h" - -namespace gdf { -namespace test { -namespace binop { - -struct BinaryOperationOperandsNullTest : public ::testing::Test { - BinaryOperationOperandsNullTest() { - } - - virtual ~BinaryOperationOperandsNullTest() { - } - - virtual void SetUp() { - } - - virtual void TearDown() { - } -}; - -/* - * Kernels v_v_s, using UI64 - * Output:Vector, OperandX:Vector, OperandY:Scalar - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_UI64_WithScalarOperandNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.setValue(500) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_UI64_WithScalarOperandNotNull) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.setValue(500) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, ADD()); -} - -/* - * Kernels v_v_s, using FP64 - * Output:Vector, OperandX:Vector, OperandY:Scalar - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNull) { - using FP64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.setValue(500.0) - .setValid(false); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, ADD()); -} - - -TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNotNull) { - using FP64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Scalar vay; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.setValue(500.0) - .setValid(true); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_s(out.column(), vax.column(), vay.scalar(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, ADD()); -} - -/* - * Kernels v_v_v, using UI64 - * Output:Vector, OperandX:Vector, OperandY:Vector - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_UI64) { - using UI64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; - - vax.rangeData(0, 100, 1) - .rangeValid(false, 0, 3); - vay.rangeData(0, 200, 2) - .rangeValid(false, 0, 4); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, ADD()); -} - -/* - * Kernels v_v_v, using FP64 - * Output:Vector, OperandX:Vector, OperandY:Vector - */ -TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64) { - using FP64 = gdf::library::GdfEnumType; - using ADD = gdf::library::operation::Add; - - gdf::library::Vector out; - gdf::library::Vector vax; - gdf::library::Vector vay; - - vax.rangeData(0, 100.0, 1.0) - .rangeValid(false, 0, 3); - vay.rangeData(0, 200.0, 2.0) - .rangeValid(false, 0, 4); - out.emplaceVector(vax.dataSize()); - - auto result = gdf_binary_operation_v_v(out.column(), vax.column(), vay.column(), GDF_ADD); - ASSERT_TRUE(result == GDF_SUCCESS); - - out.readVector(); - - ASSERT_BINOP(out, vax, vay, ADD()); -} - -} // namespace binop -} // namespace test -} // namespace gdf diff --git a/cpp/tests/binary/unit/binop-verify-input-test.cpp b/cpp/tests/binary/unit/binop-verify-input-test.cpp index 8074fbbe95b6..d3796f0ac6e1 100644 --- a/cpp/tests/binary/unit/binop-verify-input-test.cpp +++ b/cpp/tests/binary/unit/binop-verify-input-test.cpp @@ -15,9 +15,9 @@ * limitations under the License. */ +#include "tests/utilities/column_wrapper.cuh" +#include "tests/utilities/scalar_wrapper.cuh" #include "gtest/gtest.h" -#include "tests/binary/util/scalar.h" -#include "tests/utilities/cudf_test_utils.cuh" #include #include @@ -37,276 +37,264 @@ struct BinopVerifyInputTest : public ::testing::Test { TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorZeroSize) { - std::vector vector_out(0, 0); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{0}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - gdf::library::Scalar scalar; - scalar.setValue(100); + auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorZeroSize) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(0, 0); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{0}; - gdf::library::Scalar scalar; - scalar.setValue(100); + auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorNull) { - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - gdf::library::Scalar scalar; - scalar.setValue(100); + auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(nullptr, col_vax.get(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(nullptr, vector_vax, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorNull) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - gdf::library::Scalar scalar; - scalar.setValue(100); + auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(col_out.get(), nullptr, scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, nullptr, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarNull) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), nullptr, GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_vax, nullptr, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorType) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); - col_out.get()->dtype = (gdf_dtype)100; + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; + vector_out.get()->dtype = (gdf_dtype)100; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - gdf::library::Scalar scalar; - scalar.setValue(100); + auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorType) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); - col_vax.get()->dtype = (gdf_dtype)100; + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; + vector_vax.get()->dtype = (gdf_dtype)100; - gdf::library::Scalar scalar; - scalar.setValue(100); + auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarType) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - gdf::library::Scalar scalar; - scalar.setValue(100); - scalar.scalar()->dtype = (gdf_dtype)100; + auto scalar = cudf::test::scalar_wrapper{100}; + scalar.get()->dtype = (gdf_dtype)100; - auto result = gdf_binary_operation_v_s(col_out.get(), col_vax.get(), scalar.scalar(), GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorZeroSize) { - std::vector vector_out(0, 0); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{0}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vay(10); - std::iota(vector_vay.begin(), vector_vay.end(), 1); - auto col_vay = create_gdf_column(vector_vay); + auto vector_vay = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorZeroSize) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(0, 0); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{0}; - std::vector vector_vay(10); - std::iota(vector_vay.begin(), vector_vay.end(), 1); - auto col_vay = create_gdf_column(vector_vay); + auto vector_vay = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorZeroSize) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vay(0, 0); - auto col_vay = create_gdf_column(vector_vay); + auto vector_vay = cudf::test::column_wrapper{0}; - auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorNull) { - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vay(10); - std::iota(vector_vay.begin(), vector_vay.end(), 1); - auto col_vay = create_gdf_column(vector_vay); + auto vector_vay = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(nullptr, col_vax.get(), col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(nullptr, vector_vax, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorNull) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vay(10); - std::iota(vector_vay.begin(), vector_vay.end(), 1); - auto col_vay = create_gdf_column(vector_vay); + auto vector_vay = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(col_out.get(), nullptr, col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, nullptr, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorNull) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), nullptr, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_vax, nullptr, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorType) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); - col_out.get()->dtype = (gdf_dtype)100; + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; + vector_out.get()->dtype = (gdf_dtype)100; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vay(10); - std::iota(vector_vay.begin(), vector_vay.end(), 1); - auto col_vay = create_gdf_column(vector_vay); + auto vector_vay = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorType) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); - col_vax.get()->dtype = (gdf_dtype)100; + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; + vector_vax.get()->dtype = (gdf_dtype)100; - std::vector vector_vay(10); - std::iota(vector_vay.begin(), vector_vay.end(), 1); - auto col_vay = create_gdf_column(vector_vay); + auto vector_vay = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorType) { - std::vector vector_out(10); - std::iota(vector_out.begin(), vector_out.end(), 1); - auto col_out = create_gdf_column(vector_out); + auto vector_out = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vax(10); - std::iota(vector_vax.begin(), vector_vax.end(), 1); - auto col_vax = create_gdf_column(vector_vax); + auto vector_vax = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; - std::vector vector_vay(10); - std::iota(vector_vay.begin(), vector_vay.end(), 1); - auto col_vay = create_gdf_column(vector_vay); - col_vay.get()->dtype = (gdf_dtype)100; + auto vector_vay = cudf::test::column_wrapper{10, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return true;}}; + vector_vay.get()->dtype = (gdf_dtype)100; - auto result = gdf_binary_operation_v_v(col_out.get(), col_vax.get(), col_vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } diff --git a/cpp/tests/binary/util/field.h b/cpp/tests/binary/util/field.h deleted file mode 100644 index 47d8016dd68f..000000000000 --- a/cpp/tests/binary/util/field.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2018-2019 BlazingDB, Inc. - * Copyright 2018 Christian Noboa Mardini - * - * 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 GDF_TESTS_BINARY_OPERATION_UTIL_FIELD_H -#define GDF_TESTS_BINARY_OPERATION_UTIL_FIELD_H - -#include -#include -#include - -namespace gdf { -namespace library { - - template - class Field { - public: - ~Field() { - destroy(); - } - - public: - void clear() { - mCpuData.clear(); - destroy(); - } - - void resize(int size) { - int sizeBytes = size * sizeof(Type); - if (sizeBytes != mSizeAllocBytes) { - mCpuData.resize(size); - destroy(); - create(size); - } - } - - public: - auto getGpuData() -> Type* { - return mGpuData; - } - - public: - auto begin() -> typename std::vector::iterator { - return mCpuData.begin(); - } - - auto end() -> typename std::vector::iterator { - return mCpuData.end(); - } - - auto back() -> typename std::vector::reference { - return mCpuData.back(); - } - - public: - auto size() -> std::size_t { - return mCpuData.size(); - } - - auto operator[](int index) -> Type& { - assert(index < mCpuData.size()); - return mCpuData[index]; - } - - public: - void write() { - if (mSizeAllocBytes) { - cudaMemcpy(mGpuData, mCpuData.data(), mSizeAllocBytes, cudaMemcpyHostToDevice); - } - } - - void read() { - if (mSizeAllocBytes) { - cudaMemcpy(mCpuData.data(), mGpuData, mSizeAllocBytes, cudaMemcpyDeviceToHost); - } - } - - protected: - void create(int size) { - mSizeAllocBytes = size * sizeof(Type); - cudaMalloc((void**)&(mGpuData), mSizeAllocBytes); - } - - void destroy() { - if (mSizeAllocBytes) { - mSizeAllocBytes = 0; - cudaFree(mGpuData); - } - } - - private: - int mSizeAllocBytes {0}; - Type* mGpuData {nullptr}; - std::vector mCpuData; - }; - -} // namespace library -} // namespace gdf - -#endif diff --git a/cpp/tests/binary/util/operation.h b/cpp/tests/binary/util/operation.h index 4db30d049c94..b217e754c56e 100644 --- a/cpp/tests/binary/util/operation.h +++ b/cpp/tests/binary/util/operation.h @@ -19,6 +19,8 @@ #define GDF_TESTS_BINARY_OPERATION_UTIL_OPERATION_H #include +#include +#include namespace gdf { namespace library { @@ -77,9 +79,9 @@ namespace operation { struct Mod; template - struct Mod { + struct Mod { TypeOut operator()(TypeVax x, TypeVay y) { - return (TypeOut)((uint64_t)x % (uint64_t)y); + return (TypeOut)((int64_t)x % (int64_t)y); } }; diff --git a/cpp/tests/binary/util/scalar.h b/cpp/tests/binary/util/scalar.h deleted file mode 100644 index 92c0b76bcf77..000000000000 --- a/cpp/tests/binary/util/scalar.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2018-2019 BlazingDB, Inc. - * Copyright 2018 Christian Noboa Mardini - * - * 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 GDF_TESTS_BINARY_OPERATION_UTIL_SCALAR_H -#define GDF_TESTS_BINARY_OPERATION_UTIL_SCALAR_H - -#include "tests/binary/util/types.h" -#include "cudf.h" - -namespace gdf { -namespace library { - - template - class Scalar { - public: - Scalar& setValue(Type value) { - mScalar.dtype = gdf::library::GdfDataType::Value; - gdf::library::setScalar(mScalar, value); - mScalar.is_valid = true; - return *this; - } - - Scalar& setValid(bool value) { - mScalar.is_valid = value; - return *this; - } - - public: - Type getValue() { - return (Type)*this; - } - - gdf_dtype getType() { - return mScalar.dtype; - } - - bool isValid() { - return mScalar.is_valid; - } - - public: - gdf_scalar* scalar() { - return &mScalar; - } - - public: - operator int8_t() const { - return mScalar.data.si08; - } - - operator int16_t() const { - return mScalar.data.si16; - } - - operator int32_t() const { - return mScalar.data.si32; - } - - operator int64_t() const { - return mScalar.data.si64; - } - - operator uint8_t() const { - return mScalar.data.ui08; - } - - operator uint16_t() const { - return mScalar.data.ui16; - } - - operator uint32_t() const { - return mScalar.data.ui32; - } - - operator uint64_t() const { - return mScalar.data.ui64; - } - - operator float() const { - return mScalar.data.fp32; - } - - operator double() const { - return mScalar.data.fp64; - } - - private: - gdf_scalar mScalar; - }; - -} // namespace library -} // namespace gdf - -#endif diff --git a/cpp/tests/binary/util/types.cpp b/cpp/tests/binary/util/types.cpp deleted file mode 100644 index dce691a68365..000000000000 --- a/cpp/tests/binary/util/types.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2018-2019 BlazingDB, Inc. - * Copyright 2018 Christian Noboa Mardini - * - * 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 "tests/binary/util/types.h" - -namespace gdf { -namespace library { - - const char* getTypeName(gdf_dtype type) { - switch (type) { - case GDF_INT8: - return "GDF_INT8"; - case GDF_INT16: - return "GDF_INT16"; - case GDF_INT32: - return "GDF_INT32"; - case GDF_INT64: - return "GDF_INT64"; - case GDF_UINT8: - return "GDF_UINT8"; - case GDF_UINT16: - return "GDF_UINT16"; - case GDF_UINT32: - return "GDF_UINT32"; - case GDF_UINT64: - return "GDF_UINT64"; - case GDF_FLOAT32: - return "GDF_FLOAT32"; - case GDF_FLOAT64: - return "GDF_FLOAT64"; - case GDF_DATE32: - return "GDF_DATE32"; - case GDF_DATE64: - return "GDF_DATE64"; - case GDF_TIMESTAMP: - return "GDF_TIMESTAMP"; - } - } - - namespace helper { - void setScalar(gdf_scalar& scalar, int8_t value) { - scalar.data.si08 = value; - } - - void setScalar(gdf_scalar& scalar, int16_t value) { - scalar.data.si16 = value; - } - - void setScalar(gdf_scalar& scalar, int32_t value) { - scalar.data.si32 = value; - } - - void setScalar(gdf_scalar& scalar, int64_t value) { - scalar.data.si64 = value; - } - - void setScalar(gdf_scalar& scalar, uint8_t value) { - scalar.data.ui08 = value; - } - - void setScalar(gdf_scalar& scalar, uint16_t value) { - scalar.data.ui16 = value; - } - - void setScalar(gdf_scalar& scalar, uint32_t value) { - scalar.data.ui32 = value; - } - - void setScalar(gdf_scalar& scalar, uint64_t value) { - scalar.data.ui64 = value; - } - - void setScalar(gdf_scalar& scalar, float value) { - scalar.data.fp32 = value; - } - - void setScalar(gdf_scalar& scalar, double value) { - scalar.data.fp64 = value; - } - } - - int8_t getScalar(int8_t, gdf_scalar* scalar) { - return scalar->data.si08; - } - - int16_t getScalar(int16_t, gdf_scalar* scalar) { - return scalar->data.si16; - } - - int32_t getScalar(int32_t, gdf_scalar* scalar) { - return scalar->data.si32; - } - - int64_t getScalar(int64_t, gdf_scalar* scalar) { - return scalar->data.si64; - } - - uint8_t getScalar(uint8_t, gdf_scalar* scalar) { - return scalar->data.ui08; - } - - uint16_t getScalar(uint16_t, gdf_scalar* scalar) { - return scalar->data.ui16; - } - - uint32_t getScalar(uint32_t, gdf_scalar* scalar) { - return scalar->data.ui32; - } - - uint64_t getScalar(uint64_t, gdf_scalar* scalar) { - return scalar->data.ui64; - } - - float getScalar(float, gdf_scalar* scalar) { - return scalar->data.fp32; - } - - double getScalar(double, gdf_scalar* scalar) { - return scalar->data.fp64; - } - -} // namespace library -} // namespace gdf diff --git a/cpp/tests/binary/util/types.h b/cpp/tests/binary/util/types.h deleted file mode 100644 index a553c2ebf336..000000000000 --- a/cpp/tests/binary/util/types.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2018-2019 BlazingDB, Inc. - * Copyright 2018 Christian Noboa Mardini - * - * 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 GDF_TESTS_BINARY_OPERATION_UTIL_TYPES_H -#define GDF_TESTS_BINARY_OPERATION_UTIL_TYPES_H - -#include "cudf.h" - -namespace gdf { -namespace library { - - namespace helper { - void setScalar(gdf_scalar& scalar, int8_t value); - - void setScalar(gdf_scalar& scalar, int16_t value); - - void setScalar(gdf_scalar& scalar, int32_t value); - - void setScalar(gdf_scalar& scalar, int64_t value); - - void setScalar(gdf_scalar& scalar, uint8_t value); - - void setScalar(gdf_scalar& scalar, uint16_t value); - - void setScalar(gdf_scalar& scalar, uint32_t value); - - void setScalar(gdf_scalar& scalar, uint64_t value); - - void setScalar(gdf_scalar& scalar, float value); - - void setScalar(gdf_scalar& scalar, double value); - } - - namespace helper { - template - struct GdfEnumType; - - template <> - struct GdfEnumType { - using Type = void; - }; - - template <> - struct GdfEnumType { - using Type = int8_t; - }; - - template <> - struct GdfEnumType { - using Type = int16_t; - }; - - template <> - struct GdfEnumType { - using Type = int32_t; - }; - - template <> - struct GdfEnumType { - using Type = int64_t; - }; - - template <> - struct GdfEnumType { - using Type = uint8_t; - }; - - template <> - struct GdfEnumType { - using Type = uint16_t; - }; - - template <> - struct GdfEnumType { - using Type = uint32_t; - }; - - template <> - struct GdfEnumType { - using Type = uint64_t; - }; - - template <> - struct GdfEnumType { - using Type = float; - }; - - template <> - struct GdfEnumType { - using Type = double; - }; - } - - namespace helper { - template - struct GdfDataType; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_INT8; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_INT16; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_INT32; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_INT64; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_UINT8; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_UINT16; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_UINT32; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_UINT64; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_FLOAT32; - }; - - template <> - struct GdfDataType { - static constexpr gdf_dtype Value = GDF_FLOAT64; - }; - } - - template - using GdfEnumType = typename helper::GdfEnumType::Type; - - template - using GdfDataType = helper::GdfDataType; - - template - void setScalar(gdf_scalar& scalar, Type value) { - helper::setScalar(scalar, value); - } - - const char* getTypeName(gdf_dtype type); - - int8_t getScalar(int8_t, gdf_scalar* scalar); - - int16_t getScalar(int16_t, gdf_scalar* scalar); - - int32_t getScalar(int32_t, gdf_scalar* scalar); - - int64_t getScalar(int64_t, gdf_scalar* scalar); - - uint8_t getScalar(uint8_t, gdf_scalar* scalar); - - uint16_t getScalar(uint16_t, gdf_scalar* scalar); - - uint32_t getScalar(uint32_t, gdf_scalar* scalar); - - uint64_t getScalar(uint64_t, gdf_scalar* scalar); - - float getScalar(float, gdf_scalar* scalar); - - double getScalar(double, gdf_scalar* scalar); - -} // namespace library -} // namespace gdf - -#endif diff --git a/cpp/tests/binary/util/vector.h b/cpp/tests/binary/util/vector.h deleted file mode 100644 index 3974daaa1731..000000000000 --- a/cpp/tests/binary/util/vector.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2018-2019 BlazingDB, Inc. - * Copyright 2018 Christian Noboa Mardini - * - * 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 GDF_TESTS_BINARY_OPERATION_UTIL_VECTOR_H -#define GDF_TESTS_BINARY_OPERATION_UTIL_VECTOR_H - -#include "tests/binary/util/types.h" -#include "tests/binary/util/field.h" -#include "cudf.h" - -namespace gdf { -namespace library { - - template - class Vector { - public: - using ValidType = int32_t; - static constexpr int ValidSize = 32; - - private: - template - class InnerWrapper { - public: - InnerWrapper(Field& container) - : mField (container) - { } - - T operator[](int index) { - return mField[index]; - } - - private: - Field& mField; - }; - - public: - ~Vector() { - eraseGpu(); - } - - Vector& clearGpu() { - eraseGpu(); - return *this; - } - - Vector& rangeData(Type init, Type final, Type step) { - assert((Type)0 < step); - assert(init < final); - - int size = (final - init) / step; - mData.resize(size); - for (int k = 0; k < size; ++k) { - mData[k] = init; - init += step; - } - mData.write(); - updateData(); - return *this; - } - - Vector& fillData(int size, Type value) { - mData.resize(size); - std::fill(mData.begin(), mData.end(), value); - mData.write(); - updateData(); - return *this; - } - - Vector& rangeValid(bool value) { - int size = (mData.size() / ValidSize) + ((mData.size() % ValidSize) ? 1 : 0); - mValid.resize(size); - - std::generate(mValid.begin(), mValid.end(), [value] { return -(ValidType)value; }); - clearPaddingBits(); - - mValid.write(); - updateValid(); - return *this; - } - - Vector& rangeValid(bool value, int init, int step) { - int final = mData.size(); - int size = (final / ValidSize) + ((final % ValidSize) ? 1 : 0); - mValid.resize(size); - - for (int index = 0; index < size; ++index) { - ValidType val = 0; - while (((init / ValidSize) == index) && (init < final)) { - val |= (1 << (init % ValidSize)); - init += step; - } - if (value) { - mValid[index] = val; - } else { - mValid[index] = ~val; - } - } - clearPaddingBits(); - - mValid.write(); - updateValid(); - return *this; - } - - void emplaceVector(int size) { - int validSize = (size / ValidSize) + ((size % ValidSize) ? 1 : 0); - mData.resize(size); - mValid.resize(validSize); - updateData(); - updateValid(); - } - - void readVector() { - mData.read(); - mValid.read(); - } - - public: - int dataSize() { - return mData.size(); - } - - int validSize() { - return mValid.size(); - } - - gdf_column* column() { - return &mColumn; - } - - public: - InnerWrapper data{mData}; - - InnerWrapper valid{mValid}; - - private: - void eraseGpu() { - mData.clear(); - mValid.clear(); - } - - void updateData() { - mColumn.size = mData.size(); - mColumn.dtype = GdfDataType::Value; - mColumn.data = (void*)mData.getGpuData(); - } - - void updateValid() { - mColumn.valid = (gdf_valid_type*)mValid.getGpuData(); - } - - void clearPaddingBits() { - int padding = mData.size() % ValidSize; - if (padding) { - padding = (1 << padding) - 1; - mValid.back() &= padding; - } - } - - private: - gdf_column mColumn; - - private: - Field mData; - Field mValid; - }; - -} // namespace library -} // namespace gdf - -#endif diff --git a/cpp/tests/utilities/scalar_wrapper.cuh b/cpp/tests/utilities/scalar_wrapper.cuh index 3e62917c787c..d1d202c2c11e 100644 --- a/cpp/tests/utilities/scalar_wrapper.cuh +++ b/cpp/tests/utilities/scalar_wrapper.cuh @@ -17,15 +17,16 @@ #ifndef SCALAR_WRAPPER_H #define SCALAR_WRAPPER_H -#include -#include -#include #include "cudf.h" #include "cudf_test_utils.cuh" #include "rmm/rmm.h" #include "utilities/bit_util.cuh" #include "utilities/type_dispatcher.hpp" +#include +#include +#include + #ifndef CUDA_RT_CALL #define CUDA_RT_CALL(call) \ do { \ @@ -55,6 +56,20 @@ namespace test { *---------------------------------------------------------------------------**/ template struct scalar_wrapper { + /**---------------------------------------------------------------------------* + * @brief Implicit conversion operator to a gdf_scalar pointer. + * + * Allows for implicit conversion of a column_wrapper to a pointer to its + * underlying gdf_scalar. + * + * In this way, a column_wrapper can be passed directly into a libcudf API + * and will be implicitly converted to a pointer to its underlying gdf_scalar + * without the need to use the `get()` member. + * + * @return gdf_scalar* Pointer to the underlying gdf_scalar + *---------------------------------------------------------------------------**/ + operator gdf_scalar*(){return &the_scalar;}; + /**---------------------------------------------------------------------------* * @brief Construct a new scalar wrapper object * From df64885ad4b39ccb73799a2c27e46f48402abbcf Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Sat, 16 Feb 2019 22:14:47 +0530 Subject: [PATCH 06/51] Added cython bindings --- python/cudf/bindings/binops.pyx | 68 +++++++++++++++++++++++++++++++ python/cudf/bindings/cudf_cpp.pxd | 26 ++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 python/cudf/bindings/binops.pyx diff --git a/python/cudf/bindings/binops.pyx b/python/cudf/bindings/binops.pyx new file mode 100644 index 000000000000..9eb0dc97fe91 --- /dev/null +++ b/python/cudf/bindings/binops.pyx @@ -0,0 +1,68 @@ +# Copyright (c) 2018, NVIDIA CORPORATION. + +# cython: profile=False +# distutils: language = c++ +# cython: embedsignature = True +# cython: language_level = 3 + +# Copyright (c) 2018, NVIDIA CORPORATION. + +from .cudf_cpp cimport * +from .cudf_cpp import * + + +from librmm_cffi import librmm as rmm + + +from libc.stdint cimport uintptr_t +from libc.stdlib cimport free + +from libcpp.map cimport map as cmap +from libcpp.string cimport string as cstring + +cdef cmap[cstring, gdf_binary_operator] _BINARY_OP +_BINARY_OP[b'add'] = GDF_ADD +_BINARY_OP[b'sub'] = GDF_SUB +_BINARY_OP[b'mul'] = GDF_MUL +_BINARY_OP[b'div'] = GDF_DIV +_BINARY_OP[b'truediv'] = GDF_TRUE_DIV +_BINARY_OP[b'floordiv'] = GDF_FLOOR_DIV +_BINARY_OP[b'mod'] = GDF_MOD +_BINARY_OP[b'pow'] = GDF_POW +_BINARY_OP[b'eq'] = GDF_EQUAL +_BINARY_OP[b'ne'] = GDF_NOT_EQUAL +_BINARY_OP[b'lt'] = GDF_LESS +_BINARY_OP[b'gt'] = GDF_GREATER +_BINARY_OP[b'le'] = GDF_LESS_EQUAL +_BINARY_OP[b'ge'] = GDF_GREATER_EQUAL + + +def apply_op(lhs, rhs, out, op): + """ + Call JITified gdf binary ops. + """ + + oper = bytes(op, encoding="UTF-8") + + check_gdf_compatibility(lhs) + check_gdf_compatibility(rhs) + check_gdf_compatibility(out) + + cdef gdf_column* c_lhs = column_view_from_column(lhs) + cdef gdf_column* c_rhs = column_view_from_column(rhs) + cdef gdf_column* c_out = column_view_from_column(out) + + cdef gdf_error result + cdef gdf_binary_operator c_op = _BINARY_OP[oper] + with nogil: + result = gdf_binary_operation_v_v( + c_out, + c_lhs, + c_rhs, + c_op) + + free(c_lhs) + free(c_rhs) + free(c_out) + + check_gdf_error(result) diff --git a/python/cudf/bindings/cudf_cpp.pxd b/python/cudf/bindings/cudf_cpp.pxd index ea43ad3b2cc4..9036a42cc8ea 100644 --- a/python/cudf/bindings/cudf_cpp.pxd +++ b/python/cudf/bindings/cudf_cpp.pxd @@ -189,6 +189,28 @@ cdef extern from "cudf.h" nogil: GDF_WINDOW_VA + ctypedef enum gdf_binary_operator: + GDF_ADD, + GDF_SUB, + GDF_MUL, + GDF_DIV, + GDF_TRUE_DIV, + GDF_FLOOR_DIV, + GDF_MOD, + GDF_POW, + GDF_EQUAL, + GDF_NOT_EQUAL, + GDF_LESS, + GDF_GREATER, + GDF_LESS_EQUAL, + GDF_GREATER_EQUAL + + + ctypedef struct gdf_scalar: + void *data + gdf_dtype dtype + + cdef gdf_error gdf_nvtx_range_push(char * name, gdf_color color ) cdef gdf_error gdf_nvtx_range_push_hex(char * name, unsigned int color ) @@ -488,6 +510,10 @@ cdef extern from "cudf.h" nogil: cdef gdf_error gdf_extract_datetime_minute(gdf_column *input, gdf_column *output) cdef gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output) + cdef gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) + cdef gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) + cdef gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) + cdef gdf_error gdf_add_generic(gdf_column *lhs, gdf_column *rhs, gdf_column *output) cdef gdf_error gdf_add_i32(gdf_column *lhs, gdf_column *rhs, gdf_column *output) cdef gdf_error gdf_add_i64(gdf_column *lhs, gdf_column *rhs, gdf_column *output) From 8fd508133c543a70739b97a4ecb875d04aaa0a9c Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Sat, 16 Feb 2019 22:18:28 +0530 Subject: [PATCH 07/51] Cleanup types and doc. --- cpp/include/cudf/types.h | 7 ------- cpp/src/binary/jit/util/type.cpp | 8 -------- 2 files changed, 15 deletions(-) diff --git a/cpp/include/cudf/types.h b/cpp/include/cudf/types.h index aeee1c400bc9..483d947865d7 100644 --- a/cpp/include/cudf/types.h +++ b/cpp/include/cudf/types.h @@ -27,10 +27,6 @@ typedef enum { GDF_TIMESTAMP, /**< Exact timestamp encoded with int64 since UNIX epoch (Default unit millisecond) */ GDF_CATEGORY, GDF_STRING, - GDF_UINT8, - GDF_UINT16, - GDF_UINT32, - GDF_UINT64, N_GDF_TYPES, /* additional types should go BEFORE N_GDF_TYPES */ } gdf_dtype; @@ -185,9 +181,6 @@ typedef enum { * - gdf_binary_operation_v_s_v * - gdf_binary_operation_v_v_s * - gdf_binary_operation_v_v_v - * - gdf_binary_operation_v_s_v_d - * - gdf_binary_operation_v_v_s_d - * - gdf_binary_operation_v_v_v_d */ typedef enum { GDF_ADD, diff --git a/cpp/src/binary/jit/util/type.cpp b/cpp/src/binary/jit/util/type.cpp index 873baca3db86..555e9cd37d18 100644 --- a/cpp/src/binary/jit/util/type.cpp +++ b/cpp/src/binary/jit/util/type.cpp @@ -34,14 +34,6 @@ namespace jit { case GDF_DATE64: case GDF_TIMESTAMP: return "int64_t"; - case GDF_UINT8: - return "uint8_t"; - case GDF_UINT16: - return "uint16_t"; - case GDF_UINT32: - return "uint32_t"; - case GDF_UINT64: - return "uint64_t"; case GDF_FLOAT32: return "float"; case GDF_FLOAT64: From beec8671f69f9ce43d4288a8bd2d45e7cd30d23f Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Sat, 16 Feb 2019 22:21:39 +0530 Subject: [PATCH 08/51] Use jit binop in cuDF for heterogeneous types. --- python/cudf/dataframe/numerical.py | 41 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/python/cudf/dataframe/numerical.py b/python/cudf/dataframe/numerical.py index 12af280480cc..f87e3f9d4e64 100644 --- a/python/cudf/dataframe/numerical.py +++ b/python/cudf/dataframe/numerical.py @@ -19,25 +19,20 @@ import cudf.bindings.reduce as cpp_reduce import cudf.bindings.replace as cpp_replace +import cudf.bindings.binops as cpp_binops # Operator mappings -# Unordered comparators -_unordered_impl = { +_binary_impl = { + # Unordered comparators 'eq': libgdf.gdf_eq_generic, 'ne': libgdf.gdf_ne_generic, -} - -# Ordered comparators -_ordered_impl = { + # Ordered comparators 'lt': libgdf.gdf_lt_generic, 'le': libgdf.gdf_le_generic, 'gt': libgdf.gdf_gt_generic, 'ge': libgdf.gdf_ge_generic, -} - -# Binary operators -_binary_impl = { + # Binary operators 'add': libgdf.gdf_add_generic, 'sub': libgdf.gdf_sub_generic, 'mul': libgdf.gdf_mul_generic, @@ -89,10 +84,9 @@ def deserialize(cls, deserialize, header, frames): def binary_operator(self, binop, rhs): if isinstance(rhs, NumericalColumn): - op = _binary_impl[binop] - lhs, rhs = numeric_normalize_types(self, rhs) - return numeric_column_binop(lhs=lhs, rhs=rhs, op=op, - out_dtype=lhs.dtype) + out_dtype = np.result_type(self.dtype, rhs.dtype) + return numeric_column_binop(lhs=self, rhs=rhs, op=binop, + out_dtype=out_dtype) else: msg = "{!r} operator not supported between {} and {}" raise TypeError(msg.format(binop, type(self), type(rhs))) @@ -102,12 +96,10 @@ def unary_operator(self, unaryop): out_dtype=self.dtype) def unordered_compare(self, cmpop, rhs): - lhs, rhs = numeric_normalize_types(self, rhs) - return numeric_column_compare(lhs, rhs, op=_unordered_impl[cmpop]) + return numeric_column_compare(self, rhs, op=cmpop) def ordered_compare(self, cmpop, rhs): - lhs, rhs = numeric_normalize_types(self, rhs) - return numeric_column_compare(lhs, rhs, op=_ordered_impl[cmpop]) + return numeric_column_compare(self, rhs, op=cmpop) def normalize_binop_value(self, other): other_dtype = np.min_scalar_type(other) @@ -396,15 +388,20 @@ def find_and_replace(self, to_replace, value): def numeric_column_binop(lhs, rhs, op, out_dtype): - if lhs.dtype != rhs.dtype: - raise TypeError('{} != {}'.format(lhs.dtype, rhs.dtype)) - nvtx_range_push("PYGDF_BINARY_OP", "orange") # Allocate output masked = lhs.has_null_mask or rhs.has_null_mask out = columnops.column_empty_like(lhs, dtype=out_dtype, masked=masked) # Call and fix null_count - null_count = _gdf.apply_binaryop(op, lhs, rhs, out) + if lhs.dtype != rhs.dtype: + # Use JIT implementation + cpp_binops.apply_op(lhs=lhs, rhs=rhs, out=out, op=op) + nnz = _gdf.count_nonzero_mask(out.mask.mem, size=len(out)) + null_count = len(out) - nnz + else: + # Use compiled implementation + null_count = _gdf.apply_binaryop(_binary_impl[op], lhs, rhs, out) + out = out.replace(null_count=null_count) result = out.view(NumericalColumn, dtype=out_dtype) nvtx_range_pop() From 7fe29b82fceb315874b54a4d26e4870f18507e24 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Sat, 16 Feb 2019 22:29:17 +0530 Subject: [PATCH 09/51] Fixed bug where jit kernel assumes we always have null mask. --- cpp/src/binary/jit/code/kernel.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 95ae1212129b..264b48b21cde 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -43,9 +43,10 @@ R"***( for (int i=start; i(vax_data[i], vay_data[0]); - if ((i % warpSize) == 0) { + if ((out_valid != nullptr) && (i % warpSize) == 0) { int index = i / warpSize; - out_valid[index] = vax_valid[index]; + uint32_t vax_valid_word = (vax_valid != nullptr) ? vax_valid[index] : 0xffffffff; + out_valid[index] = vax_valid_word; } } } @@ -66,9 +67,11 @@ R"***( for (int i=start; i(vax_data[i], vay_data[i]); - if ((i % warpSize) == 0) { + if ((out_valid != nullptr) && (i % warpSize) == 0) { int index = i / warpSize; - out_valid[index] = vax_valid[index] & vay_valid[index]; + uint32_t vax_valid_word = (vax_valid != nullptr) ? vax_valid[index] : 0xffffffff; + uint32_t vay_valid_word = (vay_valid != nullptr) ? vay_valid[index] : 0xffffffff; + out_valid[index] = vax_valid_word & vay_valid_word; } } } From 8e54098f7d0840945f4e0affd0a5f8a5c5fc7b05 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Mon, 18 Feb 2019 03:40:47 +0530 Subject: [PATCH 10/51] fixed another bug where null mask existence was assumed, now in cuDF --- python/cudf/dataframe/numerical.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/python/cudf/dataframe/numerical.py b/python/cudf/dataframe/numerical.py index f87e3f9d4e64..d92c2debd48d 100644 --- a/python/cudf/dataframe/numerical.py +++ b/python/cudf/dataframe/numerical.py @@ -396,8 +396,11 @@ def numeric_column_binop(lhs, rhs, op, out_dtype): if lhs.dtype != rhs.dtype: # Use JIT implementation cpp_binops.apply_op(lhs=lhs, rhs=rhs, out=out, op=op) - nnz = _gdf.count_nonzero_mask(out.mask.mem, size=len(out)) - null_count = len(out) - nnz + if masked: + nnz = _gdf.count_nonzero_mask(out.mask.mem, size=len(out)) + null_count = len(out) - nnz + else: + null_count = 0 else: # Use compiled implementation null_count = _gdf.apply_binaryop(_binary_impl[op], lhs, rhs, out) From ada453eadc321d8e975191a798d2e96c4be1f188 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Mon, 18 Feb 2019 03:42:59 +0530 Subject: [PATCH 11/51] Enabled global JIT cache and confirmed performance and correctness. that was easy. --- cpp/CMakeLists.txt | 6 ++++++ cpp/src/binary/jit/core/launcher.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 2b37fadf179a..0507a69b85e5 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -236,6 +236,12 @@ if(HT_LEGACY_ALLOCATOR) set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --define-macro HT_LEGACY_ALLOCATOR") endif(HT_LEGACY_ALLOCATOR) +option(JITIFY_THREAD_SAFE "Use a global cache for JIT compiled kernels" ON) +if(JITIFY_THREAD_SAFE) + message(STATUS "Using global cache for JIT compiled kernels") + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --define-macro JITIFY_THREAD_SAFE") +endif(JITIFY_THREAD_SAFE) + ################################################################################################### # - link libraries -------------------------------------------------------------------------------- diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index 934992b83baf..f0ea449424f8 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -23,7 +23,11 @@ namespace gdf { namespace binops { namespace jit { +#ifdef JITIFY_THREAD_SAFE + static jitify::JitCache JitCache; +#else static thread_local jitify::JitCache JitCache; +#endif std::istream* headersCode(std::string filename, std::iostream& stream) { if (filename == "operation.h") { From 88c57c1c2abed50a2bc2b4b8b3281b9b165503ce Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Mon, 18 Feb 2019 18:15:55 +0530 Subject: [PATCH 12/51] Added remaining binary ops were previously unimplemented - Modulo - Power --- python/cudf/dataframe/numerical.py | 2 +- python/cudf/dataframe/series.py | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/python/cudf/dataframe/numerical.py b/python/cudf/dataframe/numerical.py index d92c2debd48d..672dba8ded0c 100644 --- a/python/cudf/dataframe/numerical.py +++ b/python/cudf/dataframe/numerical.py @@ -393,7 +393,7 @@ def numeric_column_binop(lhs, rhs, op, out_dtype): masked = lhs.has_null_mask or rhs.has_null_mask out = columnops.column_empty_like(lhs, dtype=out_dtype, masked=masked) # Call and fix null_count - if lhs.dtype != rhs.dtype: + if lhs.dtype != rhs.dtype or op not in _binary_impl: # Use JIT implementation cpp_binops.apply_op(lhs=lhs, rhs=rhs, out=out, op=op) if masked: diff --git a/python/cudf/dataframe/series.py b/python/cudf/dataframe/series.py index 5e8ae1f84e2d..3a961d92efbb 100644 --- a/python/cudf/dataframe/series.py +++ b/python/cudf/dataframe/series.py @@ -368,11 +368,14 @@ def __mul__(self, other): def __rmul__(self, other): return self._rbinaryop(other, 'mul') + def __mod__(self, other): + return self._binaryop(other, 'mod') + + def __rmod__(self, other): + return self._rbinaryop(other, 'mod') + def __pow__(self, other): - if other == 2: - return self * self - else: - return NotImplemented + return self._binaryop(other, 'pow') def __floordiv__(self, other): return self._binaryop(other, 'floordiv') From b6650ce3d0e327aee018a860078d546d8025f94b Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Mon, 18 Feb 2019 20:32:41 +0530 Subject: [PATCH 13/51] Added pytests for the two new ops --- python/cudf/tests/test_binops.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/cudf/tests/test_binops.py b/python/cudf/tests/test_binops.py index 5ea44d140aeb..0b531d5fdef2 100644 --- a/python/cudf/tests/test_binops.py +++ b/python/cudf/tests/test_binops.py @@ -20,6 +20,8 @@ operator.mul, operator.floordiv, operator.truediv, + operator.mod, + operator.pow, ] From f9dea2004d9efe8e52365392ffe9ae11209861f2 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 20 Feb 2019 19:04:37 +0530 Subject: [PATCH 14/51] renamed Vax and Vay to Lhs and Rhs. --- cpp/include/cudf/functions.h | 24 +-- cpp/src/binary/jit/code/kernel.cpp | 26 +-- cpp/src/binary/jit/code/operation.cpp | 192 +++++++++--------- cpp/src/binary/jit/code/traits.cpp | 36 ++-- cpp/src/binary/jit/core/binop.cpp | 54 ++--- cpp/src/binary/jit/core/launcher.cpp | 12 +- cpp/src/binary/jit/core/launcher.h | 8 +- cpp/tests/binary/integration/assert-binops.h | 106 +++++----- .../binary-operation-integration-test.cpp | 130 ++++++------ .../binary/unit/binop-verify-input-test.cpp | 84 ++++---- cpp/tests/binary/util/operation.h | 74 +++---- python/cudf/bindings/cudf_cpp.pxd | 6 +- 12 files changed, 376 insertions(+), 376 deletions(-) diff --git a/cpp/include/cudf/functions.h b/cpp/include/cudf/functions.h index 667538ff1065..9a1c080a47d4 100644 --- a/cpp/include/cudf/functions.h +++ b/cpp/include/cudf/functions.h @@ -603,19 +603,19 @@ gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output); * gdf_column operand. * * The valid field in the gdf_column output will be 1 (by bit) when the two - * operands (vax and vay) are not null. Otherwise, it will be 0 (by bit). + * operands (lhs and rhs) are not null. Otherwise, it will be 0 (by bit). * * It is required to set in an appropriate manner the fields in the gdf_scalar and * gdf_column structs due to that the binary operation will not be performed. * * @param out (gdf_column) Output of the operation. - * @param vax (gdf_scalar) First operand of the operation. - * @param vay (gdf_column) Second operand of the operation. + * @param lhs (gdf_scalar) First operand of the operation. + * @param rhs (gdf_column) Second operand of the operation. * @param ope (enum) The binary operator that is going to be used in the operation. * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ -gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope); +gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope); /** * @brief Binary operation function between gdf_column and gdf_scalar structs. @@ -624,19 +624,19 @@ gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* * gdf_scalar operand. * * The valid field in the gdf_column output will be 1 (by bit) when the two - * operands (vax and vay) are not null. Otherwise, it will be 0 (by bit). + * operands (lhs and rhs) are not null. Otherwise, it will be 0 (by bit). * * It is required to set in an appropriate manner the fields in the gdf_scalar and * gdf_column structs due to that the binary operation will not be performed. * * @param out (gdf_column) Output of the operation. - * @param vax (gdf_column) First operand of the operation. - * @param vay (gdf_scalar) Second operand of the operation. + * @param lhs (gdf_column) First operand of the operation. + * @param rhs (gdf_scalar) Second operand of the operation. * @param ope (enum) The binary operator that is going to be used in the operation. * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ -gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope); +gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_binary_operator ope); /** * @brief Binary operation function between two gdf_column structs. @@ -644,19 +644,19 @@ gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* * The function performs the binary operation of two gdf_column operands. * * The valid field in the gdf_column output will be 1 (by bit) when the two - * operands (vax and vay) are not null. Otherwise, it will be 0 (by bit). + * operands (lhs and rhs) are not null. Otherwise, it will be 0 (by bit). * * It is required to set in an appropriate manner the fields in the gdf_column * struct due to that the binary operation will not be performed. * * @param out (gdf_column) Output of the operation. - * @param vax (gdf_column) First operand of the operation. - * @param vay (gdf_column) Second operand of the operation. + * @param lhs (gdf_column) First operand of the operation. + * @param rhs (gdf_column) Second operand of the operation. * @param ope (enum) The binary operator that is going to be used in the operation. * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ -gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope); +gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_binary_operator ope); /* arith */ diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 264b48b21cde..d01dfeef3404 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -27,11 +27,11 @@ R"***( #include "traits.h" #include "operation.h" - template + template __global__ void kernel_v_s(int size, - TypeOut* out_data, TypeVax* vax_data, TypeVay* vay_data, - uint32_t* out_valid, uint32_t* vax_valid) { + TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data, + uint32_t* out_valid, uint32_t* lhs_valid) { int tid = threadIdx.x; int blkid = blockIdx.x; int blksz = blockDim.x; @@ -41,21 +41,21 @@ R"***( int step = blksz * gridsz; for (int i=start; i(vax_data[i], vay_data[0]); + out_data[i] = TypeOpe::template operate(lhs_data[i], rhs_data[0]); if ((out_valid != nullptr) && (i % warpSize) == 0) { int index = i / warpSize; - uint32_t vax_valid_word = (vax_valid != nullptr) ? vax_valid[index] : 0xffffffff; - out_valid[index] = vax_valid_word; + uint32_t lhs_valid_word = (lhs_valid != nullptr) ? lhs_valid[index] : 0xffffffff; + out_valid[index] = lhs_valid_word; } } } - template + template __global__ void kernel_v_v(int size, - TypeOut* out_data, TypeVax* vax_data, TypeVay* vay_data, - uint32_t* out_valid, uint32_t* vax_valid, uint32_t* vay_valid) { + TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data, + uint32_t* out_valid, uint32_t* lhs_valid, uint32_t* rhs_valid) { int tid = threadIdx.x; int blkid = blockIdx.x; int blksz = blockDim.x; @@ -65,13 +65,13 @@ R"***( int step = blksz * gridsz; for (int i=start; i(vax_data[i], vay_data[i]); + out_data[i] = TypeOpe::template operate(lhs_data[i], rhs_data[i]); if ((out_valid != nullptr) && (i % warpSize) == 0) { int index = i / warpSize; - uint32_t vax_valid_word = (vax_valid != nullptr) ? vax_valid[index] : 0xffffffff; - uint32_t vay_valid_word = (vay_valid != nullptr) ? vay_valid[index] : 0xffffffff; - out_valid[index] = vax_valid_word & vay_valid_word; + uint32_t lhs_valid_word = (lhs_valid != nullptr) ? lhs_valid[index] : 0xffffffff; + uint32_t rhs_valid_word = (rhs_valid != nullptr) ? rhs_valid[index] : 0xffffffff; + out_valid[index] = lhs_valid_word & rhs_valid_word; } } } diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp index 781226395fb1..18ae46266d80 100644 --- a/cpp/src/binary/jit/code/operation.cpp +++ b/cpp/src/binary/jit/code/operation.cpp @@ -25,9 +25,9 @@ R"***( #pragma once struct Add { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x + (Common)y); } }; @@ -35,25 +35,25 @@ R"***( using RAdd = Add; struct Sub { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x - (Common)y); } }; struct RSub { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)y - (Common)x); } }; struct Mul { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x * (Common)y); } }; @@ -61,125 +61,125 @@ R"***( using RMul = Mul; struct Div { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x / (Common)y); } }; struct RDiv { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)y / (Common)x); } }; struct TrueDiv { - template - static TypeOut operate(TypeVax x, TypeVay y) { + template + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)((double)x / (double)y); } }; struct RTrueDiv { - template - static TypeOut operate(TypeVax x, TypeVay y) { + template + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)((double)y / (double)x); } }; struct FloorDiv { - template - static TypeOut operate(TypeVax x, TypeVay y) { + template + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)floor((double)x / (double)y); } }; struct RFloorDiv { - template - static TypeOut operate(TypeVax x, TypeVay y) { + template + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)floor((double)y / (double)x); } }; struct Mod { template , + typename TypeLhs, + typename TypeRhs, + typename Common = CommonNumber, enableIf<(isIntegral)>* = nullptr> - static TypeOut operate(TypeVax x, TypeVay y) { + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)((Common)x % (Common)y); } template , + typename TypeLhs, + typename TypeRhs, + typename Common = CommonNumber, enableIf<(isFloat)>* = nullptr> - static TypeOut operate(TypeVax x, TypeVay y) { + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)fmodf((Common)x, (Common)y); } template , + typename TypeLhs, + typename TypeRhs, + typename Common = CommonNumber, enableIf<(isDouble)>* = nullptr> - static TypeOut operate(TypeVax x, TypeVay y) { + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)fmod((Common)x, (Common)y); } }; struct RMod { template , + typename TypeLhs, + typename TypeRhs, + typename Common = CommonNumber, enableIf<(isIntegral)>* = nullptr> - static TypeOut operate(TypeVax x, TypeVay y) { + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)((Common)y % (Common)x); } template , + typename TypeLhs, + typename TypeRhs, + typename Common = CommonNumber, enableIf<(isFloat)>* = nullptr> - static TypeOut operate(TypeVax x, TypeVay y) { + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)fmodf((Common)y, (Common)x); } template , + typename TypeLhs, + typename TypeRhs, + typename Common = CommonNumber, enableIf<(isDouble)>* = nullptr> - static TypeOut operate(TypeVax x, TypeVay y) { + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)fmod((Common)y, (Common)x); } }; struct Pow { - template - static TypeOut operate(TypeVax x, TypeVay y) { + template + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)pow((double)x, (double)y); } }; struct RPow { - template - static TypeOut operate(TypeVax x, TypeVay y) { + template + static TypeOut operate(TypeLhs x, TypeRhs y) { return (TypeOut)pow((double)y, (double)x); } }; struct Equal { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x == (Common)y); } }; @@ -187,9 +187,9 @@ R"***( using REqual = Equal; struct NotEqual { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x != (Common)y); } }; @@ -197,65 +197,65 @@ R"***( using RNotEqual = NotEqual; struct Less { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x < (Common)y); } }; struct RLess { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)y < (Common)x); } }; struct Greater { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x > (Common)y); } }; struct RGreater { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)y > (Common)x); } }; struct LessEqual { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x <= (Common)y); } }; struct RLessEqual { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)y <= (Common)x); } }; struct GreaterEqual { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)x >= (Common)y); } }; struct RGreaterEqual { - template - static TypeOut operate(TypeVax x, TypeVay y) { - using Common = CommonNumber; + template + static TypeOut operate(TypeLhs x, TypeRhs y) { + using Common = CommonNumber; return (TypeOut)((Common)y >= (Common)x); } }; @@ -269,32 +269,32 @@ R"***( * * struct Add { * template , + * typename TypeLhs, + * typename TypeRhs, + * typename Common = CommonNumber, * enableIf<(isIntegralSigned)>* = nullptr> * __device__ - * TypeOut operate(TypeVax x, TypeVay y) { + * TypeOut operate(TypeLhs x, TypeRhs y) { * return (TypeOut)((Common)x + (Common)y); * } * * template , + * typename TypeLhs, + * typename TypeRhs, + * typename Common = CommonNumber, * enableIf<(isIntegralUnsigned)>* = nullptr> * __device__ - * TypeOut operate(TypeVax x, TypeVay y) { + * TypeOut operate(TypeLhs x, TypeRhs y) { * return (TypeOut)((Common)x + (Common)y); * } * * template , + * typename TypeLhs, + * typename TypeRhs, + * typename Common = CommonNumber, * enableIf<(isFloatingPoint)>* = nullptr> * __device__ - * TypeOut operate(TypeVax x, TypeVay y) { + * TypeOut operate(TypeLhs x, TypeRhs y) { * return (TypeOut)((Common)x + (Common)y); * } * }; diff --git a/cpp/src/binary/jit/code/traits.cpp b/cpp/src/binary/jit/code/traits.cpp index 9e01d40f480d..9266b24ace2c 100644 --- a/cpp/src/binary/jit/code/traits.cpp +++ b/cpp/src/binary/jit/code/traits.cpp @@ -199,36 +199,36 @@ R"***( - template + template struct HelperCommonNumber {}; - template - struct HelperCommonNumber || isFloatingPoint)>> { - using Type = If<(sizeof(Vax) == 8 || sizeof(Vay) == 8), double, float>; + template + struct HelperCommonNumber || isFloatingPoint)>> { + using Type = If<(sizeof(Lhs) == 8 || sizeof(Rhs) == 8), double, float>; }; - template - struct HelperCommonNumber && isIntegralSigned)>> { - using Type = IntegralMap<(MaxSize), IntegralSigned>; + template + struct HelperCommonNumber && isIntegralSigned)>> { + using Type = IntegralMap<(MaxSize), IntegralSigned>; }; - template - struct HelperCommonNumber && isIntegralUnsigned)>> { - using Type = IntegralMap<(MaxSize), IntegralSigned>; + template + struct HelperCommonNumber && isIntegralUnsigned)>> { + using Type = IntegralMap<(MaxSize), IntegralSigned>; }; - template - struct HelperCommonNumber && isIntegralSigned)>> { - using Type = IntegralMap<(MaxSize), IntegralSigned>; + template + struct HelperCommonNumber && isIntegralSigned)>> { + using Type = IntegralMap<(MaxSize), IntegralSigned>; }; - template - struct HelperCommonNumber && isIntegralUnsigned)>> { - using Type = IntegralMap<(MaxSize), IntegralUnsigned>; + template + struct HelperCommonNumber && isIntegralUnsigned)>> { + using Type = IntegralMap<(MaxSize), IntegralUnsigned>; }; - template - using CommonNumber = typename HelperCommonNumber::Type; + template + using CommonNumber = typename HelperCommonNumber::Type; )***"; } // namespace code diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index 3231157f9b41..e97ff5923bdc 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -70,83 +70,83 @@ namespace jit { return Option(true, GDF_SUCCESS); } - Option verify_column(gdf_column* out, gdf_column* vax) { + Option verify_column(gdf_column* out, gdf_column* lhs) { auto result = verify_column(out); if (!result) { return result; } - result = verify_column(vax); + result = verify_column(lhs); if (!result) { return result; } - if (out->size < vax->size) { + if (out->size < lhs->size) { return Option(false, GDF_COLUMN_SIZE_MISMATCH); } return Option(true, GDF_SUCCESS); } - Option verify_column(gdf_column* out, gdf_column* vax, gdf_column* vay) { + Option verify_column(gdf_column* out, gdf_column* lhs, gdf_column* rhs) { auto result = verify_column(out); if (!result) { return result; } - result = verify_column(vax); + result = verify_column(lhs); if (!result) { return result; } - result = verify_column(vay); + result = verify_column(rhs); if (!result) { return result; } - if ((out->size < vax->size) || (out->size < vay->size) || (vay->size != vax->size)) { + if ((out->size < lhs->size) || (out->size < rhs->size) || (rhs->size != lhs->size)) { return Option(false, GDF_COLUMN_SIZE_MISMATCH); } return Option(true, GDF_SUCCESS); } - gdf_error binary_operation(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) { - auto option_scalar = verify_scalar(vax); + gdf_error binary_operation(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) { + auto option_scalar = verify_scalar(lhs); if (!option_scalar) { return option_scalar.get_gdf_error(); } - auto option_column = verify_column(out, vay); + auto option_column = verify_column(out, rhs); if (!option_column) { return option_column.get_gdf_error(); } Launcher::launch().kernel("kernel_v_s") - .instantiate(ope, Operator::Type::Reverse, out, vay, vax) - .launch(out, vay, vax); + .instantiate(ope, Operator::Type::Reverse, out, rhs, lhs) + .launch(out, rhs, lhs); return GDF_SUCCESS; } - gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) { - auto option_scalar = verify_scalar(vay); + gdf_error binary_operation(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_binary_operator ope) { + auto option_scalar = verify_scalar(rhs); if (!option_scalar) { return option_scalar.get_gdf_error(); } - auto option_column = verify_column(out, vax); + auto option_column = verify_column(out, lhs); if (!option_column) { return option_column.get_gdf_error(); } Launcher::launch().kernel("kernel_v_s") - .instantiate(ope, Operator::Type::Direct, out, vax, vay) - .launch(out, vax, vay); + .instantiate(ope, Operator::Type::Direct, out, lhs, rhs) + .launch(out, lhs, rhs); return GDF_SUCCESS; } - gdf_error binary_operation(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) { - auto option_column = verify_column(out, vax, vay); + gdf_error binary_operation(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_binary_operator ope) { + auto option_column = verify_column(out, lhs, rhs); if (!option_column) { return option_column.get_gdf_error(); } Launcher::launch().kernel("kernel_v_v") - .instantiate(ope, Operator::Type::Direct, out, vax, vay) - .launch(out, vax, vay); + .instantiate(ope, Operator::Type::Direct, out, lhs, rhs) + .launch(out, lhs, rhs); return GDF_SUCCESS; } @@ -156,14 +156,14 @@ namespace jit { } // namespace gdf -gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, vax, vay, ope); +gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, lhs, rhs, ope); } -gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, vax, vay, ope); +gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, lhs, rhs, ope); } -gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, vax, vay, ope); +gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_binary_operator ope) { + return gdf::binops::jit::binary_operation(out, lhs, rhs, ope); } diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index f0ea449424f8..4225aee7ed56 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -54,24 +54,24 @@ namespace jit { return *this; } - gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay) { + gdf_error Launcher::launch(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs) { program.kernel(kernelName.c_str()) .instantiate(arguments) .configure_1d_max_occupancy() .launch(out->size, - out->data, vax->data, vay->data, - out->valid, vax->valid); + out->data, lhs->data, rhs->data, + out->valid, lhs->valid); return GDF_SUCCESS; } - gdf_error Launcher::launch(gdf_column* out, gdf_column* vax, gdf_column* vay) { + gdf_error Launcher::launch(gdf_column* out, gdf_column* lhs, gdf_column* rhs) { program.kernel(kernelName.c_str()) .instantiate(arguments) .configure_1d_max_occupancy() .launch(out->size, - out->data, vax->data, vay->data, - out->valid, vax->valid, vay->valid); + out->data, lhs->data, rhs->data, + out->valid, lhs->valid, rhs->valid); return GDF_SUCCESS; } diff --git a/cpp/src/binary/jit/core/launcher.h b/cpp/src/binary/jit/core/launcher.h index 187d6320ce35..3db233552373 100644 --- a/cpp/src/binary/jit/core/launcher.h +++ b/cpp/src/binary/jit/core/launcher.h @@ -56,13 +56,13 @@ namespace jit { return *this; } - gdf_error launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay); + gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs); - gdf_error launch(gdf_column* out, gdf_column* vax, gdf_column* vay); + gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_column* rhs); - gdf_error launch(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_scalar* def); + gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_scalar* def); - gdf_error launch(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_scalar* def); + gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_scalar* def); private: std::vector compilerFlags { "-std=c++14" }; diff --git a/cpp/tests/binary/integration/assert-binops.h b/cpp/tests/binary/integration/assert-binops.h index 8ddd48af2383..de961f3d58c0 100644 --- a/cpp/tests/binary/integration/assert-binops.h +++ b/cpp/tests/binary/integration/assert-binops.h @@ -27,82 +27,82 @@ namespace gdf { namespace test { namespace binop { -template +template void ASSERT_BINOP(cudf::test::column_wrapper& out, - cudf::test::scalar_wrapper& vax, - cudf::test::column_wrapper& vay, + cudf::test::scalar_wrapper& lhs, + cudf::test::column_wrapper& rhs, TypeOpe&& ope) { - auto vax_h = vax.to_host(); - auto vay_h = vay.to_host(); - auto vay_data = std::get<0>(vay_h); + auto lhs_h = lhs.to_host(); + auto rhs_h = rhs.to_host(); + auto rhs_data = std::get<0>(rhs_h); auto out_h = out.to_host(); auto out_data = std::get<0>(out_h); - ASSERT_TRUE(out_data.size() == vay_data.size()); + ASSERT_TRUE(out_data.size() == rhs_data.size()); for (int index = 0; index < out_data.size(); ++index) { - ASSERT_TRUE(out_data[index] == (TypeOut)(ope(vax_h, vay_data[index]))); + ASSERT_TRUE(out_data[index] == (TypeOut)(ope(lhs_h, rhs_data[index]))); } - auto vay_valid = std::get<1>(vay_h); + auto rhs_valid = std::get<1>(rhs_h); auto out_valid = std::get<1>(out_h); - ASSERT_TRUE(out_valid.size() == vay_valid.size()); + ASSERT_TRUE(out_valid.size() == rhs_valid.size()); for (int index = 0; index < out_valid.size(); ++index) { - ASSERT_TRUE(out_valid[index] == vay_valid[index]); + ASSERT_TRUE(out_valid[index] == rhs_valid[index]); } } -template +template void ASSERT_BINOP(cudf::test::column_wrapper& out, - cudf::test::column_wrapper& vax, - cudf::test::scalar_wrapper& vay, + cudf::test::column_wrapper& lhs, + cudf::test::scalar_wrapper& rhs, TypeOpe&& ope) { - auto vay_h = vay.to_host(); - auto vax_h = vax.to_host(); - auto vax_data = std::get<0>(vax_h); + auto rhs_h = rhs.to_host(); + auto lhs_h = lhs.to_host(); + auto lhs_data = std::get<0>(lhs_h); auto out_h = out.to_host(); auto out_data = std::get<0>(out_h); - ASSERT_TRUE(out_data.size() == vax_data.size()); + ASSERT_TRUE(out_data.size() == lhs_data.size()); for (int index = 0; index < out_data.size(); ++index) { - ASSERT_TRUE(out_data[index] == (TypeOut)(ope(vax_data[index], vay_h))); + ASSERT_TRUE(out_data[index] == (TypeOut)(ope(lhs_data[index], rhs_h))); } - auto vax_valid = std::get<1>(vax_h); + auto lhs_valid = std::get<1>(lhs_h); auto out_valid = std::get<1>(out_h); - ASSERT_TRUE(out_valid.size() == vax_valid.size()); + ASSERT_TRUE(out_valid.size() == lhs_valid.size()); for (int index = 0; index < out_valid.size(); ++index) { - ASSERT_TRUE(out_valid[index] == (vax_valid[index])); + ASSERT_TRUE(out_valid[index] == (lhs_valid[index])); } } -template +template void ASSERT_BINOP(cudf::test::column_wrapper& out, - cudf::test::column_wrapper& vax, - cudf::test::column_wrapper& vay, + cudf::test::column_wrapper& lhs, + cudf::test::column_wrapper& rhs, TypeOpe&& ope) { - auto vax_h = vax.to_host(); - auto vax_data = std::get<0>(vax_h); - auto vay_h = vay.to_host(); - auto vay_data = std::get<0>(vay_h); + auto lhs_h = lhs.to_host(); + auto lhs_data = std::get<0>(lhs_h); + auto rhs_h = rhs.to_host(); + auto rhs_data = std::get<0>(rhs_h); auto out_h = out.to_host(); auto out_data = std::get<0>(out_h); - ASSERT_TRUE(out_data.size() == vax_data.size()); - ASSERT_TRUE(out_data.size() == vay_data.size()); + ASSERT_TRUE(out_data.size() == lhs_data.size()); + ASSERT_TRUE(out_data.size() == rhs_data.size()); for (int index = 0; index < out_data.size(); ++index) { - ASSERT_TRUE(out_data[index] == (TypeOut)(ope(vax_data[index], vay_data[index]))); + ASSERT_TRUE(out_data[index] == (TypeOut)(ope(lhs_data[index], rhs_data[index]))); } - auto vax_valid = std::get<1>(vax_h); - auto vay_valid = std::get<1>(vay_h); + auto lhs_valid = std::get<1>(lhs_h); + auto rhs_valid = std::get<1>(rhs_h); auto out_valid = std::get<1>(out_h); - ASSERT_TRUE(out_valid.size() == vax_valid.size()); - ASSERT_TRUE(out_valid.size() == vay_valid.size()); + ASSERT_TRUE(out_valid.size() == lhs_valid.size()); + ASSERT_TRUE(out_valid.size() == rhs_valid.size()); for (int index = 0; index < out_valid.size(); ++index) { - ASSERT_TRUE(out_valid[index] == vax_valid[index] | vay_valid[index]); + ASSERT_TRUE(out_valid[index] == lhs_valid[index] | rhs_valid[index]); } } @@ -111,33 +111,33 @@ void ASSERT_BINOP(cudf::test::column_wrapper& out, * Mathematical Standard Library Functions with Maximum ULP Error' * The pow function has 2 (full range) maximum ulp error. */ -template +template void ASSERT_BINOP(cudf::test::column_wrapper& out, - cudf::test::column_wrapper& vax, - cudf::test::column_wrapper& vay, - gdf::library::operation::Pow&& ope) { - auto vax_h = vax.to_host(); - auto vax_data = std::get<0>(vax_h); - auto vay_h = vay.to_host(); - auto vay_data = std::get<0>(vay_h); + cudf::test::column_wrapper& lhs, + cudf::test::column_wrapper& rhs, + gdf::library::operation::Pow&& ope) { + auto lhs_h = lhs.to_host(); + auto lhs_data = std::get<0>(lhs_h); + auto rhs_h = rhs.to_host(); + auto rhs_data = std::get<0>(rhs_h); auto out_h = out.to_host(); auto out_data = std::get<0>(out_h); const int ULP = 2.0; - ASSERT_TRUE(out_data.size() == vax_data.size()); - ASSERT_TRUE(out_data.size() == vay_data.size()); + ASSERT_TRUE(out_data.size() == lhs_data.size()); + ASSERT_TRUE(out_data.size() == rhs_data.size()); for (int index = 0; index < out_data.size(); ++index) { - ASSERT_TRUE(abs(out_data[index] - (TypeOut)(ope(vax_data[index], vay_data[index]))) < ULP); + ASSERT_TRUE(abs(out_data[index] - (TypeOut)(ope(lhs_data[index], rhs_data[index]))) < ULP); } - auto vax_valid = std::get<1>(vax_h); - auto vay_valid = std::get<1>(vay_h); + auto lhs_valid = std::get<1>(lhs_h); + auto rhs_valid = std::get<1>(rhs_h); auto out_valid = std::get<1>(out_h); - ASSERT_TRUE(out_valid.size() == vax_valid.size()); - ASSERT_TRUE(out_valid.size() == vay_valid.size()); + ASSERT_TRUE(out_valid.size() == lhs_valid.size()); + ASSERT_TRUE(out_valid.size() == rhs_valid.size()); for (int index = 0; index < out_valid.size(); ++index) { - ASSERT_TRUE(out_valid[index] == (vax_valid[index] & vay_valid[index])); + ASSERT_TRUE(out_valid[index] == (lhs_valid[index] & rhs_valid[index])); } } diff --git a/cpp/tests/binary/integration/binary-operation-integration-test.cpp b/cpp/tests/binary/integration/binary-operation-integration-test.cpp index 493e33821287..b3f576efd2dc 100644 --- a/cpp/tests/binary/integration/binary-operation-integration-test.cpp +++ b/cpp/tests/binary/integration/binary-operation-integration-test.cpp @@ -39,228 +39,228 @@ struct BinaryOperationIntegrationTest : public ::testing::Test { TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_SI32_FP32_SI64) { using ADD = gdf::library::operation::Add; - auto vax = cudf::test::scalar_wrapper{100}; - auto vay = cudf::test::column_wrapper{100000, + auto lhs = cudf::test::scalar_wrapper{100}; + auto rhs = cudf::test::column_wrapper{100000, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return (row % 4 > 0);}}; - auto out = cudf::test::column_wrapper{vay.get()->size, true}; + auto out = cudf::test::column_wrapper{rhs.get()->size, true}; - auto result = gdf_binary_operation_s_v(out.get(), vax.get(), vay.get(), GDF_ADD); + auto result = gdf_binary_operation_s_v(out.get(), lhs.get(), rhs.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, ADD()); + ASSERT_BINOP(out, lhs, rhs, ADD()); } TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_SI32_FP32_SI64) { using SUB = gdf::library::operation::Sub; - auto vax = cudf::test::scalar_wrapper{10000}; - auto vay = cudf::test::column_wrapper{100000, + auto lhs = cudf::test::scalar_wrapper{10000}; + auto rhs = cudf::test::column_wrapper{100000, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return (row % 4 > 0);}}; - auto out = cudf::test::column_wrapper{vay.get()->size, true}; + auto out = cudf::test::column_wrapper{rhs.get()->size, true}; - auto result = gdf_binary_operation_s_v(out.get(), vax.get(), vay.get(), GDF_SUB); + auto result = gdf_binary_operation_s_v(out.get(), lhs.get(), rhs.get(), GDF_SUB); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, SUB()); + ASSERT_BINOP(out, lhs, rhs, SUB()); } TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_SI08_SI16_SI32) { using ADD = gdf::library::operation::Add; - auto vax = cudf::test::column_wrapper{100, + auto lhs = cudf::test::column_wrapper{100, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return (row % 6 > 0);}}; - auto vay = cudf::test::scalar_wrapper{100}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto rhs = cudf::test::scalar_wrapper{100}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_s(out.get(), vax.get(), vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_s(out.get(), lhs.get(), rhs.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, ADD()); + ASSERT_BINOP(out, lhs, rhs, ADD()); } TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_SI32_FP64_SI08) { using ADD = gdf::library::operation::Add; - auto vax = cudf::test::column_wrapper{100, + auto lhs = cudf::test::column_wrapper{100, [](gdf_size_type row) {return row * 2.0;}, [](gdf_size_type row) {return (row % 3 > 0);}}; - auto vay = cudf::test::column_wrapper{100, + auto rhs = cudf::test::column_wrapper{100, [](gdf_size_type row) {return row * 1;}, [](gdf_size_type row) {return (row % 4 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_ADD); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, ADD()); + ASSERT_BINOP(out, lhs, rhs, ADD()); } TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_SI64) { using SUB = gdf::library::operation::Sub; - auto vax = cudf::test::column_wrapper{50000, + auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, [](gdf_size_type row) {return (row % 4 == 0);}}; - auto vay = cudf::test::column_wrapper{50000, + auto rhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 50000 + row;}, [](gdf_size_type row) {return (row % 3 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_SUB); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_SUB); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, SUB()); + ASSERT_BINOP(out, lhs, rhs, SUB()); } TEST_F(BinaryOperationIntegrationTest, Mul_Vector_Vector_SI64) { using MUL = gdf::library::operation::Mul; - auto vax = cudf::test::column_wrapper{50000, + auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, [](gdf_size_type row) {return (row % 3 > 0);}}; - auto vay = cudf::test::column_wrapper{50000, + auto rhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 50000 + row;}, [](gdf_size_type row) {return (row % 4 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MUL); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_MUL); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, MUL()); + ASSERT_BINOP(out, lhs, rhs, MUL()); } TEST_F(BinaryOperationIntegrationTest, Div_Vector_Vector_SI64) { using DIV = gdf::library::operation::Div; - auto vax = cudf::test::column_wrapper{50000, + auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, [](gdf_size_type row) {return (row % 6 > 0);}}; - auto vay = cudf::test::column_wrapper{50000, + auto rhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 50000 + row;}, [](gdf_size_type row) {return (row % 8 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_DIV); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_DIV); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, DIV()); + ASSERT_BINOP(out, lhs, rhs, DIV()); } TEST_F(BinaryOperationIntegrationTest, TrueDiv_Vector_Vector_SI64) { using TRUEDIV = gdf::library::operation::TrueDiv; - auto vax = cudf::test::column_wrapper{50000, + auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, [](gdf_size_type row) {return (row % 3 == 0);}}; - auto vay = cudf::test::column_wrapper{50000, + auto rhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 50000 + row;}, [](gdf_size_type row) {return (row % 4 == 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_TRUE_DIV); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_TRUE_DIV); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, TRUEDIV()); + ASSERT_BINOP(out, lhs, rhs, TRUEDIV()); } TEST_F(BinaryOperationIntegrationTest, FloorDiv_Vector_Vector_SI64) { using FLOORDIV = gdf::library::operation::FloorDiv; - auto vax = cudf::test::column_wrapper{50000, + auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, [](gdf_size_type row) {return (row % 6 > 0);}}; - auto vay = cudf::test::column_wrapper{50000, + auto rhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 50000 + row;}, [](gdf_size_type row) {return (row % 8 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_FLOOR_DIV); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_FLOOR_DIV); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, FLOORDIV()); + ASSERT_BINOP(out, lhs, rhs, FLOORDIV()); } TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_SI64) { using MOD = gdf::library::operation::Mod; - auto vax = cudf::test::column_wrapper{50, + auto lhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 120 + row * 2;}, [](gdf_size_type row) {return (row % 3 > 0);}}; - auto vay = cudf::test::column_wrapper{50, + auto rhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 50 + row;}, [](gdf_size_type row) {return (row % 5 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, MOD()); + ASSERT_BINOP(out, lhs, rhs, MOD()); } TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP32) { using MOD = gdf::library::operation::Mod; - auto vax = cudf::test::column_wrapper{50, + auto lhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 120 + row * 2;}, [](gdf_size_type row) {return (row % 4 > 0);}}; - auto vay = cudf::test::column_wrapper{50, + auto rhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 50 + row;}, [](gdf_size_type row) {return (row % 6 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, MOD()); + ASSERT_BINOP(out, lhs, rhs, MOD()); } TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP64) { using MOD = gdf::library::operation::Mod; - auto vax = cudf::test::column_wrapper{50, + auto lhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 120 + row * 2;}, [](gdf_size_type row) {return (row % 3 == 0);}}; - auto vay = cudf::test::column_wrapper{50, + auto rhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 50 + row;}, [](gdf_size_type row) {return (row % 4 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_MOD); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_MOD); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, MOD()); + ASSERT_BINOP(out, lhs, rhs, MOD()); } TEST_F(BinaryOperationIntegrationTest, Pow_Vector_Vector_SI64) { using POW = gdf::library::operation::Pow; - auto vax = cudf::test::column_wrapper{500, + auto lhs = cudf::test::column_wrapper{500, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return (row % 6 > 0);}}; - auto vay = cudf::test::column_wrapper{500, + auto rhs = cudf::test::column_wrapper{500, [](gdf_size_type row) {return 2;}, [](gdf_size_type row) {return (row % 4 > 0);}}; - auto out = cudf::test::column_wrapper{vax.get()->size, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; - auto result = gdf_binary_operation_v_v(out.get(), vax.get(), vay.get(), GDF_POW); + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_POW); ASSERT_TRUE(result == GDF_SUCCESS); - ASSERT_BINOP(out, vax, vay, POW()); + ASSERT_BINOP(out, lhs, rhs, POW()); } } // namespace binop diff --git a/cpp/tests/binary/unit/binop-verify-input-test.cpp b/cpp/tests/binary/unit/binop-verify-input-test.cpp index d3796f0ac6e1..b8bbc88eb82f 100644 --- a/cpp/tests/binary/unit/binop-verify-input-test.cpp +++ b/cpp/tests/binary/unit/binop-verify-input-test.cpp @@ -39,13 +39,13 @@ struct BinopVerifyInputTest : public ::testing::Test { TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorZeroSize) { auto vector_out = cudf::test::column_wrapper{0}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_lhs, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } @@ -55,23 +55,23 @@ TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorZeroSize) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{0}; + auto vector_lhs = cudf::test::column_wrapper{0}; auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_lhs, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorNull) { - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(nullptr, vector_vax, scalar, GDF_ADD); + auto result = gdf_binary_operation_v_s(nullptr, vector_lhs, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } @@ -93,11 +93,11 @@ TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarNull) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_s(vector_out, vector_vax, nullptr, GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_lhs, nullptr, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } @@ -108,13 +108,13 @@ TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOutputVectorType) { [](gdf_size_type row) {return true;}}; vector_out.get()->dtype = (gdf_dtype)100; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_lhs, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } @@ -124,14 +124,14 @@ TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandVectorType) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - vector_vax.get()->dtype = (gdf_dtype)100; + vector_lhs.get()->dtype = (gdf_dtype)100; auto scalar = cudf::test::scalar_wrapper{100}; - auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_lhs, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } @@ -141,14 +141,14 @@ TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarType) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; auto scalar = cudf::test::scalar_wrapper{100}; scalar.get()->dtype = (gdf_dtype)100; - auto result = gdf_binary_operation_v_s(vector_out, vector_vax, scalar, GDF_ADD); + auto result = gdf_binary_operation_v_s(vector_out, vector_lhs, scalar, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } @@ -156,15 +156,15 @@ TEST_F(BinopVerifyInputTest, Vector_Scalar_ErrorOperandScalarType) { TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorZeroSize) { auto vector_out = cudf::test::column_wrapper{0}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vay = cudf::test::column_wrapper{10, + auto vector_rhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_lhs, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } @@ -174,13 +174,13 @@ TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorZeroSize) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{0}; + auto vector_lhs = cudf::test::column_wrapper{0}; - auto vector_vay = cudf::test::column_wrapper{10, + auto vector_rhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_lhs, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } @@ -190,27 +190,27 @@ TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorZeroSize) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vay = cudf::test::column_wrapper{0}; + auto vector_rhs = cudf::test::column_wrapper{0}; - auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_lhs, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_SUCCESS); } TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorNull) { - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vay = cudf::test::column_wrapper{10, + auto vector_rhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(nullptr, vector_vax, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(nullptr, vector_lhs, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } @@ -220,11 +220,11 @@ TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorNull) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vay = cudf::test::column_wrapper{10, + auto vector_rhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(vector_out, nullptr, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, nullptr, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } @@ -234,11 +234,11 @@ TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorNull) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(vector_out, vector_vax, nullptr, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_lhs, nullptr, GDF_ADD); ASSERT_TRUE(result == GDF_DATASET_EMPTY); } @@ -249,15 +249,15 @@ TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorOutputVectorType) { [](gdf_size_type row) {return true;}}; vector_out.get()->dtype = (gdf_dtype)100; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vay = cudf::test::column_wrapper{10, + auto vector_rhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_lhs, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } @@ -267,16 +267,16 @@ TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorFirstOperandVectorType) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - vector_vax.get()->dtype = (gdf_dtype)100; + vector_lhs.get()->dtype = (gdf_dtype)100; - auto vector_vay = cudf::test::column_wrapper{10, + auto vector_rhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_lhs, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } @@ -286,15 +286,15 @@ TEST_F(BinopVerifyInputTest, Vector_Vector_ErrorSecondOperandVectorType) { [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vax = cudf::test::column_wrapper{10, + auto vector_lhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - auto vector_vay = cudf::test::column_wrapper{10, + auto vector_rhs = cudf::test::column_wrapper{10, [](gdf_size_type row) {return row;}, [](gdf_size_type row) {return true;}}; - vector_vay.get()->dtype = (gdf_dtype)100; + vector_rhs.get()->dtype = (gdf_dtype)100; - auto result = gdf_binary_operation_v_v(vector_out, vector_vax, vector_vay, GDF_ADD); + auto result = gdf_binary_operation_v_v(vector_out, vector_lhs, vector_rhs, GDF_ADD); ASSERT_TRUE(result == GDF_UNSUPPORTED_DTYPE); } diff --git a/cpp/tests/binary/util/operation.h b/cpp/tests/binary/util/operation.h index b217e754c56e..9340e2734bfc 100644 --- a/cpp/tests/binary/util/operation.h +++ b/cpp/tests/binary/util/operation.h @@ -26,83 +26,83 @@ namespace gdf { namespace library { namespace operation { - template + template struct Add { - TypeOut operator()(TypeVax vax, TypeVay vay) { - using TypeCommon = typename std::common_type::type; - return (TypeOut)((TypeCommon)vax + (TypeCommon)vay); + TypeOut operator()(TypeLhs lhs, TypeRhs rhs) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)lhs + (TypeCommon)rhs); } }; - template + template struct Sub { - TypeOut operator()(TypeVax vax, TypeVay vay) { - using TypeCommon = typename std::common_type::type; - return (TypeOut)((TypeCommon)vax - (TypeCommon)vay); + TypeOut operator()(TypeLhs lhs, TypeRhs rhs) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)lhs - (TypeCommon)rhs); } }; - template + template struct Mul { - TypeOut operator()(TypeVax vax, TypeVay vay) { - using TypeCommon = typename std::common_type::type; - return (TypeOut)((TypeCommon)vax * (TypeCommon)vay); + TypeOut operator()(TypeLhs lhs, TypeRhs rhs) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)lhs * (TypeCommon)rhs); } }; - template + template struct Div { - TypeOut operator()(TypeVax vax, TypeVay vay) { - using TypeCommon = typename std::common_type::type; - return (TypeOut)((TypeCommon)vax / (TypeCommon)vay); + TypeOut operator()(TypeLhs lhs, TypeRhs rhs) { + using TypeCommon = typename std::common_type::type; + return (TypeOut)((TypeCommon)lhs / (TypeCommon)rhs); } }; - template + template struct TrueDiv { - TypeOut operator()(TypeVax vax, TypeVay vay) { - return (TypeOut)((double)vax / (double)vay); + TypeOut operator()(TypeLhs lhs, TypeRhs rhs) { + return (TypeOut)((double)lhs / (double)rhs); } }; - template + template struct FloorDiv { - TypeOut operator()(TypeVax vax, TypeVay vay) { - return (TypeOut)floor((double)vax / (double)vay); + TypeOut operator()(TypeLhs lhs, TypeRhs rhs) { + return (TypeOut)floor((double)lhs / (double)rhs); } }; template ::type> + typename TypeLhs, + typename TypeRhs, + typename Common = typename std::common_type::type> struct Mod; - template - struct Mod { - TypeOut operator()(TypeVax x, TypeVay y) { + template + struct Mod { + TypeOut operator()(TypeLhs x, TypeRhs y) { return (TypeOut)((int64_t)x % (int64_t)y); } }; - template - struct Mod { - TypeOut operator()(TypeVax x, TypeVay y) { + template + struct Mod { + TypeOut operator()(TypeLhs x, TypeRhs y) { return (TypeOut)fmod((float)x, (float)y); } }; - template - struct Mod { - TypeOut operator()(TypeVax x, TypeVay y) { + template + struct Mod { + TypeOut operator()(TypeLhs x, TypeRhs y) { return (TypeOut)fmod((double)x, (double)y); } }; - template + template struct Pow { - TypeOut operator()(TypeVax vax, TypeVay vay) { - return (TypeOut)pow((double)vax, (double)vay); + TypeOut operator()(TypeLhs lhs, TypeRhs rhs) { + return (TypeOut)pow((double)lhs, (double)rhs); } }; diff --git a/python/cudf/bindings/cudf_cpp.pxd b/python/cudf/bindings/cudf_cpp.pxd index 9036a42cc8ea..3d0c176bf9e5 100644 --- a/python/cudf/bindings/cudf_cpp.pxd +++ b/python/cudf/bindings/cudf_cpp.pxd @@ -510,9 +510,9 @@ cdef extern from "cudf.h" nogil: cdef gdf_error gdf_extract_datetime_minute(gdf_column *input, gdf_column *output) cdef gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output) - cdef gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* vax, gdf_column* vay, gdf_binary_operator ope) - cdef gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* vax, gdf_scalar* vay, gdf_binary_operator ope) - cdef gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* vax, gdf_column* vay, gdf_binary_operator ope) + cdef gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) + cdef gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_binary_operator ope) + cdef gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_binary_operator ope) cdef gdf_error gdf_add_generic(gdf_column *lhs, gdf_column *rhs, gdf_column *output) cdef gdf_error gdf_add_i32(gdf_column *lhs, gdf_column *rhs, gdf_column *output) From 48302f7d91b0632816285ff41a0b96cef16fcf04 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 20 Feb 2019 19:12:59 +0530 Subject: [PATCH 15/51] Documentation cleanup in types. --- cpp/include/cudf/types.h | 63 ++++++++++++-------------------- cpp/src/binary/jit/util/type.cpp | 5 --- 2 files changed, 24 insertions(+), 44 deletions(-) diff --git a/cpp/include/cudf/types.h b/cpp/include/cudf/types.h index 483d947865d7..976a0534ad60 100644 --- a/cpp/include/cudf/types.h +++ b/cpp/include/cudf/types.h @@ -86,19 +86,13 @@ typedef struct { } gdf_dtype_extra_info; -/** - * @struct gdf_scalar - * @brief literal or variable - * - * The struct is used as a literal or a variable in the libgdf library. - * - * @var data A union that represents the value. - * @var dtype An enum that represents the type of the value. - * @var is_valid A boolean that represents whether the scalar is null. - */ +/**---------------------------------------------------------------------------* + * @brief A struct to hold a scalar (single) value and its type information + * + *---------------------------------------------------------------------------**/ typedef struct { - void* data; - gdf_dtype dtype; + void* data; /**< Pointer to the scalar data */ + gdf_dtype dtype; /**< The datatype of the scalar's data */ } gdf_scalar; @@ -174,34 +168,25 @@ typedef enum { } gdf_color; -/** - * @enum gdf_binary_operator - * It contains the different operations that can be performed in the binary operations. - * The enumeration is used in the following functions: - * - gdf_binary_operation_v_s_v - * - gdf_binary_operation_v_v_s - * - gdf_binary_operation_v_v_v - */ +/**---------------------------------------------------------------------------* + * @brief Types of binary operations that can be performed on data. + * + *---------------------------------------------------------------------------**/ typedef enum { - GDF_ADD, - GDF_SUB, - GDF_MUL, - GDF_DIV, - GDF_TRUE_DIV, - GDF_FLOOR_DIV, - GDF_MOD, - GDF_POW, - GDF_EQUAL, - GDF_NOT_EQUAL, - GDF_LESS, - GDF_GREATER, - GDF_LESS_EQUAL, - GDF_GREATER_EQUAL, - //GDF_COMBINE, - //GDF_COMBINE_FIRST, - //GDF_ROUND, - //GDF_PRODUCT, - //GDF_DOT + GDF_ADD, /**< operator + */ + GDF_SUB, /**< operator - */ + GDF_MUL, /**< operator * */ + GDF_DIV, /**< operator / using common type of lhs and rhs */ + GDF_TRUE_DIV, /**< operator / after promoting type to floating point*/ + GDF_FLOOR_DIV, /**< operator / after promoting to float and then flooring the result */ + GDF_MOD, /**< operator % */ + GDF_POW, /**< lhs ^ rhs */ + GDF_EQUAL, /**< operator == */ + GDF_NOT_EQUAL, /**< operator != */ + GDF_LESS, /**< operator < */ + GDF_GREATER, /**< operator > */ + GDF_LESS_EQUAL, /**< operator <= */ + GDF_GREATER_EQUAL, /**< operator >= */ } gdf_binary_operator; diff --git a/cpp/src/binary/jit/util/type.cpp b/cpp/src/binary/jit/util/type.cpp index 555e9cd37d18..6e47a2b3982d 100644 --- a/cpp/src/binary/jit/util/type.cpp +++ b/cpp/src/binary/jit/util/type.cpp @@ -61,9 +61,6 @@ namespace jit { return "Mod"; case GDF_POW: return "Pow"; - //case GDF_COMBINE: - //case GDF_COMBINE_FIRST: - //case GDF_ROUND: case GDF_EQUAL: return "Equal"; case GDF_NOT_EQUAL: @@ -76,8 +73,6 @@ namespace jit { return "LessEqual"; case GDF_GREATER_EQUAL: return "GreaterEqual"; - //GDF_PRODUCT, - //GDF_DOT default: return "None"; } From d553db038e0719fe24f8b37fe81e2a8855de589f Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 20 Feb 2019 19:34:56 +0530 Subject: [PATCH 16/51] change name of namespace gdf to cudf. --- cpp/src/binary/jit/code/code.h | 2 +- cpp/src/binary/jit/code/kernel.cpp | 4 +-- cpp/src/binary/jit/code/operation.cpp | 4 +-- cpp/src/binary/jit/code/traits.cpp | 4 +-- cpp/src/binary/jit/core/binop.cpp | 10 +++---- cpp/src/binary/jit/core/launcher.cpp | 4 +-- cpp/src/binary/jit/core/launcher.h | 4 +-- cpp/src/binary/jit/util/operator.cpp | 4 +-- cpp/src/binary/jit/util/operator.h | 4 +-- cpp/src/binary/jit/util/type.cpp | 4 +-- cpp/src/binary/jit/util/type.h | 2 +- cpp/tests/binary/integration/assert-binops.h | 6 ++-- .../binary-operation-integration-test.cpp | 30 +++++++++---------- cpp/tests/binary/util/operation.h | 4 +-- 14 files changed, 43 insertions(+), 43 deletions(-) diff --git a/cpp/src/binary/jit/code/code.h b/cpp/src/binary/jit/code/code.h index 1ca7d8369de5..0825e732dc12 100644 --- a/cpp/src/binary/jit/code/code.h +++ b/cpp/src/binary/jit/code/code.h @@ -18,7 +18,7 @@ #ifndef GDF_BINARY_OPERATION_JIT_CODE_CODE_H #define GDF_BINARY_OPERATION_JIT_CODE_CODE_H -namespace gdf { +namespace cudf { namespace binops { namespace jit { namespace code { diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index d01dfeef3404..516ffec28774 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -16,7 +16,7 @@ * limitations under the License. */ -namespace gdf { +namespace cudf { namespace binops { namespace jit { namespace code { @@ -80,4 +80,4 @@ R"***( } // namespace code } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp index 18ae46266d80..8787e8490edc 100644 --- a/cpp/src/binary/jit/code/operation.cpp +++ b/cpp/src/binary/jit/code/operation.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -namespace gdf { +namespace cudf { namespace binops { namespace jit { namespace code { @@ -303,4 +303,4 @@ R"***( } // namespace code } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf diff --git a/cpp/src/binary/jit/code/traits.cpp b/cpp/src/binary/jit/code/traits.cpp index 9266b24ace2c..e9d79c640ee4 100644 --- a/cpp/src/binary/jit/code/traits.cpp +++ b/cpp/src/binary/jit/code/traits.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -namespace gdf { +namespace cudf { namespace binops { namespace jit { namespace code { @@ -234,4 +234,4 @@ R"***( } // namespace code } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index e97ff5923bdc..a50ce926d8da 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -19,7 +19,7 @@ #include "binary/jit/util/operator.h" #include "cudf.h" -namespace gdf { +namespace cudf { namespace binops { namespace jit { @@ -153,17 +153,17 @@ namespace jit { } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, lhs, rhs, ope); + return cudf::binops::jit::binary_operation(out, lhs, rhs, ope); } gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, lhs, rhs, ope); + return cudf::binops::jit::binary_operation(out, lhs, rhs, ope); } gdf_error gdf_binary_operation_v_v(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_binary_operator ope) { - return gdf::binops::jit::binary_operation(out, lhs, rhs, ope); + return cudf::binops::jit::binary_operation(out, lhs, rhs, ope); } diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index 4225aee7ed56..f529efa18d78 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -19,7 +19,7 @@ #include "binary/jit/code/code.h" #include -namespace gdf { +namespace cudf { namespace binops { namespace jit { @@ -78,4 +78,4 @@ namespace jit { } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf diff --git a/cpp/src/binary/jit/core/launcher.h b/cpp/src/binary/jit/core/launcher.h index 3db233552373..1cfdef430704 100644 --- a/cpp/src/binary/jit/core/launcher.h +++ b/cpp/src/binary/jit/core/launcher.h @@ -22,7 +22,7 @@ #include "binary/jit/util/operator.h" #include -namespace gdf { +namespace cudf { namespace binops { namespace jit { @@ -78,6 +78,6 @@ namespace jit { } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf #endif diff --git a/cpp/src/binary/jit/util/operator.cpp b/cpp/src/binary/jit/util/operator.cpp index 694b72e5c3ba..0c5226b7ba8c 100644 --- a/cpp/src/binary/jit/util/operator.cpp +++ b/cpp/src/binary/jit/util/operator.cpp @@ -19,7 +19,7 @@ #include "binary/jit/util/type.h" #include -namespace gdf { +namespace cudf { namespace binops { namespace jit { @@ -40,4 +40,4 @@ namespace jit { } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf diff --git a/cpp/src/binary/jit/util/operator.h b/cpp/src/binary/jit/util/operator.h index 96f1497af6f1..6869f691cf47 100644 --- a/cpp/src/binary/jit/util/operator.h +++ b/cpp/src/binary/jit/util/operator.h @@ -20,7 +20,7 @@ #include "cudf.h" -namespace gdf { +namespace cudf { namespace binops { namespace jit { @@ -43,6 +43,6 @@ namespace jit { } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf #endif diff --git a/cpp/src/binary/jit/util/type.cpp b/cpp/src/binary/jit/util/type.cpp index 6e47a2b3982d..8ba3bdda9c94 100644 --- a/cpp/src/binary/jit/util/type.cpp +++ b/cpp/src/binary/jit/util/type.cpp @@ -17,7 +17,7 @@ #include "binary/jit/util/type.h" -namespace gdf { +namespace cudf { namespace binops { namespace jit { @@ -80,4 +80,4 @@ namespace jit { } // namespace jit } // namespace binops -} // namespace gdf +} // namespace cudf diff --git a/cpp/src/binary/jit/util/type.h b/cpp/src/binary/jit/util/type.h index 78fe34334e58..379e2f14db99 100644 --- a/cpp/src/binary/jit/util/type.h +++ b/cpp/src/binary/jit/util/type.h @@ -20,7 +20,7 @@ #include "cudf.h" -namespace gdf { +namespace cudf { namespace binops { namespace jit { diff --git a/cpp/tests/binary/integration/assert-binops.h b/cpp/tests/binary/integration/assert-binops.h index de961f3d58c0..5ec619c82e6b 100644 --- a/cpp/tests/binary/integration/assert-binops.h +++ b/cpp/tests/binary/integration/assert-binops.h @@ -23,7 +23,7 @@ #include "tests/utilities/scalar_wrapper.cuh" #include "gtest/gtest.h" -namespace gdf { +namespace cudf { namespace test { namespace binop { @@ -115,7 +115,7 @@ template void ASSERT_BINOP(cudf::test::column_wrapper& out, cudf::test::column_wrapper& lhs, cudf::test::column_wrapper& rhs, - gdf::library::operation::Pow&& ope) { + cudf::library::operation::Pow&& ope) { auto lhs_h = lhs.to_host(); auto lhs_data = std::get<0>(lhs_h); auto rhs_h = rhs.to_host(); @@ -143,6 +143,6 @@ void ASSERT_BINOP(cudf::test::column_wrapper& out, } // namespace binop } // namespace test -} // namespace gdf +} // namespace cudf #endif diff --git a/cpp/tests/binary/integration/binary-operation-integration-test.cpp b/cpp/tests/binary/integration/binary-operation-integration-test.cpp index b3f576efd2dc..3df63db54e0c 100644 --- a/cpp/tests/binary/integration/binary-operation-integration-test.cpp +++ b/cpp/tests/binary/integration/binary-operation-integration-test.cpp @@ -17,7 +17,7 @@ #include "tests/binary/integration/assert-binops.h" -namespace gdf { +namespace cudf { namespace test { namespace binop { @@ -37,7 +37,7 @@ struct BinaryOperationIntegrationTest : public ::testing::Test { TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_SI32_FP32_SI64) { - using ADD = gdf::library::operation::Add; + using ADD = cudf::library::operation::Add; auto lhs = cudf::test::scalar_wrapper{100}; auto rhs = cudf::test::column_wrapper{100000, @@ -53,7 +53,7 @@ TEST_F(BinaryOperationIntegrationTest, Add_Scalar_Vector_SI32_FP32_SI64) { TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_SI32_FP32_SI64) { - using SUB = gdf::library::operation::Sub; + using SUB = cudf::library::operation::Sub; auto lhs = cudf::test::scalar_wrapper{10000}; auto rhs = cudf::test::column_wrapper{100000, @@ -69,7 +69,7 @@ TEST_F(BinaryOperationIntegrationTest, Sub_Scalar_Vector_SI32_FP32_SI64) { TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_SI08_SI16_SI32) { - using ADD = gdf::library::operation::Add; + using ADD = cudf::library::operation::Add; auto lhs = cudf::test::column_wrapper{100, [](gdf_size_type row) {return row;}, @@ -85,7 +85,7 @@ TEST_F(BinaryOperationIntegrationTest, Add_Vector_Scalar_SI08_SI16_SI32) { TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_SI32_FP64_SI08) { - using ADD = gdf::library::operation::Add; + using ADD = cudf::library::operation::Add; auto lhs = cudf::test::column_wrapper{100, [](gdf_size_type row) {return row * 2.0;}, @@ -103,7 +103,7 @@ TEST_F(BinaryOperationIntegrationTest, Add_Vector_Vector_SI32_FP64_SI08) { TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_SI64) { - using SUB = gdf::library::operation::Sub; + using SUB = cudf::library::operation::Sub; auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, @@ -121,7 +121,7 @@ TEST_F(BinaryOperationIntegrationTest, Sub_Vector_Vector_SI64) { TEST_F(BinaryOperationIntegrationTest, Mul_Vector_Vector_SI64) { - using MUL = gdf::library::operation::Mul; + using MUL = cudf::library::operation::Mul; auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, @@ -139,7 +139,7 @@ TEST_F(BinaryOperationIntegrationTest, Mul_Vector_Vector_SI64) { TEST_F(BinaryOperationIntegrationTest, Div_Vector_Vector_SI64) { - using DIV = gdf::library::operation::Div; + using DIV = cudf::library::operation::Div; auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, @@ -157,7 +157,7 @@ TEST_F(BinaryOperationIntegrationTest, Div_Vector_Vector_SI64) { TEST_F(BinaryOperationIntegrationTest, TrueDiv_Vector_Vector_SI64) { - using TRUEDIV = gdf::library::operation::TrueDiv; + using TRUEDIV = cudf::library::operation::TrueDiv; auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, @@ -175,7 +175,7 @@ TEST_F(BinaryOperationIntegrationTest, TrueDiv_Vector_Vector_SI64) { TEST_F(BinaryOperationIntegrationTest, FloorDiv_Vector_Vector_SI64) { - using FLOORDIV = gdf::library::operation::FloorDiv; + using FLOORDIV = cudf::library::operation::FloorDiv; auto lhs = cudf::test::column_wrapper{50000, [](gdf_size_type row) {return 100000 + row * 2;}, @@ -193,7 +193,7 @@ TEST_F(BinaryOperationIntegrationTest, FloorDiv_Vector_Vector_SI64) { TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_SI64) { - using MOD = gdf::library::operation::Mod; + using MOD = cudf::library::operation::Mod; auto lhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 120 + row * 2;}, @@ -211,7 +211,7 @@ TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_SI64) { TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP32) { - using MOD = gdf::library::operation::Mod; + using MOD = cudf::library::operation::Mod; auto lhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 120 + row * 2;}, @@ -229,7 +229,7 @@ TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP32) { TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP64) { - using MOD = gdf::library::operation::Mod; + using MOD = cudf::library::operation::Mod; auto lhs = cudf::test::column_wrapper{50, [](gdf_size_type row) {return 120 + row * 2;}, @@ -247,7 +247,7 @@ TEST_F(BinaryOperationIntegrationTest, Mod_Vector_Vector_FP64) { TEST_F(BinaryOperationIntegrationTest, Pow_Vector_Vector_SI64) { - using POW = gdf::library::operation::Pow; + using POW = cudf::library::operation::Pow; auto lhs = cudf::test::column_wrapper{500, [](gdf_size_type row) {return row;}, @@ -265,4 +265,4 @@ TEST_F(BinaryOperationIntegrationTest, Pow_Vector_Vector_SI64) { } // namespace binop } // namespace test -} // namespace gdf +} // namespace cudf diff --git a/cpp/tests/binary/util/operation.h b/cpp/tests/binary/util/operation.h index 9340e2734bfc..0f988b33f458 100644 --- a/cpp/tests/binary/util/operation.h +++ b/cpp/tests/binary/util/operation.h @@ -22,7 +22,7 @@ #include #include -namespace gdf { +namespace cudf { namespace library { namespace operation { @@ -108,6 +108,6 @@ namespace operation { } // namespace operation } // namespace library -} // namespace gdf +} // namespace cudf #endif From 4413a78841b9990e4bfc3a6907a1112329ebd783 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 20 Feb 2019 21:53:51 +0530 Subject: [PATCH 17/51] changed error handling to use GDF_REQUIRE --- cpp/src/binary/jit/core/binop.cpp | 138 +++++++++--------------------- 1 file changed, 40 insertions(+), 98 deletions(-) diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index a50ce926d8da..d07e126fb59c 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -17,102 +17,28 @@ #include "binary/jit/core/launcher.h" #include "binary/jit/util/operator.h" +#include "utilities/error_utils.h" #include "cudf.h" namespace cudf { namespace binops { namespace jit { - struct Option { - Option(bool state, gdf_error value) - : is_correct{state}, gdf_error_value{value} - { } - - operator bool() { - return is_correct; - } - - gdf_error get_gdf_error() { - return gdf_error_value; - } - - private: - bool is_correct; - gdf_error gdf_error_value; - }; - - Option verify_scalar(gdf_scalar* scalar) { - if (scalar == nullptr) { - return Option(false, GDF_DATASET_EMPTY); - } - if (scalar->data == nullptr) { - return Option(false, GDF_DATASET_EMPTY); - } - if ((scalar->dtype <= GDF_invalid) || (N_GDF_TYPES <= scalar->dtype)) { - return Option(false, GDF_UNSUPPORTED_DTYPE); - } - return Option(true, GDF_SUCCESS); - } + gdf_error binary_operation(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) { - Option verify_column(gdf_column* vector) { - if (vector == nullptr) { - return Option(false, GDF_DATASET_EMPTY); - } - if (vector->size == 0) { - return Option(false, GDF_SUCCESS); - } - if (vector->data == nullptr) { - return Option(false, GDF_DATASET_EMPTY); - } - if ((vector->dtype <= GDF_invalid) || (N_GDF_TYPES <= vector->dtype)) { - return Option(false, GDF_UNSUPPORTED_DTYPE); - } - return Option(true, GDF_SUCCESS); - } + // Check for null pointers in input + GDF_REQUIRE((out != nullptr) && (lhs != nullptr) && (rhs != nullptr), GDF_DATASET_EMPTY) - Option verify_column(gdf_column* out, gdf_column* lhs) { - auto result = verify_column(out); - if (!result) { - return result; - } - result = verify_column(lhs); - if (!result) { - return result; - } - if (out->size < lhs->size) { - return Option(false, GDF_COLUMN_SIZE_MISMATCH); - } - return Option(true, GDF_SUCCESS); - } + // Check for 0 sized data + GDF_REQUIRE((out->size != 0) && (rhs->size != 0), GDF_SUCCESS) + GDF_REQUIRE((out->size == rhs->size), GDF_COLUMN_SIZE_MISMATCH) - Option verify_column(gdf_column* out, gdf_column* lhs, gdf_column* rhs) { - auto result = verify_column(out); - if (!result) { - return result; - } - result = verify_column(lhs); - if (!result) { - return result; - } - result = verify_column(rhs); - if (!result) { - return result; - } - if ((out->size < lhs->size) || (out->size < rhs->size) || (rhs->size != lhs->size)) { - return Option(false, GDF_COLUMN_SIZE_MISMATCH); - } - return Option(true, GDF_SUCCESS); - } + // Check for null data pointer + GDF_REQUIRE((out->data != nullptr) && (lhs->data != nullptr) && (rhs->data != nullptr), GDF_DATASET_EMPTY) - gdf_error binary_operation(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) { - auto option_scalar = verify_scalar(lhs); - if (!option_scalar) { - return option_scalar.get_gdf_error(); - } - auto option_column = verify_column(out, rhs); - if (!option_column) { - return option_column.get_gdf_error(); - } + // Check for datatype + GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) + GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) Launcher::launch().kernel("kernel_v_s") .instantiate(ope, Operator::Type::Reverse, out, rhs, lhs) @@ -122,14 +48,20 @@ namespace jit { } gdf_error binary_operation(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_binary_operator ope) { - auto option_scalar = verify_scalar(rhs); - if (!option_scalar) { - return option_scalar.get_gdf_error(); - } - auto option_column = verify_column(out, lhs); - if (!option_column) { - return option_column.get_gdf_error(); - } + + // Check for null pointers in input + GDF_REQUIRE((out != nullptr) && (lhs != nullptr) && (rhs != nullptr), GDF_DATASET_EMPTY) + + // Check for 0 sized data + GDF_REQUIRE((out->size != 0) && (lhs->size != 0), GDF_SUCCESS) + GDF_REQUIRE((out->size == lhs->size), GDF_COLUMN_SIZE_MISMATCH) + + // Check for null data pointer + GDF_REQUIRE((out->data != nullptr) && (lhs->data != nullptr) && (rhs->data != nullptr), GDF_DATASET_EMPTY) + + // Check for datatype + GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) + GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) Launcher::launch().kernel("kernel_v_s") .instantiate(ope, Operator::Type::Direct, out, lhs, rhs) @@ -139,11 +71,21 @@ namespace jit { } gdf_error binary_operation(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_binary_operator ope) { - auto option_column = verify_column(out, lhs, rhs); - if (!option_column) { - return option_column.get_gdf_error(); - } + // Check for null pointers in input + GDF_REQUIRE((out != nullptr) && (lhs != nullptr) && (rhs != nullptr), GDF_DATASET_EMPTY) + + // Check for 0 sized data + GDF_REQUIRE((out->size != 0) && (lhs->size != 0) && (rhs->size != 0), GDF_SUCCESS) + GDF_REQUIRE((out->size == lhs->size) && (lhs->size == rhs->size), GDF_COLUMN_SIZE_MISMATCH) + + // Check for null data pointer + GDF_REQUIRE((out->data != nullptr) && (lhs->data != nullptr) && (rhs->data != nullptr), GDF_DATASET_EMPTY) + + // Check for datatype + GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) + GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) + Launcher::launch().kernel("kernel_v_v") .instantiate(ope, Operator::Type::Direct, out, lhs, rhs) .launch(out, lhs, rhs); From ca9e43e17cec5b967a9fe4a501009b72e3cade4d Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 21 Feb 2019 04:29:47 +0530 Subject: [PATCH 18/51] documentation for launcher --- cpp/src/binary/jit/core/launcher.cpp | 14 ++++++++++ cpp/src/binary/jit/core/launcher.h | 40 +++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index f529efa18d78..dcdba164dee0 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -23,12 +23,26 @@ namespace cudf { namespace binops { namespace jit { +/**---------------------------------------------------------------------------* + * @brief Cache to hold previously compiled code in. If JITIFY_THREAD_SAFE is + * defined, then the cache is held globally in the process, otherwise it is + * held locally in each thread + * + *---------------------------------------------------------------------------**/ #ifdef JITIFY_THREAD_SAFE static jitify::JitCache JitCache; #else static thread_local jitify::JitCache JitCache; #endif + /**---------------------------------------------------------------------------* + * @brief Used to provide Jitify with strings that should be used as headers + * during JIT compilation. + * + * @param filename file which was requested to include in source + * @param stream stream to pass string of the requested header to + * @return std::istream* + *---------------------------------------------------------------------------**/ std::istream* headersCode(std::string filename, std::iostream& stream) { if (filename == "operation.h") { stream << code::operation; diff --git a/cpp/src/binary/jit/core/launcher.h b/cpp/src/binary/jit/core/launcher.h index 1cfdef430704..5d56cd4274ac 100644 --- a/cpp/src/binary/jit/core/launcher.h +++ b/cpp/src/binary/jit/core/launcher.h @@ -28,6 +28,10 @@ namespace jit { std::istream* headersCode(std::string filename, std::iostream& stream); + /**---------------------------------------------------------------------------* + * @brief Class used to handle compilation and execution of JIT kernels + * + *---------------------------------------------------------------------------**/ class Launcher { public: static Launcher launch() { @@ -47,8 +51,22 @@ namespace jit { Launcher& operator=(const Launcher&) = delete; public: + /**---------------------------------------------------------------------------* + * @brief Set the kernel name that this launcher will compile and launch + * + * @param value kernel name + *---------------------------------------------------------------------------**/ Launcher& kernel(std::string&& value); + /**---------------------------------------------------------------------------* + * @brief Method to generate vector containing all template types for a JIT + * kernel. This vector is used to instantiate the kernel code for one set of types + * + * @tparam Args Output dtype, LHS dtype, RHS dtype + * @param type Operator type (direct (lhs op rhs) or reverse (rhs op lhs)) + * @param args gdf_column* output, lhs, rhs + * @return Launcher& ref to this launcehr object + *---------------------------------------------------------------------------**/ template Launcher& instantiate(gdf_binary_operator ope, Operator::Type type, Args&& ... args) { Operator operatorSelector; @@ -56,14 +74,28 @@ namespace jit { return *this; } + /**---------------------------------------------------------------------------* + * @brief Handle the Jitify API to instantiate and launch using information + * contained in the members of `this` + * + * @param out[out] Output column + * @param lhs[in] LHS column + * @param rhs[in] RHS scalar (single value) + * @return gdf_error + *---------------------------------------------------------------------------**/ gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs); + /**---------------------------------------------------------------------------* + * @brief Handle the Jitify API to instantiate and launch using information + * contained in the members of `this` + * + * @param out[out] Output column + * @param lhs[in] LHS column + * @param rhs[in] RHS column + * @return gdf_error + *---------------------------------------------------------------------------**/ gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_column* rhs); - gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_scalar* def); - - gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_column* rhs, gdf_scalar* def); - private: std::vector compilerFlags { "-std=c++14" }; std::vector headersName { "operation.h" , "traits.h" }; From a55f1110f7ee4870d53ee90c0c4688c9a1f1d22f Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 21 Feb 2019 04:30:31 +0530 Subject: [PATCH 19/51] Some cleanup of traits. --- cpp/src/binary/jit/code/kernel.cpp | 2 - cpp/src/binary/jit/code/operation.cpp | 1 + cpp/src/binary/jit/code/traits.cpp | 68 +++++++++------------------ 3 files changed, 22 insertions(+), 49 deletions(-) diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 516ffec28774..968b40c9754d 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -23,8 +23,6 @@ namespace code { const char* kernel = R"***( - #include - #include "traits.h" #include "operation.h" template diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp index 8787e8490edc..9a7e493a6c76 100644 --- a/cpp/src/binary/jit/code/operation.cpp +++ b/cpp/src/binary/jit/code/operation.cpp @@ -23,6 +23,7 @@ namespace code { const char* operation = R"***( #pragma once + #include "traits.h" struct Add { template diff --git a/cpp/src/binary/jit/code/traits.cpp b/cpp/src/binary/jit/code/traits.cpp index e9d79c640ee4..e192ee0c31be 100644 --- a/cpp/src/binary/jit/code/traits.cpp +++ b/cpp/src/binary/jit/code/traits.cpp @@ -23,38 +23,39 @@ namespace code { const char* traits = R"***( #pragma once + #include + #include - struct IntegralSigned {}; - - struct IntegralUnsigned {}; - + // ------------------------------------------------------------------------- + // Simplifying std::is_integral + template + constexpr bool isIntegral = std::is_integral::value; + // ------------------------------------------------------------------------- + // type_traits cannot tell the difference between float and double template - constexpr bool isIntegral = false; - - template <> - constexpr bool isIntegral = true; + constexpr bool isFloat = false; template <> - constexpr bool isIntegral = true; + constexpr bool isFloat = true; - template <> - constexpr bool isIntegral = true; - template <> - constexpr bool isIntegral = true; + template + constexpr bool isDouble = false; template <> - constexpr bool isIntegral = true; + constexpr bool isDouble = true; - template <> - constexpr bool isIntegral = true; + // ------------------------------------------------------------------------- + // Simplifying std::enable_if + template + using enableIf = typename std::enable_if::type; - template <> - constexpr bool isIntegral = true; + // ------------------------------------------------------------------------- + // Implementing std::common_type for two types + struct IntegralSigned {}; - template <> - constexpr bool isIntegral = true; + struct IntegralUnsigned {}; @@ -102,19 +103,6 @@ R"***( constexpr bool isIntegralUnsigned = true; - template - constexpr bool isFloat = false; - - template <> - constexpr bool isFloat = true; - - - template - constexpr bool isDouble = false; - - template <> - constexpr bool isDouble = true; - template constexpr int MaxSize = ((sizeof(X) < sizeof(Y)) ? sizeof(Y) : sizeof(X)); @@ -185,20 +173,6 @@ R"***( - template - struct helperEnableIf - {}; - - template - struct helperEnableIf { - using type = T; - }; - - template - using enableIf = typename helperEnableIf::type; - - - template struct HelperCommonNumber {}; From 96f83e71e94daae4ae5094ce6327f6ea343aef26 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 21 Feb 2019 20:04:34 +0530 Subject: [PATCH 20/51] modified `scalar_wrapper` to work with updated type_dispatcher --- cpp/tests/utilities/scalar_wrapper.cuh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/tests/utilities/scalar_wrapper.cuh b/cpp/tests/utilities/scalar_wrapper.cuh index d1d202c2c11e..517a492d366e 100644 --- a/cpp/tests/utilities/scalar_wrapper.cuh +++ b/cpp/tests/utilities/scalar_wrapper.cuh @@ -152,7 +152,7 @@ struct scalar_wrapper { cudaMemcpyHostToDevice)); // Fill the gdf_scalar members - the_scalar.dtype = cudf::type_to_gdf_dtype::value; + the_scalar.dtype = cudf::gdf_dtype_of(); } gdf_scalar the_scalar; From fea6751e8be32dd9c266241c8b01c1e542d5ea87 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 21 Feb 2019 20:10:28 +0530 Subject: [PATCH 21/51] fix merge conflict that wasn't detected earlier --- python/cudf/dataframe/numerical.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/python/cudf/dataframe/numerical.py b/python/cudf/dataframe/numerical.py index efcc996d14c4..10ff6333f16f 100644 --- a/python/cudf/dataframe/numerical.py +++ b/python/cudf/dataframe/numerical.py @@ -394,14 +394,7 @@ def find_and_replace(self, to_replace, value): def numeric_column_binop(lhs, rhs, op, out_dtype): -<<<<<<< HEAD - nvtx_range_push("PYGDF_BINARY_OP", "orange") -======= - if lhs.dtype != rhs.dtype: - raise TypeError('{} != {}'.format(lhs.dtype, rhs.dtype)) - nvtx_range_push("CUDF_BINARY_OP", "orange") ->>>>>>> bug-binops-nullmask-and # Allocate output masked = lhs.has_null_mask or rhs.has_null_mask out = columnops.column_empty_like(lhs, dtype=out_dtype, masked=masked) From bf4dc61b16ec2390900e6c52789330e4f420a6e1 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Fri, 22 Feb 2019 03:32:57 +0530 Subject: [PATCH 22/51] Removed valid mask binary op from JIT kernel And added regular compiled version. Regular version also calculates new null_count --- cpp/src/binary/jit/code/kernel.cpp | 13 --------- cpp/src/binary/jit/core/binop.cpp | 43 ++++++++++++++++++++++++++++++ cpp/src/bitmask/bitmask_ops.cu | 35 +++++++++++++----------- cpp/src/bitmask/bitmask_ops.h | 1 + 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 968b40c9754d..ac3fc4266e40 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -40,12 +40,6 @@ R"***( for (int i=start; i(lhs_data[i], rhs_data[0]); - - if ((out_valid != nullptr) && (i % warpSize) == 0) { - int index = i / warpSize; - uint32_t lhs_valid_word = (lhs_valid != nullptr) ? lhs_valid[index] : 0xffffffff; - out_valid[index] = lhs_valid_word; - } } } @@ -64,13 +58,6 @@ R"***( for (int i=start; i(lhs_data[i], rhs_data[i]); - - if ((out_valid != nullptr) && (i % warpSize) == 0) { - int index = i / warpSize; - uint32_t lhs_valid_word = (lhs_valid != nullptr) ? lhs_valid[index] : 0xffffffff; - uint32_t rhs_valid_word = (rhs_valid != nullptr) ? rhs_valid[index] : 0xffffffff; - out_valid[index] = lhs_valid_word & rhs_valid_word; - } } } )***"; diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index d07e126fb59c..1b6f672f97d3 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -17,11 +17,48 @@ #include "binary/jit/core/launcher.h" #include "binary/jit/util/operator.h" +#include "bitmask/bitmask_ops.h" #include "utilities/error_utils.h" #include "cudf.h" namespace cudf { namespace binops { + + + gdf_error binary_valid_mask_and(gdf_size_type & out_null_count, + gdf_valid_type * valid_out, + gdf_valid_type * valid_left, + gdf_valid_type * valid_right, + gdf_size_type num_values) { + if (num_values == 0) { + out_null_count = 0; + return GDF_SUCCESS; + } + + GDF_REQUIRE((valid_out != nullptr), GDF_DATASET_EMPTY) + + cudaStream_t stream; + cudaStreamCreate(&stream); + + if ( valid_left != nullptr && valid_right != nullptr ) { + return apply_bitmask_to_bitmask(out_null_count, valid_out, valid_left, valid_right, stream, num_values); + } + + gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); + + if ( valid_left == nullptr && valid_right != nullptr ) { + CUDA_TRY( cudaMemcpy(valid_out, valid_right, num_values, cudaMemcpyDeviceToDevice) ); + } + else if ( valid_left != nullptr && valid_right == nullptr ) { + CUDA_TRY( cudaMemcpy(valid_out, valid_left, num_values, cudaMemcpyDeviceToDevice) ); + } + else if ( valid_left == nullptr && valid_right == nullptr ) { + CUDA_TRY( cudaMemset(valid_out, 0xff, num_values) ); + } + + return update_null_count(out_null_count, valid_out, stream, num_values); + } + namespace jit { gdf_error binary_operation(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) { @@ -40,6 +77,8 @@ namespace jit { GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) + binary_valid_mask_and(out->null_count, out->valid, nullptr, rhs->valid, rhs->size); + Launcher::launch().kernel("kernel_v_s") .instantiate(ope, Operator::Type::Reverse, out, rhs, lhs) .launch(out, rhs, lhs); @@ -63,6 +102,8 @@ namespace jit { GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) + binary_valid_mask_and(out->null_count, out->valid, lhs->valid, nullptr, lhs->size); + Launcher::launch().kernel("kernel_v_s") .instantiate(ope, Operator::Type::Direct, out, lhs, rhs) .launch(out, lhs, rhs); @@ -86,6 +127,8 @@ namespace jit { GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) + binary_valid_mask_and(out->null_count, out->valid, lhs->valid, rhs->valid, rhs->size); + Launcher::launch().kernel("kernel_v_v") .instantiate(ope, Operator::Type::Direct, out, lhs, rhs) .launch(out, lhs, rhs); diff --git a/cpp/src/bitmask/bitmask_ops.cu b/cpp/src/bitmask/bitmask_ops.cu index 4f33452cb791..0e2212f0dd00 100644 --- a/cpp/src/bitmask/bitmask_ops.cu +++ b/cpp/src/bitmask/bitmask_ops.cu @@ -59,24 +59,12 @@ gdf_error all_bitmask_on(gdf_valid_type * valid_out, gdf_size_type & out_null_co return GDF_SUCCESS; } -gdf_error apply_bitmask_to_bitmask(gdf_size_type & out_null_count, gdf_valid_type * valid_out, gdf_valid_type * valid_left, gdf_valid_type * valid_right, - cudaStream_t stream, gdf_size_type num_values){ - +gdf_error update_null_count(gdf_size_type & out_null_count, gdf_valid_type * valid, cudaStream_t stream, gdf_size_type num_values) { gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); - thrust::device_ptr valid_out_ptr = thrust::device_pointer_cast(valid_out); - thrust::device_ptr valid_left_ptr = thrust::device_pointer_cast(valid_left); - //here we are basically figuring out what is the last pointed to unsigned char that can contain part of the bitmask - thrust::device_ptr valid_left_end_ptr = thrust::device_pointer_cast(valid_left + num_chars_bitmask ); - thrust::device_ptr valid_right_ptr = thrust::device_pointer_cast(valid_right); - - - thrust::transform(rmm::exec_policy(stream)->on(stream), thrust::detail::make_normal_iterator(valid_left_ptr), - thrust::detail::make_normal_iterator(valid_left_end_ptr), thrust::detail::make_normal_iterator(valid_right_ptr), - thrust::detail::make_normal_iterator(valid_out_ptr), thrust::bit_and()); - + thrust::device_ptr valid_out_ptr = thrust::device_pointer_cast(valid); char * last_char = new char[1]; - cudaError_t error = cudaMemcpyAsync(last_char,valid_out + ( num_chars_bitmask-1),sizeof(gdf_valid_type),cudaMemcpyDeviceToHost,stream); + cudaError_t error = cudaMemcpyAsync(last_char,valid + ( num_chars_bitmask-1),sizeof(gdf_valid_type),cudaMemcpyDeviceToHost,stream); rmm::device_vector bit_mask_null_counts_device(bit_mask_null_counts); @@ -93,3 +81,20 @@ gdf_error apply_bitmask_to_bitmask(gdf_size_type & out_null_count, gdf_valid_typ return GDF_SUCCESS; } +gdf_error apply_bitmask_to_bitmask(gdf_size_type & out_null_count, gdf_valid_type * valid_out, gdf_valid_type * valid_left, gdf_valid_type * valid_right, + cudaStream_t stream, gdf_size_type num_values){ + + gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); + thrust::device_ptr valid_out_ptr = thrust::device_pointer_cast(valid_out); + thrust::device_ptr valid_left_ptr = thrust::device_pointer_cast(valid_left); + //here we are basically figuring out what is the last pointed to unsigned char that can contain part of the bitmask + thrust::device_ptr valid_left_end_ptr = thrust::device_pointer_cast(valid_left + num_chars_bitmask ); + thrust::device_ptr valid_right_ptr = thrust::device_pointer_cast(valid_right); + + + thrust::transform(rmm::exec_policy(stream)->on(stream), thrust::detail::make_normal_iterator(valid_left_ptr), + thrust::detail::make_normal_iterator(valid_left_end_ptr), thrust::detail::make_normal_iterator(valid_right_ptr), + thrust::detail::make_normal_iterator(valid_out_ptr), thrust::bit_and()); + + return update_null_count(out_null_count, valid_out, stream, num_values); +} diff --git a/cpp/src/bitmask/bitmask_ops.h b/cpp/src/bitmask/bitmask_ops.h index dedf1fc6f506..721daa4554ae 100644 --- a/cpp/src/bitmask/bitmask_ops.h +++ b/cpp/src/bitmask/bitmask_ops.h @@ -7,6 +7,7 @@ gdf_error all_bitmask_on(gdf_valid_type * valid_out, gdf_size_type & out_null_count, gdf_size_type num_values, cudaStream_t stream); +gdf_error update_null_count(gdf_size_type & out_null_count, gdf_valid_type * valid, cudaStream_t stream, gdf_size_type num_values); gdf_error apply_bitmask_to_bitmask(gdf_size_type & out_null_count, gdf_valid_type * valid_out, gdf_valid_type * valid_left, gdf_valid_type * valid_right, cudaStream_t stream, gdf_size_type num_values); From 358e0c08ffb972ec5b750a19f0c250fedced96ee Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Fri, 22 Feb 2019 20:43:57 +0530 Subject: [PATCH 23/51] fix bug in null mask calculation --- cpp/src/binary/jit/core/binop.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index 1b6f672f97d3..08dab07e6c2f 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -47,13 +47,13 @@ namespace binops { gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); if ( valid_left == nullptr && valid_right != nullptr ) { - CUDA_TRY( cudaMemcpy(valid_out, valid_right, num_values, cudaMemcpyDeviceToDevice) ); + CUDA_TRY( cudaMemcpy(valid_out, valid_right, num_chars_bitmask, cudaMemcpyDeviceToDevice) ); } else if ( valid_left != nullptr && valid_right == nullptr ) { - CUDA_TRY( cudaMemcpy(valid_out, valid_left, num_values, cudaMemcpyDeviceToDevice) ); + CUDA_TRY( cudaMemcpy(valid_out, valid_left, num_chars_bitmask, cudaMemcpyDeviceToDevice) ); } else if ( valid_left == nullptr && valid_right == nullptr ) { - CUDA_TRY( cudaMemset(valid_out, 0xff, num_values) ); + CUDA_TRY( cudaMemset(valid_out, 0xff, num_chars_bitmask) ); } return update_null_count(out_null_count, valid_out, stream, num_values); From ca0b31f604761313f8da6d634b23664004656218 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Mon, 25 Feb 2019 23:49:34 +0530 Subject: [PATCH 24/51] We didn't need common_type after all --- cpp/src/binary/jit/code/operation.cpp | 90 ++++++--------- cpp/src/binary/jit/code/traits.cpp | 152 -------------------------- 2 files changed, 34 insertions(+), 208 deletions(-) diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp index 9a7e493a6c76..e7078241726d 100644 --- a/cpp/src/binary/jit/code/operation.cpp +++ b/cpp/src/binary/jit/code/operation.cpp @@ -28,8 +28,7 @@ R"***( struct Add { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x + (Common)y); + return ((TypeOut)x + (TypeOut)y); } }; @@ -38,24 +37,21 @@ R"***( struct Sub { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x - (Common)y); + return ((TypeOut)x - (TypeOut)y); } }; struct RSub { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)y - (Common)x); + return ((TypeOut)y - (TypeOut)x); } }; struct Mul { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x * (Common)y); + return ((TypeOut)x * (TypeOut)y); } }; @@ -64,44 +60,42 @@ R"***( struct Div { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x / (Common)y); + return ((TypeOut)x / (TypeOut)y); } }; struct RDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)y / (Common)x); + return ((TypeOut)y / (TypeOut)x); } }; struct TrueDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)((double)x / (double)y); + return ((double)x / (double)y); } }; struct RTrueDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)((double)y / (double)x); + return ((double)y / (double)x); } }; struct FloorDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)floor((double)x / (double)y); + return floor((double)x / (double)y); } }; struct RFloorDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)floor((double)y / (double)x); + return floor((double)y / (double)x); } }; @@ -109,28 +103,25 @@ R"***( template , - enableIf<(isIntegral)>* = nullptr> + enableIf<(isIntegral)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)((Common)x % (Common)y); + return ((TypeOut)x % (TypeOut)y); } template , - enableIf<(isFloat)>* = nullptr> + enableIf<(isFloat)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)fmodf((Common)x, (Common)y); + return fmodf((TypeOut)x, (TypeOut)y); } template , - enableIf<(isDouble)>* = nullptr> + enableIf<(isDouble)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)fmod((Common)x, (Common)y); + return fmod((TypeOut)x, (TypeOut)y); } }; @@ -138,50 +129,46 @@ R"***( template , - enableIf<(isIntegral)>* = nullptr> + enableIf<(isIntegral)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)((Common)y % (Common)x); + return ((TypeOut)y % (TypeOut)x); } template , - enableIf<(isFloat)>* = nullptr> + enableIf<(isFloat)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)fmodf((Common)y, (Common)x); + return fmodf((TypeOut)y, (TypeOut)x); } template , - enableIf<(isDouble)>* = nullptr> + enableIf<(isDouble)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)fmod((Common)y, (Common)x); + return fmod((TypeOut)y, (TypeOut)x); } }; struct Pow { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)pow((double)x, (double)y); + return pow((double)x, (double)y); } }; struct RPow { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return (TypeOut)pow((double)y, (double)x); + return pow((double)y, (double)x); } }; struct Equal { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x == (Common)y); + return (x == y); } }; @@ -190,8 +177,7 @@ R"***( struct NotEqual { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x != (Common)y); + return (x != y); } }; @@ -200,64 +186,56 @@ R"***( struct Less { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x < (Common)y); + return (x < y); } }; struct RLess { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)y < (Common)x); + return (y < x); } }; struct Greater { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x > (Common)y); + return (x > y); } }; struct RGreater { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)y > (Common)x); + return (y > x); } }; struct LessEqual { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x <= (Common)y); + return (x <= y); } }; struct RLessEqual { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)y <= (Common)x); + return (y <= x); } }; struct GreaterEqual { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)x >= (Common)y); + return (x >= y); } }; struct RGreaterEqual { template static TypeOut operate(TypeLhs x, TypeRhs y) { - using Common = CommonNumber; - return (TypeOut)((Common)y >= (Common)x); + return (y >= x); } }; )***"; diff --git a/cpp/src/binary/jit/code/traits.cpp b/cpp/src/binary/jit/code/traits.cpp index e192ee0c31be..805d017429fa 100644 --- a/cpp/src/binary/jit/code/traits.cpp +++ b/cpp/src/binary/jit/code/traits.cpp @@ -51,158 +51,6 @@ R"***( template using enableIf = typename std::enable_if::type; - // ------------------------------------------------------------------------- - // Implementing std::common_type for two types - struct IntegralSigned {}; - - struct IntegralUnsigned {}; - - - - template - constexpr bool isFloatingPoint = false; - - template <> - constexpr bool isFloatingPoint = true; - - template <> - constexpr bool isFloatingPoint = true; - - - - template - constexpr bool isIntegralSigned = false; - - template <> - constexpr bool isIntegralSigned = true; - - template <> - constexpr bool isIntegralSigned = true; - - template <> - constexpr bool isIntegralSigned = true; - - template <> - constexpr bool isIntegralSigned = true; - - - - template - constexpr bool isIntegralUnsigned = false; - - template <> - constexpr bool isIntegralUnsigned = true; - - template <> - constexpr bool isIntegralUnsigned = true; - - template <> - constexpr bool isIntegralUnsigned = true; - - template <> - constexpr bool isIntegralUnsigned = true; - - - - template - constexpr int MaxSize = ((sizeof(X) < sizeof(Y)) ? sizeof(Y) : sizeof(X)); - - template - struct HelperIntegralMap; - - template <> - struct HelperIntegralMap<1, IntegralSigned> { - using Type = int8_t; - }; - - template <> - struct HelperIntegralMap<2, IntegralSigned> { - using Type = int16_t; - }; - - template <> - struct HelperIntegralMap<4, IntegralSigned> { - using Type = int32_t; - }; - - template <> - struct HelperIntegralMap<8, IntegralSigned> { - using Type = int64_t; - }; - - template <> - struct HelperIntegralMap<1, IntegralUnsigned> { - using Type = uint8_t; - }; - - template <> - struct HelperIntegralMap<2, IntegralUnsigned> { - using Type = uint16_t; - }; - - template <> - struct HelperIntegralMap<4, IntegralUnsigned> { - using Type = uint32_t; - }; - - template <> - struct HelperIntegralMap<8, IntegralUnsigned> { - using Type = uint64_t; - }; - - template - using IntegralMap = typename HelperIntegralMap::Type; - - - - template - struct helperIf; - - template - struct helperIf { - using type = T; - }; - - template - struct helperIf { - using type = F; - }; - - template - using If = typename helperIf::type; - - - - template - struct HelperCommonNumber {}; - - template - struct HelperCommonNumber || isFloatingPoint)>> { - using Type = If<(sizeof(Lhs) == 8 || sizeof(Rhs) == 8), double, float>; - }; - - template - struct HelperCommonNumber && isIntegralSigned)>> { - using Type = IntegralMap<(MaxSize), IntegralSigned>; - }; - - template - struct HelperCommonNumber && isIntegralUnsigned)>> { - using Type = IntegralMap<(MaxSize), IntegralSigned>; - }; - - template - struct HelperCommonNumber && isIntegralSigned)>> { - using Type = IntegralMap<(MaxSize), IntegralSigned>; - }; - - template - struct HelperCommonNumber && isIntegralUnsigned)>> { - using Type = IntegralMap<(MaxSize), IntegralUnsigned>; - }; - - template - using CommonNumber = typename HelperCommonNumber::Type; )***"; } // namespace code From b269ee45de047f2c65d167e30bd74a6b9295ccb7 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Tue, 26 Feb 2019 02:23:35 +0530 Subject: [PATCH 25/51] Removed passing valid mask pointers to jit kernels --- cpp/src/binary/jit/code/kernel.cpp | 6 ++---- cpp/src/binary/jit/core/launcher.cpp | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index ac3fc4266e40..99ecb030367c 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -28,8 +28,7 @@ R"***( template __global__ void kernel_v_s(int size, - TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data, - uint32_t* out_valid, uint32_t* lhs_valid) { + TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data) { int tid = threadIdx.x; int blkid = blockIdx.x; int blksz = blockDim.x; @@ -46,8 +45,7 @@ R"***( template __global__ void kernel_v_v(int size, - TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data, - uint32_t* out_valid, uint32_t* lhs_valid, uint32_t* rhs_valid) { + TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data) { int tid = threadIdx.x; int blkid = blockIdx.x; int blksz = blockDim.x; diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index dcdba164dee0..6ef013d854bc 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -73,8 +73,7 @@ namespace jit { .instantiate(arguments) .configure_1d_max_occupancy() .launch(out->size, - out->data, lhs->data, rhs->data, - out->valid, lhs->valid); + out->data, lhs->data, rhs->data); return GDF_SUCCESS; } @@ -84,8 +83,7 @@ namespace jit { .instantiate(arguments) .configure_1d_max_occupancy() .launch(out->size, - out->data, lhs->data, rhs->data, - out->valid, lhs->valid, rhs->valid); + out->data, lhs->data, rhs->data); return GDF_SUCCESS; } From 322e4a55afaa5362028a9f536d07c5da73857a78 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Tue, 26 Feb 2019 03:30:11 +0530 Subject: [PATCH 26/51] Jit kernel now uses gdf_size_type - Added Stringify target - Added dynamically generated types.h.jit --- cpp/CMakeLists.txt | 16 ++++++++++++++++ cpp/src/binary/jit/code/kernel.cpp | 9 +++++---- cpp/src/binary/jit/core/launcher.cpp | 5 +++++ cpp/src/binary/jit/core/launcher.h | 4 ++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index e19169095e28..13851eeb54f8 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -221,6 +221,22 @@ add_library(cudf SHARED #Override RPATH for cudf SET_TARGET_PROPERTIES(cudf PROPERTIES BUILD_RPATH "\$ORIGIN") +################################################################################################### +# - jitify ---------------------------------------------------------------------------------------- + +add_executable(stringify "${CMAKE_SOURCE_DIR}/thirdparty/jitify/stringify.cpp") +execute_process(WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include) + +add_custom_target(stringify_run + COMMAND ${CMAKE_BINARY_DIR}/stringify cudf/types.h > ${CMAKE_BINARY_DIR}/include/types.h.jit + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include + COMMENT "stringify header types.h" + DEPENDS stringify +) + +add_dependencies(cudf stringify_run) + ################################################################################################### # - build options --------------------------------------------------------------------------------- diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 99ecb030367c..24a2959c89c9 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -24,10 +24,11 @@ namespace code { const char* kernel = R"***( #include "operation.h" + #include "cudf/types.h" template __global__ - void kernel_v_s(int size, + void kernel_v_s(gdf_size_type size, TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data) { int tid = threadIdx.x; int blkid = blockIdx.x; @@ -37,14 +38,14 @@ R"***( int start = tid + blkid * blksz; int step = blksz * gridsz; - for (int i=start; i(lhs_data[i], rhs_data[0]); } } template __global__ - void kernel_v_v(int size, + void kernel_v_v(gdf_size_type size, TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data) { int tid = threadIdx.x; int blkid = blockIdx.x; @@ -54,7 +55,7 @@ R"***( int start = tid + blkid * blksz; int step = blksz * gridsz; - for (int i=start; i(lhs_data[i], rhs_data[i]); } } diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index 6ef013d854bc..297c514b2cf0 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -17,6 +17,7 @@ #include "binary/jit/core/launcher.h" #include "binary/jit/code/code.h" +#include "types.h.jit" #include namespace cudf { @@ -35,6 +36,10 @@ namespace jit { static thread_local jitify::JitCache JitCache; #endif + const std::vector Launcher::compilerFlags { "-std=c++14" }; + const std::vector Launcher::headersName + { "operation.h" , "traits.h" , cudf_types_h }; + /**---------------------------------------------------------------------------* * @brief Used to provide Jitify with strings that should be used as headers * during JIT compilation. diff --git a/cpp/src/binary/jit/core/launcher.h b/cpp/src/binary/jit/core/launcher.h index 5d56cd4274ac..aea63fd37f7e 100644 --- a/cpp/src/binary/jit/core/launcher.h +++ b/cpp/src/binary/jit/core/launcher.h @@ -97,8 +97,8 @@ namespace jit { gdf_error launch(gdf_column* out, gdf_column* lhs, gdf_column* rhs); private: - std::vector compilerFlags { "-std=c++14" }; - std::vector headersName { "operation.h" , "traits.h" }; + static const std::vector compilerFlags; + static const std::vector headersName; private: jitify::Program program; From 35c2c46af5b38c5624b0a3632c212a8a89320783 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 27 Feb 2019 00:25:36 +0530 Subject: [PATCH 27/51] Changed `getTypeName` to use compiler generated string instead of hardcoded --- cpp/src/binary/jit/util/operator.cpp | 2 +- cpp/src/binary/jit/util/type.cpp | 45 +++++++++++++++------------- cpp/src/binary/jit/util/type.h | 5 ++-- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/cpp/src/binary/jit/util/operator.cpp b/cpp/src/binary/jit/util/operator.cpp index 0c5226b7ba8c..03aef9c77347 100644 --- a/cpp/src/binary/jit/util/operator.cpp +++ b/cpp/src/binary/jit/util/operator.cpp @@ -34,7 +34,7 @@ namespace jit { buffer[0] = 'R'; buffer[1] = '\0'; } - strcat(buffer, jit::getOperatorName(ope)); + strcat(buffer, jit::getOperatorName(ope).data()); return buffer; } diff --git a/cpp/src/binary/jit/util/type.cpp b/cpp/src/binary/jit/util/type.cpp index 8ba3bdda9c94..41fa459df5e7 100644 --- a/cpp/src/binary/jit/util/type.cpp +++ b/cpp/src/binary/jit/util/type.cpp @@ -16,34 +16,37 @@ */ #include "binary/jit/util/type.h" +#include "utilities/type_dispatcher.hpp" namespace cudf { namespace binops { namespace jit { - const char* getTypeName(gdf_dtype type) { - switch (type) { - case GDF_INT8: - return "int8_t"; - case GDF_INT16: - return "int16_t"; - case GDF_INT32: - case GDF_DATE32: - return "int32_t"; - case GDF_INT64: - case GDF_DATE64: - case GDF_TIMESTAMP: - return "int64_t"; - case GDF_FLOAT32: - return "float"; - case GDF_FLOAT64: - return "double"; - default: - return "double"; + struct type_name { + template + CUDA_HOST_DEVICE_CALLABLE + std::string operator()() { +#if defined(__clang__) || defined(__GNUC__) + std::string p = __PRETTY_FUNCTION__; + std::string search_str = "T = "; + size_t start_pos = p.find(search_str) + search_str.size(); + std::string wrapper_str = "wrapper<"; + size_t wrapper_pos = p.find(wrapper_str, start_pos); + if (wrapper_pos != std::string::npos) + start_pos = wrapper_pos + wrapper_str.size(); + size_t end_pos = p.find_first_of(",;]", start_pos); + return p.substr(start_pos, end_pos - start_pos); +#else +# error Only clang and gcc supported +#endif } - } + }; - const char* getOperatorName(gdf_binary_operator ope) { + std::string getTypeName(gdf_dtype type) { + return type_dispatcher(type, type_name()); + } + + std::string getOperatorName(gdf_binary_operator ope) { switch (ope) { case GDF_ADD: return "Add"; diff --git a/cpp/src/binary/jit/util/type.h b/cpp/src/binary/jit/util/type.h index 379e2f14db99..ca7c427c7776 100644 --- a/cpp/src/binary/jit/util/type.h +++ b/cpp/src/binary/jit/util/type.h @@ -19,14 +19,15 @@ #define GDF_BINARY_OPERATION_JIT_UTIL_TYPE_H #include "cudf.h" +#include namespace cudf { namespace binops { namespace jit { - const char* getTypeName(gdf_dtype type); + std::string getTypeName(gdf_dtype type); - const char* getOperatorName(gdf_binary_operator ope); + std::string getOperatorName(gdf_binary_operator ope); } } From d93fa0b6f235fe50c57c2d0329c0881014372a58 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 27 Feb 2019 00:27:31 +0530 Subject: [PATCH 28/51] style fix --- python/cudf/dataframe/numerical.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/cudf/dataframe/numerical.py b/python/cudf/dataframe/numerical.py index bda47dde6771..1cbe3a1d1053 100644 --- a/python/cudf/dataframe/numerical.py +++ b/python/cudf/dataframe/numerical.py @@ -410,7 +410,7 @@ def numeric_column_binop(lhs, rhs, op, out_dtype): else: # Use compiled implementation null_count = _gdf.apply_binaryop(_binary_impl[op], lhs, rhs, out) - + out = out.replace(null_count=null_count) result = out.view(NumericalColumn, dtype=out_dtype) nvtx_range_pop() From df641c40aa8a5044e4ccf26b9d49cb7d91b400d3 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 27 Feb 2019 01:00:46 +0530 Subject: [PATCH 29/51] Added modulo to index because we support it now. --- python/cudf/dataframe/index.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/cudf/dataframe/index.py b/python/cudf/dataframe/index.py index c59ed9a14820..946cfd05ab6a 100644 --- a/python/cudf/dataframe/index.py +++ b/python/cudf/dataframe/index.py @@ -144,6 +144,12 @@ def __mul__(self, other): def __rmul__(self, other): return self._apply_op('__rmul__', other) + def __mod__(self, other): + return self._apply_op('__mod__', other) + + def __rmod__(self, other): + return self._apply_op('__rmod__', other) + def __pow__(self, other): return self._apply_op('__pow__', other) From aaae814fcf4df208977ad5643e68bcbaf8f3968c Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 27 Feb 2019 01:04:38 +0530 Subject: [PATCH 30/51] fixing pytests. replaced `np.testing.assert_equal` with `np.testing.assert_almost_equal` --- python/cudf/tests/test_binops.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/cudf/tests/test_binops.py b/python/cudf/tests/test_binops.py index 7d5d1dc81196..46752481e24c 100644 --- a/python/cudf/tests/test_binops.py +++ b/python/cudf/tests/test_binops.py @@ -40,7 +40,7 @@ def test_series_binop(binop, obj_class): if obj_class == 'Index': result = Series(result) - np.testing.assert_equal(result.to_array(), binop(arr, arr)) + np.testing.assert_almost_equal(result.to_array(), binop(arr, arr)) @pytest.mark.parametrize('obj_class', ['Series', 'Index']) @@ -57,7 +57,7 @@ def test_series_binop_scalar(nelem, binop, obj_class): if obj_class == 'Index': result = Series(result) - np.testing.assert_equal(result.to_array(), binop(arr, rhs)) + np.testing.assert_almost_equal(result.to_array(), binop(arr, rhs)) _cmpops = [ @@ -72,7 +72,7 @@ def test_series_binop_scalar(nelem, binop, obj_class): @pytest.mark.parametrize('obj_class', ['Series', 'Index']) @pytest.mark.parametrize('cmpop', _cmpops) -@pytest.mark.parametrize('dtype', ['int8', 'int16', 'int32', 'int64', +@pytest.mark.parametrize('dtype', ['int8', 'int32', 'int64', 'float32', 'float64', 'datetime64[ms]']) def test_series_compare(cmpop, obj_class, dtype): arr1 = np.random.randint(0, 100, 100).astype(dtype) From e0c8faba1961c64476ead87d9f32f77b4452424c Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 27 Feb 2019 02:15:51 +0530 Subject: [PATCH 31/51] fix inlining for util functions. required for using util functions in tests. especially tests which have multiple source files --- cpp/src/utilities/cudf_utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/src/utilities/cudf_utils.h b/cpp/src/utilities/cudf_utils.h index 0a7b4f53819e..cccaa9bc59d5 100644 --- a/cpp/src/utilities/cudf_utils.h +++ b/cpp/src/utilities/cudf_utils.h @@ -11,8 +11,8 @@ #define CUDA_DEVICE_CALLABLE __device__ __forceinline__ #define CUDA_LAUNCHABLE __global__ #else -#define CUDA_HOST_DEVICE_CALLABLE -#define CUDA_DEVICE_CALLABLE +#define CUDA_HOST_DEVICE_CALLABLE inline +#define CUDA_DEVICE_CALLABLE inline #define CUDA_LAUNCHABLE #endif From c5cbd8bbccc797bfd8ccfad46005f552a6285b50 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 27 Feb 2019 23:53:31 +0530 Subject: [PATCH 32/51] documentation update --- cpp/include/cudf/functions.h | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/cpp/include/cudf/functions.h b/cpp/include/cudf/functions.h index 589ce1c28b88..6cf396238888 100644 --- a/cpp/include/cudf/functions.h +++ b/cpp/include/cudf/functions.h @@ -617,11 +617,8 @@ gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output); * The function performs the binary operation of a gdf_scalar operand and a * gdf_column operand. * - * The valid field in the gdf_column output will be 1 (by bit) when the two - * operands (lhs and rhs) are not null. Otherwise, it will be 0 (by bit). - * - * It is required to set in an appropriate manner the fields in the gdf_scalar and - * gdf_column structs due to that the binary operation will not be performed. + * If the valid field in the gdf_column output is not nullptr, then the valid + * mask from rhs gdf_column is copied into the data pointer to by out->valid * * @param out (gdf_column) Output of the operation. * @param lhs (gdf_scalar) First operand of the operation. @@ -638,11 +635,8 @@ gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* lhs, gdf_column* * The function performs the binary operation of a gdf_column operand and a * gdf_scalar operand. * - * The valid field in the gdf_column output will be 1 (by bit) when the two - * operands (lhs and rhs) are not null. Otherwise, it will be 0 (by bit). - * - * It is required to set in an appropriate manner the fields in the gdf_scalar and - * gdf_column structs due to that the binary operation will not be performed. + * If the valid field in the gdf_column output is not nullptr, then the valid + * mask from lhs gdf_column is copied into the data pointer to by out->valid * * @param out (gdf_column) Output of the operation. * @param lhs (gdf_column) First operand of the operation. @@ -658,11 +652,8 @@ gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* * * The function performs the binary operation of two gdf_column operands. * - * The valid field in the gdf_column output will be 1 (by bit) when the two - * operands (lhs and rhs) are not null. Otherwise, it will be 0 (by bit). - * - * It is required to set in an appropriate manner the fields in the gdf_column - * struct due to that the binary operation will not be performed. + * If the valid field in the gdf_column output is not nullptr, then it will be + * filled with the bitwise AND of the valid masks of lhs and rhs gdf_column's * * @param out (gdf_column) Output of the operation. * @param lhs (gdf_column) First operand of the operation. From b5c729bf5bdf56326904705ddf76ce4c909161f9 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 27 Feb 2019 23:58:16 +0530 Subject: [PATCH 33/51] changed casts and traits in jit code --- cpp/src/binary/jit/code/operation.cpp | 60 +++++++++++++-------------- cpp/src/binary/jit/code/traits.cpp | 8 +--- 2 files changed, 31 insertions(+), 37 deletions(-) diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp index e7078241726d..2d2d8e9f7e56 100644 --- a/cpp/src/binary/jit/code/operation.cpp +++ b/cpp/src/binary/jit/code/operation.cpp @@ -28,7 +28,7 @@ R"***( struct Add { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)x + (TypeOut)y); + return (static_cast(x) + static_cast(y)); } }; @@ -37,21 +37,21 @@ R"***( struct Sub { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)x - (TypeOut)y); + return (static_cast(x) - static_cast(y)); } }; struct RSub { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)y - (TypeOut)x); + return (static_cast(y) - static_cast(x)); } }; struct Mul { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)x * (TypeOut)y); + return (static_cast(x) * static_cast(y)); } }; @@ -60,42 +60,42 @@ R"***( struct Div { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)x / (TypeOut)y); + return (static_cast(x) / static_cast(y)); } }; struct RDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)y / (TypeOut)x); + return (static_cast(y) / static_cast(x)); } }; struct TrueDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((double)x / (double)y); + return (static_cast(x) / static_cast(y)); } }; struct RTrueDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((double)y / (double)x); + return (static_cast(y) / static_cast(x)); } }; struct FloorDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return floor((double)x / (double)y); + return floor(static_cast(x) / static_cast(y)); } }; struct RFloorDiv { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return floor((double)y / (double)x); + return floor(static_cast(y) / static_cast(x)); } }; @@ -103,25 +103,25 @@ R"***( template )>* = nullptr> + enable_if_t<(is_integral_v)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)x % (TypeOut)y); + return (static_cast(x) % static_cast(y)); } template )>* = nullptr> + enable_if_t<(isFloat)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return fmodf((TypeOut)x, (TypeOut)y); + return fmodf(static_cast(x), static_cast(y)); } template )>* = nullptr> + enable_if_t<(isDouble)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return fmod((TypeOut)x, (TypeOut)y); + return fmod(static_cast(x), static_cast(y)); } }; @@ -129,39 +129,39 @@ R"***( template )>* = nullptr> + enable_if_t<(is_integral_v)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return ((TypeOut)y % (TypeOut)x); + return (static_cast(y) % static_cast(x)); } template )>* = nullptr> + enable_if_t<(isFloat)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return fmodf((TypeOut)y, (TypeOut)x); + return fmodf(static_cast(y), static_cast(x)); } template )>* = nullptr> + enable_if_t<(isDouble)>* = nullptr> static TypeOut operate(TypeLhs x, TypeRhs y) { - return fmod((TypeOut)y, (TypeOut)x); + return fmod(static_cast(y), static_cast(x)); } }; struct Pow { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return pow((double)x, (double)y); + return pow(static_cast(x), static_cast(y)); } }; struct RPow { template static TypeOut operate(TypeLhs x, TypeRhs y) { - return pow((double)y, (double)x); + return pow(static_cast(y), static_cast(x)); } }; @@ -251,30 +251,30 @@ R"***( * typename TypeLhs, * typename TypeRhs, * typename Common = CommonNumber, - * enableIf<(isIntegralSigned)>* = nullptr> + * enable_if_t<(isIntegralSigned)>* = nullptr> * __device__ * TypeOut operate(TypeLhs x, TypeRhs y) { - * return (TypeOut)((Common)x + (Common)y); + * return static_cast(t)((Common)x + (Common)y); * } * * template , - * enableIf<(isIntegralUnsigned)>* = nullptr> + * enable_if_t<(isIntegralUnsigned)>* = nullptr> * __device__ * TypeOut operate(TypeLhs x, TypeRhs y) { - * return (TypeOut)((Common)x + (Common)y); + * return static_cast(t)((Common)x + (Common)y); * } * * template , - * enableIf<(isFloatingPoint)>* = nullptr> + * enable_if_t<(isFloatingPoint)>* = nullptr> * __device__ * TypeOut operate(TypeLhs x, TypeRhs y) { - * return (TypeOut)((Common)x + (Common)y); + * return static_cast(t)((Common)x + (Common)y); * } * }; */ diff --git a/cpp/src/binary/jit/code/traits.cpp b/cpp/src/binary/jit/code/traits.cpp index 805d017429fa..fa86122c3d3f 100644 --- a/cpp/src/binary/jit/code/traits.cpp +++ b/cpp/src/binary/jit/code/traits.cpp @@ -29,7 +29,7 @@ R"***( // ------------------------------------------------------------------------- // Simplifying std::is_integral template - constexpr bool isIntegral = std::is_integral::value; + constexpr bool is_integral_v = std::is_integral::value; // ------------------------------------------------------------------------- // type_traits cannot tell the difference between float and double @@ -45,12 +45,6 @@ R"***( template <> constexpr bool isDouble = true; - - // ------------------------------------------------------------------------- - // Simplifying std::enable_if - template - using enableIf = typename std::enable_if::type; - )***"; } // namespace code From febbad6152d2ec418cd8afa88655c940bef6844e Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 28 Feb 2019 00:52:19 +0530 Subject: [PATCH 34/51] more doc changes. --- cpp/include/cudf/functions.h | 6 ++++++ cpp/src/binary/jit/util/type.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/cpp/include/cudf/functions.h b/cpp/include/cudf/functions.h index 6cf396238888..c021396afd2d 100644 --- a/cpp/include/cudf/functions.h +++ b/cpp/include/cudf/functions.h @@ -616,6 +616,8 @@ gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output); * * The function performs the binary operation of a gdf_scalar operand and a * gdf_column operand. + * + * The desired output type needs to be specified in out->dtype * * If the valid field in the gdf_column output is not nullptr, then the valid * mask from rhs gdf_column is copied into the data pointer to by out->valid @@ -635,6 +637,8 @@ gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* lhs, gdf_column* * The function performs the binary operation of a gdf_column operand and a * gdf_scalar operand. * + * The desired output type needs to be specified in out->dtype + * * If the valid field in the gdf_column output is not nullptr, then the valid * mask from lhs gdf_column is copied into the data pointer to by out->valid * @@ -652,6 +656,8 @@ gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* * * The function performs the binary operation of two gdf_column operands. * + * The desired output type needs to be specified in out->dtype + * * If the valid field in the gdf_column output is not nullptr, then it will be * filled with the bitwise AND of the valid masks of lhs and rhs gdf_column's * diff --git a/cpp/src/binary/jit/util/type.cpp b/cpp/src/binary/jit/util/type.cpp index 41fa459df5e7..8b611a066050 100644 --- a/cpp/src/binary/jit/util/type.cpp +++ b/cpp/src/binary/jit/util/type.cpp @@ -22,6 +22,25 @@ namespace cudf { namespace binops { namespace jit { + /**---------------------------------------------------------------------------* + * @brief Functor to get type name in string + * + * This functor uses the unofficial compiler macro __PRETTY_FUNCTION__ + * to obtain the function signature which contains the template type name. + * The type name is searched and extracted from the string. + * + * Example (clang): __PRETTY_FUNCTION__ = + * std::string type_name::operator()() [T = short] + * returns std::string("short") + * + * Example (gcc): __PRETTY_FUNCTION__ = + * std::__cxx11::string type_name::operator()() [with T = short int; std::__cxx11::string = std::__cxx11::basic_string] + * returns std::string("short int") + * + * In case the type is wrapped using `wrapper`, the extra string "wrapper<" is + * also skipped to get the underlying wrapped type. + * + *---------------------------------------------------------------------------**/ struct type_name { template CUDA_HOST_DEVICE_CALLABLE @@ -42,10 +61,22 @@ namespace jit { } }; + /**---------------------------------------------------------------------------* + * @brief Get the Type Name + * + * @param type The data type + * @return std::string Name of the data type in string + *---------------------------------------------------------------------------**/ std::string getTypeName(gdf_dtype type) { return type_dispatcher(type, type_name()); } + /**---------------------------------------------------------------------------* + * @brief Get the Operator Name + * + * @param ope (enum) The binary operator as enum of type gdf_binary_operator + * @return std::string The name of the operator as string + *---------------------------------------------------------------------------**/ std::string getOperatorName(gdf_binary_operator ope) { switch (ope) { case GDF_ADD: From d0e30b2eaa91664815e786831c7a0e5b69964be2 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 28 Feb 2019 01:12:26 +0530 Subject: [PATCH 35/51] removed changelog duplicates (artifacts of merge conflicts) --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 074064538de2..d03f43b6591a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,12 +50,10 @@ - PR #694 Unit test utilities improvements - PR #878 Add better indexing to Groupby - PR #554 Add `empty` method and `is_monotonic` attribute to `Index` -- PR #694 Unit test utilities improvements - PR #1040 Fixed up Doxygen comment tags - PR #909 CSV Reader: Avoid host->device->host copy for header row data - PR #916 Improved unit testing and error checking for `gdf_column_concat` - PR #941 Replace `numpy` call in `Series.hash_encode` with `numba` -- PR #943 Updated `count_nonzero_mask` to return `num_rows` when the mask is null - PR #942 Added increment/decrement operators for wrapper types - PR #943 Updated `count_nonzero_mask` to return `num_rows` when the mask is null - PR #952 Added trait to map C++ type to `gdf_dtype` From dde39a7c08e0bf77461d3585f230501c92ef6ddd Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 28 Feb 2019 04:31:25 +0530 Subject: [PATCH 36/51] refactored the mask calculation. --- cpp/src/binary/jit/core/binop.cpp | 31 +++++++++--- cpp/src/bitmask/bitmask_ops.cu | 84 +++++-------------------------- cpp/src/bitmask/bitmask_ops.h | 24 +++++++-- cpp/src/bitmask/valid_ops.cu | 2 +- 4 files changed, 58 insertions(+), 83 deletions(-) diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index 08dab07e6c2f..5162630785b2 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -19,12 +19,27 @@ #include "binary/jit/util/operator.h" #include "bitmask/bitmask_ops.h" #include "utilities/error_utils.h" +#include "utilities/cudf_utils.h" #include "cudf.h" namespace cudf { namespace binops { - + /**---------------------------------------------------------------------------* + * @brief Computes bitwise AND of two input columns + * + * This is just a wrapper on apply_bitmask_to_bitmask that can also handle + * cases when one or both of the input masa are nullptr, in which case, it + * copies the mask from the non nullptr input or sets all the output mask to + * valid respectively + * + * @param out_null_coun[out] number of nulls in output + * @param valid_out preallocated output mask + * @param valid_left input mask 1 + * @param valid_right input mask 2 + * @param num_values number of values in each input mask valid_left and valid_right + * @return gdf_error + *---------------------------------------------------------------------------**/ gdf_error binary_valid_mask_and(gdf_size_type & out_null_count, gdf_valid_type * valid_out, gdf_valid_type * valid_left, @@ -37,14 +52,16 @@ namespace binops { GDF_REQUIRE((valid_out != nullptr), GDF_DATASET_EMPTY) - cudaStream_t stream; - cudaStreamCreate(&stream); - if ( valid_left != nullptr && valid_right != nullptr ) { - return apply_bitmask_to_bitmask(out_null_count, valid_out, valid_left, valid_right, stream, num_values); + cudaStream_t stream; + CUDA_TRY( cudaStreamCreate(&stream) ); + auto error = apply_bitmask_to_bitmask(out_null_count, valid_out, valid_left, valid_right, stream, num_values); + CUDA_TRY(cudaStreamSynchronize(stream)); + CUDA_TRY(cudaStreamDestroy(stream)); + return error; } - gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); + gdf_size_type num_chars_bitmask = gdf_get_num_chars_bitmask( num_values ); if ( valid_left == nullptr && valid_right != nullptr ) { CUDA_TRY( cudaMemcpy(valid_out, valid_right, num_chars_bitmask, cudaMemcpyDeviceToDevice) ); @@ -56,7 +73,7 @@ namespace binops { CUDA_TRY( cudaMemset(valid_out, 0xff, num_chars_bitmask) ); } - return update_null_count(out_null_count, valid_out, stream, num_values); + return gdf_count_nonzero_mask(valid_out, num_values, &out_null_count); } namespace jit { diff --git a/cpp/src/bitmask/bitmask_ops.cu b/cpp/src/bitmask/bitmask_ops.cu index 0e2212f0dd00..f3c8a8706d3d 100644 --- a/cpp/src/bitmask/bitmask_ops.cu +++ b/cpp/src/bitmask/bitmask_ops.cu @@ -12,89 +12,31 @@ #include #include -/* - * bit_mask_null_counts Generated using the following code - -#include - - -int main() -{ - for (int i = 0 ; i != 256 ; i++) { - int count = 0; - for (int p = 0 ; p != 8 ; p++) { - if (i & (1 << p)) { - count++; - } - } - std::cout<<(8-count)<<", "; - } - std::cout< bit_mask_null_counts = { 8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4, 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0 }; - -unsigned char gdf_num_bits_zero_after_pos(unsigned char number, int pos){ - //if pos == 0 then its aligned - if(pos == 0){ - return 0; - } - unsigned char count = 0; - for (int p = pos ; p != 8 ; p++) { - if (number & (number << p)) { - count++; - } - } - return (8 - pos) - count; -} gdf_error all_bitmask_on(gdf_valid_type * valid_out, gdf_size_type & out_null_count, gdf_size_type num_values, cudaStream_t stream){ - gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); + gdf_size_type num_chars_bitmask = gdf_get_num_chars_bitmask( num_values ); - thrust::device_ptr valid_out_ptr = thrust::device_pointer_cast(valid_out); gdf_valid_type max_char = 255; - thrust::fill(rmm::exec_policy(stream)->on(stream),thrust::detail::make_normal_iterator(valid_out_ptr),thrust::detail::make_normal_iterator(valid_out_ptr + num_chars_bitmask),max_char); + thrust::fill(rmm::exec_policy(stream)->on(stream), + valid_out, + valid_out + num_chars_bitmask, + max_char); //we have no nulls so set all the bits in gdf_valid_type to 1 out_null_count = 0; return GDF_SUCCESS; } -gdf_error update_null_count(gdf_size_type & out_null_count, gdf_valid_type * valid, cudaStream_t stream, gdf_size_type num_values) { - gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); - thrust::device_ptr valid_out_ptr = thrust::device_pointer_cast(valid); - - char * last_char = new char[1]; - cudaError_t error = cudaMemcpyAsync(last_char,valid + ( num_chars_bitmask-1),sizeof(gdf_valid_type),cudaMemcpyDeviceToHost,stream); - - - rmm::device_vector bit_mask_null_counts_device(bit_mask_null_counts); - - //this permutation iterator makes it so that each char basically gets replaced with its number of null counts - //so if you sum up this perm iterator you add up all of the counts for null values per unsigned char - thrust::permutation_iterator::iterator,thrust::detail::normal_iterator > > - null_counts_iter( bit_mask_null_counts_device.begin(),thrust::detail::make_normal_iterator(valid_out_ptr)); - - //you will notice that we subtract the number of zeros we found in the last character - out_null_count = thrust::reduce(rmm::exec_policy(stream)->on(stream),null_counts_iter, null_counts_iter + num_chars_bitmask) - gdf_num_bits_zero_after_pos(*last_char,num_values % GDF_VALID_BITSIZE ); - - delete[] last_char; - return GDF_SUCCESS; -} - gdf_error apply_bitmask_to_bitmask(gdf_size_type & out_null_count, gdf_valid_type * valid_out, gdf_valid_type * valid_left, gdf_valid_type * valid_right, cudaStream_t stream, gdf_size_type num_values){ - gdf_size_type num_chars_bitmask = ( ( num_values +( GDF_VALID_BITSIZE - 1)) / GDF_VALID_BITSIZE ); - thrust::device_ptr valid_out_ptr = thrust::device_pointer_cast(valid_out); - thrust::device_ptr valid_left_ptr = thrust::device_pointer_cast(valid_left); - //here we are basically figuring out what is the last pointed to unsigned char that can contain part of the bitmask - thrust::device_ptr valid_left_end_ptr = thrust::device_pointer_cast(valid_left + num_chars_bitmask ); - thrust::device_ptr valid_right_ptr = thrust::device_pointer_cast(valid_right); - + gdf_size_type num_chars_bitmask = gdf_get_num_chars_bitmask( num_values ); - thrust::transform(rmm::exec_policy(stream)->on(stream), thrust::detail::make_normal_iterator(valid_left_ptr), - thrust::detail::make_normal_iterator(valid_left_end_ptr), thrust::detail::make_normal_iterator(valid_right_ptr), - thrust::detail::make_normal_iterator(valid_out_ptr), thrust::bit_and()); + thrust::transform(rmm::exec_policy(stream)->on(stream), + valid_left, + valid_left + num_chars_bitmask, + valid_right, + valid_out, + thrust::bit_and()); - return update_null_count(out_null_count, valid_out, stream, num_values); + return gdf_count_nonzero_mask(valid_out, num_values, &out_null_count); } diff --git a/cpp/src/bitmask/bitmask_ops.h b/cpp/src/bitmask/bitmask_ops.h index 721daa4554ae..589cb7e07ac0 100644 --- a/cpp/src/bitmask/bitmask_ops.h +++ b/cpp/src/bitmask/bitmask_ops.h @@ -3,12 +3,28 @@ #include - +/**---------------------------------------------------------------------------* + * @brief Sets all bits in input valid mask to 1 + * + * @param valid_out preallocated valid mask to set the values for + * @param out_null_count number of nulls (0 bits) in valid mask. Always set to 0 + * @param num_values number of values in column for which the output mask was made + * @param stream cuda stream to run in + * @return gdf_error + *---------------------------------------------------------------------------**/ gdf_error all_bitmask_on(gdf_valid_type * valid_out, gdf_size_type & out_null_count, gdf_size_type num_values, cudaStream_t stream); - -gdf_error update_null_count(gdf_size_type & out_null_count, gdf_valid_type * valid, cudaStream_t stream, gdf_size_type num_values); - +/**---------------------------------------------------------------------------* + * @brief Computes bitwise AND on two valid masks and sets it in output + * + * @param out_null_count number of nulls (0 bits) in output valid mask + * @param valid_out preallocated mask to set the result values in + * @param valid_left input valid mask 1 + * @param valid_right input valid mask 2 + * @param stream cuda stream to run in + * @param num_values number of values in each input mask valid_left and valid_right + * @return gdf_error + *---------------------------------------------------------------------------**/ gdf_error apply_bitmask_to_bitmask(gdf_size_type & out_null_count, gdf_valid_type * valid_out, gdf_valid_type * valid_left, gdf_valid_type * valid_right, cudaStream_t stream, gdf_size_type num_values); #endif diff --git a/cpp/src/bitmask/valid_ops.cu b/cpp/src/bitmask/valid_ops.cu index b2f858d0eaa9..847816b22ee4 100644 --- a/cpp/src/bitmask/valid_ops.cu +++ b/cpp/src/bitmask/valid_ops.cu @@ -127,7 +127,7 @@ void count_valid_bits(valid32_t const * const masks32, gdf_error gdf_count_nonzero_mask(gdf_valid_type const *masks, gdf_size_type num_rows, gdf_size_type *count) { - + // TODO: add a default parameter cudaStream_t stream = 0 when we move API to C++ if((nullptr == count)){return GDF_DATASET_EMPTY;} From 86ea59b48ef7cc25d6871333d5f9871320806499 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 28 Feb 2019 21:40:55 +0530 Subject: [PATCH 37/51] removed redundant null_count calculation and fixed a bug in calculating null_count. --- cpp/src/binary/jit/core/binop.cpp | 12 ++++++++++-- cpp/src/bitmask/bitmask_ops.cu | 5 ++++- python/cudf/bindings/binops.pyx | 4 ++++ python/cudf/dataframe/numerical.py | 7 +------ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index 5162630785b2..bb9a83c1a8a7 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -29,7 +29,7 @@ namespace binops { * @brief Computes bitwise AND of two input columns * * This is just a wrapper on apply_bitmask_to_bitmask that can also handle - * cases when one or both of the input masa are nullptr, in which case, it + * cases when one or both of the input masks are nullptr, in which case, it * copies the mask from the non nullptr input or sets all the output mask to * valid respectively * @@ -50,6 +50,11 @@ namespace binops { return GDF_SUCCESS; } + if (valid_out == nullptr && valid_left == nullptr && valid_right == nullptr) { + out_null_count = 0; + return GDF_SUCCESS; + } + GDF_REQUIRE((valid_out != nullptr), GDF_DATASET_EMPTY) if ( valid_left != nullptr && valid_right != nullptr ) { @@ -73,7 +78,10 @@ namespace binops { CUDA_TRY( cudaMemset(valid_out, 0xff, num_chars_bitmask) ); } - return gdf_count_nonzero_mask(valid_out, num_values, &out_null_count); + gdf_size_type non_nulls; + auto error = gdf_count_nonzero_mask(valid_out, num_values, &non_nulls); + out_null_count = num_values - non_nulls; + return error; } namespace jit { diff --git a/cpp/src/bitmask/bitmask_ops.cu b/cpp/src/bitmask/bitmask_ops.cu index f3c8a8706d3d..5eb11a138e60 100644 --- a/cpp/src/bitmask/bitmask_ops.cu +++ b/cpp/src/bitmask/bitmask_ops.cu @@ -38,5 +38,8 @@ gdf_error apply_bitmask_to_bitmask(gdf_size_type & out_null_count, gdf_valid_typ valid_out, thrust::bit_and()); - return gdf_count_nonzero_mask(valid_out, num_values, &out_null_count); + gdf_size_type non_nulls; + auto error = gdf_count_nonzero_mask(valid_out, num_values, &non_nulls); + out_null_count = num_values - non_nulls; + return error; } diff --git a/python/cudf/bindings/binops.pyx b/python/cudf/bindings/binops.pyx index 9eb0dc97fe91..461c1f4b6c1c 100644 --- a/python/cudf/bindings/binops.pyx +++ b/python/cudf/bindings/binops.pyx @@ -61,8 +61,12 @@ def apply_op(lhs, rhs, out, op): c_rhs, c_op) + cdef int nullct = c_out[0].null_count + free(c_lhs) free(c_rhs) free(c_out) check_gdf_error(result) + + return nullct diff --git a/python/cudf/dataframe/numerical.py b/python/cudf/dataframe/numerical.py index 1cbe3a1d1053..a1753fd9cf25 100644 --- a/python/cudf/dataframe/numerical.py +++ b/python/cudf/dataframe/numerical.py @@ -401,12 +401,7 @@ def numeric_column_binop(lhs, rhs, op, out_dtype): # Call and fix null_count if lhs.dtype != rhs.dtype or op not in _binary_impl: # Use JIT implementation - cpp_binops.apply_op(lhs=lhs, rhs=rhs, out=out, op=op) - if masked: - nnz = _gdf.count_nonzero_mask(out.mask.mem, size=len(out)) - null_count = len(out) - nnz - else: - null_count = 0 + null_count = cpp_binops.apply_op(lhs=lhs, rhs=rhs, out=out, op=op) else: # Use compiled implementation null_count = _gdf.apply_binaryop(_binary_impl[op], lhs, rhs, out) From 11b67dc96b9a119df4e43f2ccba1e5653df7995d Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Fri, 1 Mar 2019 03:21:49 +0530 Subject: [PATCH 38/51] fix rebuilding of launcher.cpp everytime because types.h.jit was always regenerated. --- cpp/CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 13851eeb54f8..0ab9d77a721e 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -228,12 +228,14 @@ add_executable(stringify "${CMAKE_SOURCE_DIR}/thirdparty/jitify/stringify.cpp") execute_process(WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include) -add_custom_target(stringify_run - COMMAND ${CMAKE_BINARY_DIR}/stringify cudf/types.h > ${CMAKE_BINARY_DIR}/include/types.h.jit - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include - COMMENT "stringify header types.h" - DEPENDS stringify -) +add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/include/types.h.jit + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include + COMMAND ${CMAKE_BINARY_DIR}/stringify cudf/types.h > ${CMAKE_BINARY_DIR}/include/types.h.jit + COMMENT "stringify header types.h" + DEPENDS stringify + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/include/cudf/types.h) + +add_custom_target(stringify_run DEPENDS ${CMAKE_BINARY_DIR}/include/types.h.jit) add_dependencies(cudf stringify_run) From 952085330864fc4f5d85bb2da8cbd2c602cbb1e2 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Tue, 5 Mar 2019 04:52:01 +0530 Subject: [PATCH 39/51] Changed gdf_scalar to use union and is_valid bool member. Added tests that test this. changed scalar_wrapper because obviously --- cpp/include/cudf/types.h | 22 ++- cpp/src/binary/jit/code/kernel.cpp | 4 +- cpp/src/binary/jit/core/binop.cpp | 58 ++++++- cpp/tests/CMakeLists.txt | 1 + cpp/tests/binary/integration/assert-binops.h | 10 +- .../binary-operation-operands-null-test.cpp | 152 ++++++++++++++++++ cpp/tests/utilities/scalar_wrapper.cuh | 92 ++++------- 7 files changed, 262 insertions(+), 77 deletions(-) create mode 100644 cpp/tests/binary/integration/binary-operation-operands-null-test.cpp diff --git a/cpp/include/cudf/types.h b/cpp/include/cudf/types.h index b38b4a31152d..44bf37f3c01e 100644 --- a/cpp/include/cudf/types.h +++ b/cpp/include/cudf/types.h @@ -85,14 +85,32 @@ typedef struct { // here we can also hold info for decimal datatype or any other datatype that requires additional information } gdf_dtype_extra_info; +/**---------------------------------------------------------------------------* + * @union gdf_data + * @brief Union used for scalar type. + * It stores a unique value for scalar type. + * It has a direct relationship with the gdf_dtype. + *---------------------------------------------------------------------------**/ +typedef union { + int8_t si08; /**< GDF_INT8 */ + int16_t si16; /**< GDF_INT16 */ + int32_t si32; /**< GDF_INT32 */ + int64_t si64; /**< GDF_INT64 */ + float fp32; /**< GDF_FLOAT32 */ + double fp64; /**< GDF_FLOAT64 */ + int32_t dt32; /**< GDF_DATE32 */ + int64_t dt64; /**< GDF_DATE64 */ + int64_t tmst; /**< GDF_TIMESTAMP */ +} gdf_data; /**---------------------------------------------------------------------------* * @brief A struct to hold a scalar (single) value and its type information * *---------------------------------------------------------------------------**/ typedef struct { - void* data; /**< Pointer to the scalar data */ - gdf_dtype dtype; /**< The datatype of the scalar's data */ + gdf_data data; /**< Pointer to the scalar data */ + gdf_dtype dtype; /**< The datatype of the scalar's data */ + bool is_valid; /**< False if the value is null */ } gdf_scalar; diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 24a2959c89c9..53593b87962a 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -29,7 +29,7 @@ R"***( template __global__ void kernel_v_s(gdf_size_type size, - TypeOut* out_data, TypeLhs* lhs_data, TypeRhs* rhs_data) { + TypeOut* out_data, TypeLhs* lhs_data, gdf_data rhs_data) { int tid = threadIdx.x; int blkid = blockIdx.x; int blksz = blockDim.x; @@ -39,7 +39,7 @@ R"***( int step = blksz * gridsz; for (gdf_size_type i=start; i(lhs_data[i], rhs_data[0]); + out_data[i] = TypeOpe::template operate(lhs_data[i], *reinterpret_cast(&rhs_data)); } } diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index bb9a83c1a8a7..2df9e4e24bd7 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -26,7 +26,7 @@ namespace cudf { namespace binops { /**---------------------------------------------------------------------------* - * @brief Computes bitwise AND of two input columns + * @brief Computes bitwise AND of two input valid masks * * This is just a wrapper on apply_bitmask_to_bitmask that can also handle * cases when one or both of the input masks are nullptr, in which case, it @@ -51,6 +51,7 @@ namespace binops { } if (valid_out == nullptr && valid_left == nullptr && valid_right == nullptr) { + // if both in cols have no mask, then out col is allowed to have no mask out_null_count = 0; return GDF_SUCCESS; } @@ -84,6 +85,53 @@ namespace binops { return error; } + /**---------------------------------------------------------------------------* + * @brief Computes output valid mask for op between a column and a scalar + * + * @param out_null_coun[out] number of nulls in output + * @param valid_out preallocated output mask + * @param valid_col input mask of column + * @param valid_scalar bool indicating if scalar is valid + * @param num_values number of values in input mask valid_col + * @return gdf_error + *---------------------------------------------------------------------------**/ + gdf_error scalar_col_valid_mask_and(gdf_size_type & out_null_count, + gdf_valid_type * valid_out, + gdf_valid_type * valid_col, + bool valid_scalar, + gdf_size_type num_values) + { + if (num_values == 0) { + out_null_count = 0; + return GDF_SUCCESS; + } + + if (valid_out == nullptr && valid_col == nullptr && valid_scalar == true) { + // if in col has no mask and scalar is valid, then out col is allowed to have no mask + out_null_count = 0; + return GDF_SUCCESS; + } + + GDF_REQUIRE((valid_out != nullptr), GDF_DATASET_EMPTY) + + gdf_size_type num_chars_bitmask = gdf_get_num_chars_bitmask( num_values ); + + if ( valid_scalar == false ) { + CUDA_TRY( cudaMemset(valid_out, 0x00, num_chars_bitmask) ); + } + else if ( valid_scalar == true && valid_col != nullptr ) { + CUDA_TRY( cudaMemcpy(valid_out, valid_col, num_chars_bitmask, cudaMemcpyDeviceToDevice) ); + } + else if ( valid_scalar == true && valid_col == nullptr ) { + CUDA_TRY( cudaMemset(valid_out, 0xff, num_chars_bitmask) ); + } + + gdf_size_type non_nulls; + auto error = gdf_count_nonzero_mask(valid_out, num_values, &non_nulls); + out_null_count = num_values - non_nulls; + return error; + } + namespace jit { gdf_error binary_operation(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope) { @@ -96,13 +144,13 @@ namespace jit { GDF_REQUIRE((out->size == rhs->size), GDF_COLUMN_SIZE_MISMATCH) // Check for null data pointer - GDF_REQUIRE((out->data != nullptr) && (lhs->data != nullptr) && (rhs->data != nullptr), GDF_DATASET_EMPTY) + GDF_REQUIRE((out->data != nullptr) && (rhs->data != nullptr), GDF_DATASET_EMPTY) // Check for datatype GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) - binary_valid_mask_and(out->null_count, out->valid, nullptr, rhs->valid, rhs->size); + scalar_col_valid_mask_and(out->null_count, out->valid, rhs->valid, lhs->is_valid, rhs->size); Launcher::launch().kernel("kernel_v_s") .instantiate(ope, Operator::Type::Reverse, out, rhs, lhs) @@ -121,13 +169,13 @@ namespace jit { GDF_REQUIRE((out->size == lhs->size), GDF_COLUMN_SIZE_MISMATCH) // Check for null data pointer - GDF_REQUIRE((out->data != nullptr) && (lhs->data != nullptr) && (rhs->data != nullptr), GDF_DATASET_EMPTY) + GDF_REQUIRE((out->data != nullptr) && (lhs->data != nullptr), GDF_DATASET_EMPTY) // Check for datatype GDF_REQUIRE((out->dtype > GDF_invalid) && (lhs->dtype > GDF_invalid) && (rhs->dtype > GDF_invalid), GDF_UNSUPPORTED_DTYPE) GDF_REQUIRE((out->dtype < N_GDF_TYPES) && (lhs->dtype < N_GDF_TYPES) && (rhs->dtype < N_GDF_TYPES), GDF_UNSUPPORTED_DTYPE) - binary_valid_mask_and(out->null_count, out->valid, lhs->valid, nullptr, lhs->size); + scalar_col_valid_mask_and(out->null_count, out->valid, lhs->valid, rhs->is_valid, lhs->size); Launcher::launch().kernel("kernel_v_s") .instantiate(ope, Operator::Type::Direct, out, lhs, rhs) diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index cf1ca7150185..0a65b465616a 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -171,6 +171,7 @@ ConfigureTest(UNARY_TEST "${UNARY_TEST_SRC}") set(BINARY_TEST_SRC "${CMAKE_CURRENT_SOURCE_DIR}/binary/unit/binop-verify-input-test.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/binary/integration/binary-operation-operands-null-test.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/binary/integration/binary-operation-integration-test.cpp") ConfigureTest(BINARY_TEST "${BINARY_TEST_SRC}") diff --git a/cpp/tests/binary/integration/assert-binops.h b/cpp/tests/binary/integration/assert-binops.h index 5ec619c82e6b..06fbad69cd3e 100644 --- a/cpp/tests/binary/integration/assert-binops.h +++ b/cpp/tests/binary/integration/assert-binops.h @@ -32,7 +32,7 @@ void ASSERT_BINOP(cudf::test::column_wrapper& out, cudf::test::scalar_wrapper& lhs, cudf::test::column_wrapper& rhs, TypeOpe&& ope) { - auto lhs_h = lhs.to_host(); + auto lhs_h = lhs.value(); auto rhs_h = rhs.to_host(); auto rhs_data = std::get<0>(rhs_h); auto out_h = out.to_host(); @@ -46,9 +46,10 @@ void ASSERT_BINOP(cudf::test::column_wrapper& out, auto rhs_valid = std::get<1>(rhs_h); auto out_valid = std::get<1>(out_h); + uint32_t lhs_valid = (lhs.is_valid() ? UINT32_MAX : 0); ASSERT_TRUE(out_valid.size() == rhs_valid.size()); for (int index = 0; index < out_valid.size(); ++index) { - ASSERT_TRUE(out_valid[index] == rhs_valid[index]); + ASSERT_TRUE(out_valid[index] == (lhs_valid & rhs_valid[index])); } } @@ -57,7 +58,7 @@ void ASSERT_BINOP(cudf::test::column_wrapper& out, cudf::test::column_wrapper& lhs, cudf::test::scalar_wrapper& rhs, TypeOpe&& ope) { - auto rhs_h = rhs.to_host(); + auto rhs_h = rhs.value(); auto lhs_h = lhs.to_host(); auto lhs_data = std::get<0>(lhs_h); auto out_h = out.to_host(); @@ -71,9 +72,10 @@ void ASSERT_BINOP(cudf::test::column_wrapper& out, auto lhs_valid = std::get<1>(lhs_h); auto out_valid = std::get<1>(out_h); + uint32_t rhs_valid = (rhs.is_valid() ? UINT32_MAX : 0); ASSERT_TRUE(out_valid.size() == lhs_valid.size()); for (int index = 0; index < out_valid.size(); ++index) { - ASSERT_TRUE(out_valid[index] == (lhs_valid[index])); + ASSERT_TRUE(out_valid[index] == (lhs_valid[index] & rhs_valid)); } } diff --git a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp new file mode 100644 index 000000000000..0384e16bfb4c --- /dev/null +++ b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp @@ -0,0 +1,152 @@ +/* + * Copyright 2018-2019 BlazingDB, Inc. + * Copyright 2018 Christian Noboa Mardini + * + * 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 "tests/binary/integration/assert-binops.h" + +namespace cudf { +namespace test { +namespace binop { + +struct BinaryOperationOperandsNullTest : public ::testing::Test { + BinaryOperationOperandsNullTest() { + } + + virtual ~BinaryOperationOperandsNullTest() { + } + + virtual void SetUp() { + } + + virtual void TearDown() { + } +}; + +/* + * Kernels v_v_s, using int64_t + * Output:Vector, OperandX:Vector, OperandY:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_SI64_WithScalarOperandNull) { + using ADD = cudf::library::operation::Add; + + auto lhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto rhs = cudf::test::scalar_wrapper{500, false}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; + + auto result = gdf_binary_operation_v_s(out.get(), lhs.get(), rhs.get(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + ASSERT_BINOP(out, lhs, rhs, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Scalar_SI64_WithScalarOperandNotNull) { + using ADD = cudf::library::operation::Add; + + auto lhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto rhs = cudf::test::scalar_wrapper{500, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; + + auto result = gdf_binary_operation_v_s(out.get(), lhs.get(), rhs.get(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + ASSERT_BINOP(out, lhs, rhs, ADD()); +} + +/* + * Kernels v_v_s, using double + * Output:Vector, OperandX:Vector, OperandY:Scalar + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNull) { + using ADD = cudf::library::operation::Add; + + auto lhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto rhs = cudf::test::scalar_wrapper{500, false}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; + + auto result = gdf_binary_operation_v_s(out.get(), lhs.get(), rhs.get(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + ASSERT_BINOP(out, lhs, rhs, ADD()); +} + + +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64_WithScalarOperandNotNull) { + using ADD = cudf::library::operation::Add; + + auto lhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto rhs = cudf::test::scalar_wrapper{500, true}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; + + auto result = gdf_binary_operation_v_s(out.get(), lhs.get(), rhs.get(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + ASSERT_BINOP(out, lhs, rhs, ADD()); +} + +/* + * Kernels v_v_v, using int64_t + * Output:Vector, OperandX:Vector, OperandY:Vector + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_int64_t) { + using ADD = cudf::library::operation::Add; + + auto lhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto rhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row * 2;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; + + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + ASSERT_BINOP(out, lhs, rhs, ADD()); +} + +/* + * Kernels v_v_v, using double + * Output:Vector, OperandX:Vector, OperandY:Vector + */ +TEST_F(BinaryOperationOperandsNullTest, Vector_Vector_FP64) { + using ADD = cudf::library::operation::Add; + + auto lhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row;}, + [](gdf_size_type row) {return (row % 3 > 0);}}; + auto rhs = cudf::test::column_wrapper{100, + [](gdf_size_type row) {return row * 2;}, + [](gdf_size_type row) {return (row % 4 > 0);}}; + auto out = cudf::test::column_wrapper{lhs.get()->size, true}; + + auto result = gdf_binary_operation_v_v(out.get(), lhs.get(), rhs.get(), GDF_ADD); + ASSERT_TRUE(result == GDF_SUCCESS); + + ASSERT_BINOP(out, lhs, rhs, ADD()); +} + +} // namespace binop +} // namespace test +} // namespace gdf diff --git a/cpp/tests/utilities/scalar_wrapper.cuh b/cpp/tests/utilities/scalar_wrapper.cuh index 517a492d366e..5f165d64ad84 100644 --- a/cpp/tests/utilities/scalar_wrapper.cuh +++ b/cpp/tests/utilities/scalar_wrapper.cuh @@ -27,21 +27,6 @@ #include #include -#ifndef CUDA_RT_CALL -#define CUDA_RT_CALL(call) \ - do { \ - cudaError_t cudaStatus = (call); \ - if (cudaSuccess != cudaStatus) { \ - fprintf(stderr, \ - "ERROR: CUDA RT call \"%s\" in line %d of file %s failed with " \ - "%s (%d).\n", \ - #call, __LINE__, __FILE__, cudaGetErrorString(cudaStatus), \ - cudaStatus); \ - exit(1); \ - } \ - } while (0) -#endif - namespace cudf { namespace test { @@ -73,16 +58,16 @@ struct scalar_wrapper { /**---------------------------------------------------------------------------* * @brief Construct a new scalar wrapper object * - * Constructs a scalar_wrapper using a ref value for the host data. + * Constructs a scalar_wrapper using a value of type ScalarType. * - * @param host_data The value to use for the scalar + * @param value The value to use for the scalar + * @param is_valid is the scalar valid *---------------------------------------------------------------------------**/ - scalar_wrapper(ScalarType const& host_data) { - initialize_with_host_data(host_data); - } - - ~scalar_wrapper() { - RMM_FREE(the_scalar.data, 0); + scalar_wrapper(ScalarType value, bool is_valid = true) { + auto dataptr = reinterpret_cast(&(the_scalar.data)); + *dataptr = value; + the_scalar.is_valid = is_valid; + the_scalar.dtype = gdf_dtype_of(); } /**---------------------------------------------------------------------------* @@ -93,30 +78,31 @@ struct scalar_wrapper { gdf_scalar const* get() const { return &the_scalar; } /**---------------------------------------------------------------------------* - * @brief Copies the underying gdf_scalar's data to the host. - * - * Returns the value of the scalar - * + * @brief returns the value of the scalar + * + * @return ScalarType *---------------------------------------------------------------------------**/ - auto to_host() const { - ScalarType host_data; - - if (nullptr != the_scalar.data) { - CUDA_RT_CALL(cudaMemcpy(&host_data, the_scalar.data, - sizeof(ScalarType), - cudaMemcpyDeviceToHost)); - } - - return host_data; + ScalarType value() { + return *reinterpret_cast(&(the_scalar.data)); } + /**---------------------------------------------------------------------------* + * @brief returns the validity of the scalar + * + * @return bool + *---------------------------------------------------------------------------**/ + bool is_valid() { return the_scalar.is_valid; } + /**---------------------------------------------------------------------------* * @brief Prints the value of the underlying gdf_scalar. * *---------------------------------------------------------------------------**/ void print() const { - ScalarType value = this->to_host(); - std::cout << value << std::endl; + ScalarType value = *reinterpret_cast(&(the_scalar.data)); + if (the_scalar.is_valid) + std::cout << value << std::endl; + else + std::cout << "null" << std::endl; } /**---------------------------------------------------------------------------* @@ -127,34 +113,12 @@ struct scalar_wrapper { * @return false The two scalars are not equal *---------------------------------------------------------------------------**/ bool operator==(scalar_wrapper const& rhs) const { - if (the_scalar.dtype != rhs.the_scalar.dtype) return false; - - if (!(the_scalar.data && rhs.the_scalar.data)) - return false; // if one is null but not both - - return (this->to_host() == rhs.to_host()); + return (the_scalar.data == rhs.data && + the_scalar.dtype == rhs.dtype && + the_scalar.is_valid == rhs.is_valid); } private: - /**---------------------------------------------------------------------------* - * @brief Allocates and initializes the underyling gdf_scalar with host data. - * - * Creates a gdf_scalar and copies data from the host for it's data. - * Sets the corresponding dtype based on the scalar_wrapper's ColumnType. - * - * @param host_data The host data to copy to device for the scalar's data - *---------------------------------------------------------------------------**/ - void initialize_with_host_data(ScalarType const& host_data) { - // Allocate device storage for gdf_scalar and copy contents from host_data - RMM_ALLOC(&(the_scalar.data), sizeof(ScalarType), 0); - CUDA_RT_CALL(cudaMemcpy(the_scalar.data, &host_data, - sizeof(ScalarType), - cudaMemcpyHostToDevice)); - - // Fill the gdf_scalar members - the_scalar.dtype = cudf::gdf_dtype_of(); - } - gdf_scalar the_scalar; }; From be21879436fe03c8862293ba7c6945affb927854 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Tue, 5 Mar 2019 04:57:23 +0530 Subject: [PATCH 40/51] added nvidia license --- cpp/src/binary/jit/code/code.h | 2 ++ cpp/src/binary/jit/code/kernel.cpp | 2 ++ cpp/src/binary/jit/code/operation.cpp | 2 ++ cpp/src/binary/jit/code/traits.cpp | 2 ++ cpp/src/binary/jit/core/binop.cpp | 2 ++ cpp/src/binary/jit/core/launcher.cpp | 2 ++ cpp/src/binary/jit/core/launcher.h | 2 ++ cpp/src/binary/jit/util/operator.cpp | 2 ++ cpp/src/binary/jit/util/operator.h | 2 ++ cpp/src/binary/jit/util/type.cpp | 2 ++ cpp/src/binary/jit/util/type.h | 2 ++ cpp/tests/binary/integration/assert-binops.h | 2 ++ .../binary/integration/binary-operation-integration-test.cpp | 2 ++ .../binary/integration/binary-operation-operands-null-test.cpp | 2 ++ cpp/tests/binary/unit/binop-verify-input-test.cpp | 2 ++ cpp/tests/binary/util/operation.h | 2 ++ 16 files changed, 32 insertions(+) diff --git a/cpp/src/binary/jit/code/code.h b/cpp/src/binary/jit/code/code.h index 0825e732dc12..7fdb63ab928c 100644 --- a/cpp/src/binary/jit/code/code.h +++ b/cpp/src/binary/jit/code/code.h @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/code/kernel.cpp b/cpp/src/binary/jit/code/kernel.cpp index 53593b87962a..bb52a8b76bfd 100644 --- a/cpp/src/binary/jit/code/kernel.cpp +++ b/cpp/src/binary/jit/code/kernel.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * Copyright 2018 Rommel Quintanilla diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp index 2d2d8e9f7e56..5b8765112284 100644 --- a/cpp/src/binary/jit/code/operation.cpp +++ b/cpp/src/binary/jit/code/operation.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/code/traits.cpp b/cpp/src/binary/jit/code/traits.cpp index fa86122c3d3f..c434a18281aa 100644 --- a/cpp/src/binary/jit/code/traits.cpp +++ b/cpp/src/binary/jit/code/traits.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index 2df9e4e24bd7..17a0e1b435b6 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index 297c514b2cf0..cd94f19e7ab3 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/core/launcher.h b/cpp/src/binary/jit/core/launcher.h index aea63fd37f7e..4d548ac735df 100644 --- a/cpp/src/binary/jit/core/launcher.h +++ b/cpp/src/binary/jit/core/launcher.h @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/util/operator.cpp b/cpp/src/binary/jit/util/operator.cpp index 03aef9c77347..fe986c730d1a 100644 --- a/cpp/src/binary/jit/util/operator.cpp +++ b/cpp/src/binary/jit/util/operator.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/util/operator.h b/cpp/src/binary/jit/util/operator.h index 6869f691cf47..9e5e576b4380 100644 --- a/cpp/src/binary/jit/util/operator.h +++ b/cpp/src/binary/jit/util/operator.h @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/util/type.cpp b/cpp/src/binary/jit/util/type.cpp index 8b611a066050..8ec7cdc70b8a 100644 --- a/cpp/src/binary/jit/util/type.cpp +++ b/cpp/src/binary/jit/util/type.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/src/binary/jit/util/type.h b/cpp/src/binary/jit/util/type.h index ca7c427c7776..769d9bd267f8 100644 --- a/cpp/src/binary/jit/util/type.h +++ b/cpp/src/binary/jit/util/type.h @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/tests/binary/integration/assert-binops.h b/cpp/tests/binary/integration/assert-binops.h index 06fbad69cd3e..eda36ff32609 100644 --- a/cpp/tests/binary/integration/assert-binops.h +++ b/cpp/tests/binary/integration/assert-binops.h @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/tests/binary/integration/binary-operation-integration-test.cpp b/cpp/tests/binary/integration/binary-operation-integration-test.cpp index 3df63db54e0c..3c926f36194d 100644 --- a/cpp/tests/binary/integration/binary-operation-integration-test.cpp +++ b/cpp/tests/binary/integration/binary-operation-integration-test.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp index 0384e16bfb4c..d8bf5945d91b 100644 --- a/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp +++ b/cpp/tests/binary/integration/binary-operation-operands-null-test.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/tests/binary/unit/binop-verify-input-test.cpp b/cpp/tests/binary/unit/binop-verify-input-test.cpp index b8bbc88eb82f..fa4a5a7392a3 100644 --- a/cpp/tests/binary/unit/binop-verify-input-test.cpp +++ b/cpp/tests/binary/unit/binop-verify-input-test.cpp @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * diff --git a/cpp/tests/binary/util/operation.h b/cpp/tests/binary/util/operation.h index 0f988b33f458..299f7347f9ed 100644 --- a/cpp/tests/binary/util/operation.h +++ b/cpp/tests/binary/util/operation.h @@ -1,4 +1,6 @@ /* + * Copyright (c) 2019, NVIDIA CORPORATION. + * * Copyright 2018-2019 BlazingDB, Inc. * Copyright 2018 Christian Noboa Mardini * From 99a943f455feafeaf9babab837dbc82b47c3b790 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Wed, 6 Mar 2019 18:23:28 +0530 Subject: [PATCH 41/51] added TODO #1119 --- cpp/include/cudf/types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/include/cudf/types.h b/cpp/include/cudf/types.h index 44bf37f3c01e..7b0284beaa0d 100644 --- a/cpp/include/cudf/types.h +++ b/cpp/include/cudf/types.h @@ -91,6 +91,7 @@ typedef struct { * It stores a unique value for scalar type. * It has a direct relationship with the gdf_dtype. *---------------------------------------------------------------------------**/ +// TODO: #1119 Use traits to set `gdf_data` elements typedef union { int8_t si08; /**< GDF_INT8 */ int16_t si16; /**< GDF_INT16 */ @@ -108,7 +109,7 @@ typedef union { * *---------------------------------------------------------------------------**/ typedef struct { - gdf_data data; /**< Pointer to the scalar data */ + gdf_data data; /**< A union that represents the value */ gdf_dtype dtype; /**< The datatype of the scalar's data */ bool is_valid; /**< False if the value is null */ } gdf_scalar; From ec1116b75a75501c7b8a0b516d7688a15e6da3bf Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Mar 2019 05:05:26 +0530 Subject: [PATCH 42/51] documentation cleanup --- cpp/include/cudf/functions.h | 36 +++++++++++------------- cpp/src/binary/jit/code/operation.cpp | 39 -------------------------- cpp/src/binary/jit/core/launcher.cpp | 2 +- cpp/src/bitmask/bitmask_ops.h | 4 +-- cpp/tests/utilities/scalar_wrapper.cuh | 9 ++---- 5 files changed, 21 insertions(+), 69 deletions(-) diff --git a/cpp/include/cudf/functions.h b/cpp/include/cudf/functions.h index f337c7e1b17a..d03724539e4a 100644 --- a/cpp/include/cudf/functions.h +++ b/cpp/include/cudf/functions.h @@ -1961,59 +1961,55 @@ gdf_error gdf_extract_datetime_second(gdf_column *input, gdf_column *output); /* binary operators */ /** - * @brief Binary operation function between gdf_scalar and gdf_column structs. + * @brief Performs a binary operation between a gdf_scalar and a gdf_column. * - * The function performs the binary operation of a gdf_scalar operand and a - * gdf_column operand. - * - * The desired output type needs to be specified in out->dtype + * The desired output type must be specified in out->dtype. * - * If the valid field in the gdf_column output is not nullptr, then the valid - * mask from rhs gdf_column is copied into the data pointer to by out->valid + * If the valid field in the gdf_column output is not nullptr, then it will be + * filled with the bitwise AND of the valid mask of rhs gdf_column and is_valid + * bool of lhs gdf_scalar * * @param out (gdf_column) Output of the operation. * @param lhs (gdf_scalar) First operand of the operation. * @param rhs (gdf_column) Second operand of the operation. - * @param ope (enum) The binary operator that is going to be used in the operation. + * @param ope (enum) The binary operator to use * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ gdf_error gdf_binary_operation_s_v(gdf_column* out, gdf_scalar* lhs, gdf_column* rhs, gdf_binary_operator ope); /** - * @brief Binary operation function between gdf_column and gdf_scalar structs. + * @brief Performs a binary operation between a gdf_column and a gdf_scalar. * - * The function performs the binary operation of a gdf_column operand and a - * gdf_scalar operand. + * The desired output type must be specified in out->dtype. * - * The desired output type needs to be specified in out->dtype - * - * If the valid field in the gdf_column output is not nullptr, then the valid - * mask from lhs gdf_column is copied into the data pointer to by out->valid + * If the valid field in the gdf_column output is not nullptr, then it will be + * filled with the bitwise AND of the valid mask of lhs gdf_column and is_valid + * bool of rhs gdf_scalar * * @param out (gdf_column) Output of the operation. * @param lhs (gdf_column) First operand of the operation. * @param rhs (gdf_scalar) Second operand of the operation. - * @param ope (enum) The binary operator that is going to be used in the operation. + * @param ope (enum) The binary operator to use * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* rhs, gdf_binary_operator ope); /** - * @brief Binary operation function between two gdf_column structs. + * @brief Performs a binary operation between two gdf_columns. * * The function performs the binary operation of two gdf_column operands. * - * The desired output type needs to be specified in out->dtype + * The desired output type must be specified in out->dtype. * * If the valid field in the gdf_column output is not nullptr, then it will be - * filled with the bitwise AND of the valid masks of lhs and rhs gdf_column's + * filled with the bitwise AND of the valid masks of lhs and rhs gdf_columns * * @param out (gdf_column) Output of the operation. * @param lhs (gdf_column) First operand of the operation. * @param rhs (gdf_column) Second operand of the operation. - * @param ope (enum) The binary operator that is going to be used in the operation. + * @param ope (enum) The binary operator to use * @return GDF_SUCCESS if the operation was successful, otherwise an appropriate * error code */ diff --git a/cpp/src/binary/jit/code/operation.cpp b/cpp/src/binary/jit/code/operation.cpp index 5b8765112284..4591a89c51ce 100644 --- a/cpp/src/binary/jit/code/operation.cpp +++ b/cpp/src/binary/jit/code/operation.cpp @@ -242,45 +242,6 @@ R"***( }; )***"; -/* - * The following code could be used to detect overflow or underflow - * using 'Bit Hacks' in the operations, that's why the operation is - * divided into signed, unsigned and double functions. It's required - * to create a new field on gdf_column for this feature. - * - * struct Add { - * template , - * enable_if_t<(isIntegralSigned)>* = nullptr> - * __device__ - * TypeOut operate(TypeLhs x, TypeRhs y) { - * return static_cast(t)((Common)x + (Common)y); - * } - * - * template , - * enable_if_t<(isIntegralUnsigned)>* = nullptr> - * __device__ - * TypeOut operate(TypeLhs x, TypeRhs y) { - * return static_cast(t)((Common)x + (Common)y); - * } - * - * template , - * enable_if_t<(isFloatingPoint)>* = nullptr> - * __device__ - * TypeOut operate(TypeLhs x, TypeRhs y) { - * return static_cast(t)((Common)x + (Common)y); - * } - * }; - */ - } // namespace code } // namespace jit } // namespace binops diff --git a/cpp/src/binary/jit/core/launcher.cpp b/cpp/src/binary/jit/core/launcher.cpp index cd94f19e7ab3..619642f26556 100644 --- a/cpp/src/binary/jit/core/launcher.cpp +++ b/cpp/src/binary/jit/core/launcher.cpp @@ -27,7 +27,7 @@ namespace binops { namespace jit { /**---------------------------------------------------------------------------* - * @brief Cache to hold previously compiled code in. If JITIFY_THREAD_SAFE is + * @brief Cache to hold previously compiled code. If JITIFY_THREAD_SAFE is * defined, then the cache is held globally in the process, otherwise it is * held locally in each thread * diff --git a/cpp/src/bitmask/bitmask_ops.h b/cpp/src/bitmask/bitmask_ops.h index 589cb7e07ac0..b74faf3b552b 100644 --- a/cpp/src/bitmask/bitmask_ops.h +++ b/cpp/src/bitmask/bitmask_ops.h @@ -6,9 +6,9 @@ /**---------------------------------------------------------------------------* * @brief Sets all bits in input valid mask to 1 * - * @param valid_out preallocated valid mask to set the values for + * @param valid_out preallocated output valid mask * @param out_null_count number of nulls (0 bits) in valid mask. Always set to 0 - * @param num_values number of values in column for which the output mask was made + * @param num_values number of values in column associated with output mask * @param stream cuda stream to run in * @return gdf_error *---------------------------------------------------------------------------**/ diff --git a/cpp/tests/utilities/scalar_wrapper.cuh b/cpp/tests/utilities/scalar_wrapper.cuh index 5f165d64ad84..166c4d21b726 100644 --- a/cpp/tests/utilities/scalar_wrapper.cuh +++ b/cpp/tests/utilities/scalar_wrapper.cuh @@ -34,7 +34,7 @@ namespace test { * @brief Wrapper for a gdf_scalar used for unit testing. * * An abstraction on top of a gdf_scalar that provides functionality for - * allocating, intiailizing, and otherwise managing gdf_scalar's for passing to + * allocating, intiailizing, and otherwise managing gdf_scalars for passing to * libcudf APIs in unit testing. * * @tparam ColumnType The underlying data type of the scalar @@ -44,9 +44,6 @@ struct scalar_wrapper { /**---------------------------------------------------------------------------* * @brief Implicit conversion operator to a gdf_scalar pointer. * - * Allows for implicit conversion of a column_wrapper to a pointer to its - * underlying gdf_scalar. - * * In this way, a column_wrapper can be passed directly into a libcudf API * and will be implicitly converted to a pointer to its underlying gdf_scalar * without the need to use the `get()` member. @@ -72,7 +69,6 @@ struct scalar_wrapper { /**---------------------------------------------------------------------------* * @brief Returns a pointer to the underlying gdf_scalar. - * *---------------------------------------------------------------------------**/ gdf_scalar* get() { return &the_scalar; } gdf_scalar const* get() const { return &the_scalar; } @@ -95,7 +91,6 @@ struct scalar_wrapper { /**---------------------------------------------------------------------------* * @brief Prints the value of the underlying gdf_scalar. - * *---------------------------------------------------------------------------**/ void print() const { ScalarType value = *reinterpret_cast(&(the_scalar.data)); @@ -106,7 +101,7 @@ struct scalar_wrapper { } /**---------------------------------------------------------------------------* - * @brief Compares if another scalar_wrapper is equal to this wrapper. + * @brief CompCompares this wrapper with another scalar_wrapper for equality. * * @param rhs The other scalar_wrapper to check for equality * @return true The two scalars are equal From c0243e68ca419fbb358156cf366d0d8af91c2a95 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Mar 2019 13:44:23 +0530 Subject: [PATCH 43/51] one more doc change that i missed. --- cpp/include/cudf/functions.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/include/cudf/functions.h b/cpp/include/cudf/functions.h index d03724539e4a..65826d6aeeab 100644 --- a/cpp/include/cudf/functions.h +++ b/cpp/include/cudf/functions.h @@ -1999,8 +1999,6 @@ gdf_error gdf_binary_operation_v_s(gdf_column* out, gdf_column* lhs, gdf_scalar* /** * @brief Performs a binary operation between two gdf_columns. * - * The function performs the binary operation of two gdf_column operands. - * * The desired output type must be specified in out->dtype. * * If the valid field in the gdf_column output is not nullptr, then it will be From 9c729c71af6a41543a0ea2b3a12ef439dbeddc37 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Mar 2019 16:10:01 +0530 Subject: [PATCH 44/51] changed JITIFY thread safe macro in CMakeLists --- cpp/CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 69dd3276d3de..645110b58b71 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -224,6 +224,7 @@ SET_TARGET_PROPERTIES(cudf PROPERTIES BUILD_RPATH "\$ORIGIN") ################################################################################################### # - jitify ---------------------------------------------------------------------------------------- +# Creates executable stringify and uses it to convert types.h to c-str for use in JIT code add_executable(stringify "${CMAKE_SOURCE_DIR}/thirdparty/jitify/stringify.cpp") execute_process(WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include) @@ -239,6 +240,13 @@ add_custom_target(stringify_run DEPENDS ${CMAKE_BINARY_DIR}/include/types.h.jit) add_dependencies(cudf stringify_run) + +option(JITIFY_PROCESS_CACHE "Use a process level (instead of thread level) cache for JIT compiled kernels" ON) +if(JITIFY_PROCESS_CACHE) + message(STATUS "Using process level cache for JIT compiled kernels") + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --define-macro JITIFY_THREAD_SAFE") +endif(JITIFY_PROCESS_CACHE) + ################################################################################################### # - build options --------------------------------------------------------------------------------- @@ -256,12 +264,6 @@ if(HT_LEGACY_ALLOCATOR) set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --define-macro HT_LEGACY_ALLOCATOR") endif(HT_LEGACY_ALLOCATOR) -option(JITIFY_THREAD_SAFE "Use a global cache for JIT compiled kernels" ON) -if(JITIFY_THREAD_SAFE) - message(STATUS "Using global cache for JIT compiled kernels") - set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --define-macro JITIFY_THREAD_SAFE") -endif(JITIFY_THREAD_SAFE) - ################################################################################################### # - link libraries -------------------------------------------------------------------------------- From 4626f7d995a545206195aedf74ad7369dbf0f484 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Mar 2019 21:51:39 +0530 Subject: [PATCH 45/51] Changed union members to typedef'd versions --- cpp/include/cudf/types.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cpp/include/cudf/types.h b/cpp/include/cudf/types.h index 7b0284beaa0d..5a31e110f934 100644 --- a/cpp/include/cudf/types.h +++ b/cpp/include/cudf/types.h @@ -93,15 +93,15 @@ typedef struct { *---------------------------------------------------------------------------**/ // TODO: #1119 Use traits to set `gdf_data` elements typedef union { - int8_t si08; /**< GDF_INT8 */ - int16_t si16; /**< GDF_INT16 */ - int32_t si32; /**< GDF_INT32 */ - int64_t si64; /**< GDF_INT64 */ - float fp32; /**< GDF_FLOAT32 */ - double fp64; /**< GDF_FLOAT64 */ - int32_t dt32; /**< GDF_DATE32 */ - int64_t dt64; /**< GDF_DATE64 */ - int64_t tmst; /**< GDF_TIMESTAMP */ + int8_t si08; /**< GDF_INT8 */ + int16_t si16; /**< GDF_INT16 */ + int32_t si32; /**< GDF_INT32 */ + int64_t si64; /**< GDF_INT64 */ + float fp32; /**< GDF_FLOAT32 */ + double fp64; /**< GDF_FLOAT64 */ + gdf_date32 dt32; /**< GDF_DATE32 */ + gdf_date64 dt64; /**< GDF_DATE64 */ + gdf_timestamp tmst; /**< GDF_TIMESTAMP */ } gdf_data; /**---------------------------------------------------------------------------* From 7fe729a267818e4e0a701c4f3d75269cee53114b Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Mar 2019 22:46:55 +0530 Subject: [PATCH 46/51] include the changed location of `error_utils.hpp` --- cpp/src/binary/jit/core/binop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/binary/jit/core/binop.cpp b/cpp/src/binary/jit/core/binop.cpp index 17a0e1b435b6..dddf9ea407ad 100644 --- a/cpp/src/binary/jit/core/binop.cpp +++ b/cpp/src/binary/jit/core/binop.cpp @@ -20,7 +20,7 @@ #include "binary/jit/core/launcher.h" #include "binary/jit/util/operator.h" #include "bitmask/bitmask_ops.h" -#include "utilities/error_utils.h" +#include "utilities/error_utils.hpp" #include "utilities/cudf_utils.h" #include "cudf.h" From 79d5111a3f4427e21227551e81d49df993c07b83 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Mar 2019 23:12:00 +0530 Subject: [PATCH 47/51] updated jitify --- thirdparty/jitify | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/jitify b/thirdparty/jitify index 727b1ebf06c5..c7c55b38333f 160000 --- a/thirdparty/jitify +++ b/thirdparty/jitify @@ -1 +1 @@ -Subproject commit 727b1ebf06c598f7584fa076032359236530e0a6 +Subproject commit c7c55b38333f5fa9ad5ec5e0804d5c9eedd14de2 From 8c110733c60239c85f73f1c7531ea420ff3a1675 Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Thu, 7 Mar 2019 23:44:51 +0530 Subject: [PATCH 48/51] Changed Cython binding map to dict. --- python/cudf/bindings/binops.pyx | 39 ++++++++++++++------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/python/cudf/bindings/binops.pyx b/python/cudf/bindings/binops.pyx index 461c1f4b6c1c..59a3b95208a9 100644 --- a/python/cudf/bindings/binops.pyx +++ b/python/cudf/bindings/binops.pyx @@ -10,31 +10,26 @@ from .cudf_cpp cimport * from .cudf_cpp import * - from librmm_cffi import librmm as rmm - -from libc.stdint cimport uintptr_t from libc.stdlib cimport free -from libcpp.map cimport map as cmap -from libcpp.string cimport string as cstring -cdef cmap[cstring, gdf_binary_operator] _BINARY_OP -_BINARY_OP[b'add'] = GDF_ADD -_BINARY_OP[b'sub'] = GDF_SUB -_BINARY_OP[b'mul'] = GDF_MUL -_BINARY_OP[b'div'] = GDF_DIV -_BINARY_OP[b'truediv'] = GDF_TRUE_DIV -_BINARY_OP[b'floordiv'] = GDF_FLOOR_DIV -_BINARY_OP[b'mod'] = GDF_MOD -_BINARY_OP[b'pow'] = GDF_POW -_BINARY_OP[b'eq'] = GDF_EQUAL -_BINARY_OP[b'ne'] = GDF_NOT_EQUAL -_BINARY_OP[b'lt'] = GDF_LESS -_BINARY_OP[b'gt'] = GDF_GREATER -_BINARY_OP[b'le'] = GDF_LESS_EQUAL -_BINARY_OP[b'ge'] = GDF_GREATER_EQUAL +_BINARY_OP = {} +_BINARY_OP['add'] = GDF_ADD +_BINARY_OP['sub'] = GDF_SUB +_BINARY_OP['mul'] = GDF_MUL +_BINARY_OP['div'] = GDF_DIV +_BINARY_OP['truediv'] = GDF_TRUE_DIV +_BINARY_OP['floordiv'] = GDF_FLOOR_DIV +_BINARY_OP['mod'] = GDF_MOD +_BINARY_OP['pow'] = GDF_POW +_BINARY_OP['eq'] = GDF_EQUAL +_BINARY_OP['ne'] = GDF_NOT_EQUAL +_BINARY_OP['lt'] = GDF_LESS +_BINARY_OP['gt'] = GDF_GREATER +_BINARY_OP['le'] = GDF_LESS_EQUAL +_BINARY_OP['ge'] = GDF_GREATER_EQUAL def apply_op(lhs, rhs, out, op): @@ -42,8 +37,6 @@ def apply_op(lhs, rhs, out, op): Call JITified gdf binary ops. """ - oper = bytes(op, encoding="UTF-8") - check_gdf_compatibility(lhs) check_gdf_compatibility(rhs) check_gdf_compatibility(out) @@ -53,7 +46,7 @@ def apply_op(lhs, rhs, out, op): cdef gdf_column* c_out = column_view_from_column(out) cdef gdf_error result - cdef gdf_binary_operator c_op = _BINARY_OP[oper] + cdef gdf_binary_operator c_op = _BINARY_OP[op] with nogil: result = gdf_binary_operation_v_v( c_out, From 87e0b41a32aac64936c683d18307f236d592a25f Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Fri, 8 Mar 2019 00:57:58 +0530 Subject: [PATCH 49/51] Clean Cmakelists --- cpp/CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 645110b58b71..77324e4a779e 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -232,7 +232,7 @@ execute_process(WORKING_DIRECTORY ${CMAKE_BINARY_DIR} add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/include/types.h.jit WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include COMMAND ${CMAKE_BINARY_DIR}/stringify cudf/types.h > ${CMAKE_BINARY_DIR}/include/types.h.jit - COMMENT "stringify header types.h" + COMMENT "Run stringify on header types.h to convert it to c-str for use in JIT compiled code" DEPENDS stringify MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/include/cudf/types.h) @@ -240,7 +240,6 @@ add_custom_target(stringify_run DEPENDS ${CMAKE_BINARY_DIR}/include/types.h.jit) add_dependencies(cudf stringify_run) - option(JITIFY_PROCESS_CACHE "Use a process level (instead of thread level) cache for JIT compiled kernels" ON) if(JITIFY_PROCESS_CACHE) message(STATUS "Using process level cache for JIT compiled kernels") @@ -301,7 +300,7 @@ add_custom_command(OUTPUT INSTALL_PYTHON_CFFI add_custom_target(install_python DEPENDS cudf rmm_install_python PYTHON_CFFI INSTALL_PYTHON_CFFI) - ################################################################################################### +################################################################################################### # - make documentation ---------------------------------------------------------------------------- add_custom_command(OUTPUT CUDF_DOXYGEN From 09ffe367db1a06035dd83b2881ac9e6aba17f4cb Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Sat, 9 Mar 2019 00:44:08 +0530 Subject: [PATCH 50/51] Use rapids' fork of Jitify submodule. --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 36f7151aa93f..11ba585fe79e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,4 +12,4 @@ branch = branch-0.6 [submodule "thirdparty/jitify"] path = thirdparty/jitify - url = https://github.com/NVIDIA/jitify.git + url = https://github.com/rapidsai/jitify.git From 2bfa21e32e23b8268a1773052e4a6021218b648a Mon Sep 17 00:00:00 2001 From: Devavret Makkar Date: Sat, 9 Mar 2019 04:17:22 +0530 Subject: [PATCH 51/51] now pointing to a branch in Forked Jitify --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 11ba585fe79e..c0f28a452af9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,4 @@ [submodule "thirdparty/jitify"] path = thirdparty/jitify url = https://github.com/rapidsai/jitify.git + branch = cudf \ No newline at end of file