github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/add/add.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package add
    16  
    17  /*
    18  #include "mo.h"
    19  
    20  #cgo CFLAGS: -I../../../cgo
    21  #cgo LDFLAGS: -L../../../cgo -lmo -lm
    22  */
    23  import "C"
    24  
    25  import (
    26  	"unsafe"
    27  
    28  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    29  	"github.com/matrixorigin/matrixone/pkg/container/nulls"
    30  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    31  	"golang.org/x/exp/constraints"
    32  )
    33  
    34  const (
    35  	LEFT_IS_SCALAR  = 1
    36  	RIGHT_IS_SCALAR = 2
    37  )
    38  
    39  func signedOverflow[T constraints.Signed](a, b, c T) bool {
    40  	return (a > 0 && b > 0 && c < 0) || (a < 0 && b < 0 && c > 0)
    41  }
    42  
    43  func unsignedOverflow[T constraints.Unsigned](a, b, c T) bool {
    44  	return c < a || c < b
    45  }
    46  
    47  func NumericAddSigned[T constraints.Signed](xs, ys, rs *vector.Vector) error {
    48  	return cNumericAddSigned[T](xs, ys, rs)
    49  }
    50  
    51  func cNumericAddSigned[T constraints.Signed](xs, ys, rs *vector.Vector) error {
    52  	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[T](rs)
    53  	flag := 0
    54  	if xs.IsScalar() {
    55  		flag |= LEFT_IS_SCALAR
    56  	}
    57  	if ys.IsScalar() {
    58  		flag |= RIGHT_IS_SCALAR
    59  	}
    60  
    61  	rc := C.SignedInt_VecAdd(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]),
    62  		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(rs.Typ.TypeSize()))
    63  	if rc != 0 {
    64  		return moerr.NewOutOfRangeNoCtx("int", "int add overflow")
    65  	}
    66  	return nil
    67  }
    68  
    69  func goNumericAddSigned[T constraints.Signed](xs, ys, rs *vector.Vector) error {
    70  	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[T](rs)
    71  	if xs.IsScalar() {
    72  		for i, y := range yt {
    73  			if !nulls.Contains(rs.Nsp, uint64(i)) {
    74  				rt[i] = xt[0] + y
    75  				if signedOverflow(xt[0], y, rt[i]) {
    76  					return moerr.NewOutOfRangeNoCtx("int", "int add overflow")
    77  				}
    78  			}
    79  		}
    80  		return nil
    81  	} else if ys.IsScalar() {
    82  		for i, x := range xt {
    83  			if !nulls.Contains(rs.Nsp, uint64(i)) {
    84  				rt[i] = x + yt[0]
    85  				if signedOverflow(x, yt[0], rt[i]) {
    86  					return moerr.NewOutOfRangeNoCtx("int", "int add overflow")
    87  				}
    88  			}
    89  		}
    90  		return nil
    91  	} else {
    92  		for i, x := range xt {
    93  			if !nulls.Contains(rs.Nsp, uint64(i)) {
    94  				rt[i] = x + yt[i]
    95  				if signedOverflow(x, yt[i], rt[i]) {
    96  					return moerr.NewOutOfRangeNoCtx("int", "int add overflow")
    97  				}
    98  			}
    99  		}
   100  		return nil
   101  	}
   102  }
   103  
   104  func NumericAddUnsigned[T constraints.Unsigned](xs, ys, rs *vector.Vector) error {
   105  	return cNumericAddUnsigned[T](xs, ys, rs)
   106  }
   107  
   108  func cNumericAddUnsigned[T constraints.Unsigned](xs, ys, rs *vector.Vector) error {
   109  	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[T](rs)
   110  	flag := 0
   111  	if xs.IsScalar() {
   112  		flag |= LEFT_IS_SCALAR
   113  	}
   114  	if ys.IsScalar() {
   115  		flag |= RIGHT_IS_SCALAR
   116  	}
   117  
   118  	rc := C.UnsignedInt_VecAdd(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]),
   119  		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(rs.Typ.TypeSize()))
   120  	if rc != 0 {
   121  		return moerr.NewOutOfRangeNoCtx("unsigned int", "unsigned int add overflow")
   122  	}
   123  	return nil
   124  }
   125  
   126  func goNumericAddUnsigned[T constraints.Unsigned](xs, ys, rs *vector.Vector) error {
   127  	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[T](rs)
   128  	if xs.IsScalar() {
   129  		for i, y := range yt {
   130  			if !nulls.Contains(rs.Nsp, uint64(i)) {
   131  				rt[i] = xt[0] + y
   132  				if unsignedOverflow(xt[0], y, rt[i]) {
   133  					return moerr.NewOutOfRangeNoCtx("unsigned int", "unsigned int add overflow")
   134  				}
   135  			}
   136  		}
   137  		return nil
   138  	} else if ys.IsScalar() {
   139  		for i, x := range xt {
   140  			if !nulls.Contains(rs.Nsp, uint64(i)) {
   141  				rt[i] = x + yt[0]
   142  				if unsignedOverflow(x, yt[0], rt[i]) {
   143  					return moerr.NewOutOfRangeNoCtx("unsigned int", "unsigned int add overflow")
   144  				}
   145  			}
   146  		}
   147  		return nil
   148  	} else {
   149  		for i, x := range xt {
   150  			if !nulls.Contains(rs.Nsp, uint64(i)) {
   151  				rt[i] = x + yt[i]
   152  				if unsignedOverflow(x, yt[i], rt[i]) {
   153  					return moerr.NewOutOfRangeNoCtx("unsigned int", "unsigned int add overflow")
   154  				}
   155  			}
   156  		}
   157  		return nil
   158  	}
   159  }
   160  
   161  func NumericAddFloat[T constraints.Float](xs, ys, rs *vector.Vector) error {
   162  	return cNumericAddFloat[T](xs, ys, rs)
   163  }
   164  
   165  func cNumericAddFloat[T constraints.Float](xs, ys, rs *vector.Vector) error {
   166  	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[T](rs)
   167  	flag := 0
   168  	if xs.IsScalar() {
   169  		flag |= LEFT_IS_SCALAR
   170  	}
   171  	if ys.IsScalar() {
   172  		flag |= RIGHT_IS_SCALAR
   173  	}
   174  
   175  	rc := C.Float_VecAdd(unsafe.Pointer(&rt[0]), unsafe.Pointer(&xt[0]), unsafe.Pointer(&yt[0]),
   176  		C.uint64_t(len(rt)), (*C.uint64_t)(nulls.Ptr(rs.Nsp)), C.int32_t(flag), C.int32_t(rs.Typ.TypeSize()))
   177  	if rc != 0 {
   178  		return moerr.NewOutOfRangeNoCtx("float", "float add overflow")
   179  	}
   180  	return nil
   181  }
   182  
   183  func goNumericAddFloat[T constraints.Float](xs, ys, rs *vector.Vector) error {
   184  	xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[T](rs)
   185  	if xs.IsScalar() {
   186  		for i, y := range yt {
   187  			if !nulls.Contains(rs.Nsp, uint64(i)) {
   188  				rt[i] = xt[0] + y
   189  			}
   190  		}
   191  		return nil
   192  	} else if ys.IsScalar() {
   193  		for i, x := range xt {
   194  			if !nulls.Contains(rs.Nsp, uint64(i)) {
   195  				rt[i] = x + yt[0]
   196  			}
   197  		}
   198  		return nil
   199  	} else {
   200  		for i, x := range xt {
   201  			if !nulls.Contains(rs.Nsp, uint64(i)) {
   202  				rt[i] = x + yt[i]
   203  			}
   204  		}
   205  		return nil
   206  	}
   207  }
   208  
   209  func Uint32AddScalar(x uint32, ys []uint32, zs []uint32) {
   210  	rc := C.UnsignedInt_VecAdd(unsafe.Pointer(&zs[0]), unsafe.Pointer(&x), unsafe.Pointer(&ys[0]),
   211  		C.uint64_t(len(zs)), nil, C.int32_t(1), C.int32_t(4))
   212  	if rc != 0 {
   213  		panic(moerr.NewOutOfRangeNoCtx("uint32", "uint32 add overflow"))
   214  	}
   215  }