mirror of
https://github.com/pgvector/pgvector.git
synced 2026-06-06 05:51:21 +08:00
Added more functions for halfvec
This commit is contained in:
@@ -882,6 +882,9 @@ Each half vector takes `2 * dimensions + 8` bytes of storage. Each element is a
|
|||||||
|
|
||||||
Operator | Description | Added
|
Operator | Description | Added
|
||||||
--- | --- | ---
|
--- | --- | ---
|
||||||
|
\+ | element-wise addition | unreleased
|
||||||
|
\- | element-wise subtraction | unreleased
|
||||||
|
\* | element-wise multiplication | unreleased
|
||||||
<-> | Euclidean distance | unreleased
|
<-> | Euclidean distance | unreleased
|
||||||
<#> | negative inner product | unreleased
|
<#> | negative inner product | unreleased
|
||||||
<=> | cosine distance | unreleased
|
<=> | cosine distance | unreleased
|
||||||
@@ -891,6 +894,8 @@ Operator | Description | Added
|
|||||||
Function | Description | Added
|
Function | Description | Added
|
||||||
--- | --- | ---
|
--- | --- | ---
|
||||||
cosine_distance(halfvec, halfvec) → double precision | cosine distance | unreleased
|
cosine_distance(halfvec, halfvec) → double precision | cosine distance | unreleased
|
||||||
|
halfvec_dims(halfvec) → integer | number of dimensions | unreleased
|
||||||
|
halfvec_norm(halfvec) → double precision | Euclidean norm | unreleased
|
||||||
inner_product(halfvec, halfvec) → double precision | inner product | unreleased
|
inner_product(halfvec, halfvec) → double precision | inner product | unreleased
|
||||||
l2_distance(halfvec, halfvec) → double precision | Euclidean distance | unreleased
|
l2_distance(halfvec, halfvec) → double precision | Euclidean distance | unreleased
|
||||||
l1_distance(halfvec, halfvec) → double precision | taxicab distance | unreleased
|
l1_distance(halfvec, halfvec) → double precision | taxicab distance | unreleased
|
||||||
|
|||||||
@@ -71,15 +71,48 @@ CREATE FUNCTION cosine_distance(halfvec, halfvec) RETURNS float8
|
|||||||
CREATE FUNCTION l1_distance(halfvec, halfvec) RETURNS float8
|
CREATE FUNCTION l1_distance(halfvec, halfvec) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME', 'halfvec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME', 'halfvec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_dims(halfvec) RETURNS integer
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE FUNCTION halfvec_norm(halfvec) RETURNS float8
|
CREATE FUNCTION halfvec_norm(halfvec) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_add(halfvec, halfvec) RETURNS halfvec
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_sub(halfvec, halfvec) RETURNS halfvec
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_mul(halfvec, halfvec) RETURNS halfvec
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE FUNCTION quantize_binary(halfvec) RETURNS bit
|
CREATE FUNCTION quantize_binary(halfvec) RETURNS bit
|
||||||
AS 'MODULE_PATHNAME', 'halfvec_quantize_binary' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME', 'halfvec_quantize_binary' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE FUNCTION subvector(halfvec, int, int) RETURNS halfvec
|
CREATE FUNCTION subvector(halfvec, int, int) RETURNS halfvec
|
||||||
AS 'MODULE_PATHNAME', 'halfvec_subvector' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME', 'halfvec_subvector' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_lt(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_le(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_eq(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_ne(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_ge(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_gt(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_cmp(halfvec, halfvec) RETURNS int4
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE FUNCTION halfvec_l2_squared_distance(halfvec, halfvec) RETURNS float8
|
CREATE FUNCTION halfvec_l2_squared_distance(halfvec, halfvec) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
@@ -140,6 +173,56 @@ CREATE OPERATOR <=> (
|
|||||||
COMMUTATOR = '<=>'
|
COMMUTATOR = '<=>'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR + (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_add,
|
||||||
|
COMMUTATOR = +
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR - (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_sub
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR * (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_mul,
|
||||||
|
COMMUTATOR = *
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR < (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_lt,
|
||||||
|
COMMUTATOR = > , NEGATOR = >= ,
|
||||||
|
RESTRICT = scalarltsel, JOIN = scalarltjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <= (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_le,
|
||||||
|
COMMUTATOR = >= , NEGATOR = > ,
|
||||||
|
RESTRICT = scalarlesel, JOIN = scalarlejoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR = (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_eq,
|
||||||
|
COMMUTATOR = = , NEGATOR = <> ,
|
||||||
|
RESTRICT = eqsel, JOIN = eqjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <> (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_ne,
|
||||||
|
COMMUTATOR = <> , NEGATOR = = ,
|
||||||
|
RESTRICT = eqsel, JOIN = eqjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR >= (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_ge,
|
||||||
|
COMMUTATOR = <= , NEGATOR = < ,
|
||||||
|
RESTRICT = scalargesel, JOIN = scalargejoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR > (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_gt,
|
||||||
|
COMMUTATOR = < , NEGATOR = <= ,
|
||||||
|
RESTRICT = scalargtsel, JOIN = scalargtjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
CREATE OPERATOR CLASS halfvec_l2_ops
|
CREATE OPERATOR CLASS halfvec_l2_ops
|
||||||
FOR TYPE halfvec USING ivfflat AS
|
FOR TYPE halfvec USING ivfflat AS
|
||||||
OPERATOR 1 <-> (halfvec, halfvec) FOR ORDER BY float_ops,
|
OPERATOR 1 <-> (halfvec, halfvec) FOR ORDER BY float_ops,
|
||||||
@@ -184,7 +267,7 @@ CREATE FUNCTION vector_to_halfvec(vector, integer, boolean) RETURNS halfvec
|
|||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE CAST (halfvec AS vector)
|
CREATE CAST (halfvec AS vector)
|
||||||
WITH FUNCTION halfvec_to_vector(halfvec, integer, boolean) AS IMPLICIT;
|
WITH FUNCTION halfvec_to_vector(halfvec, integer, boolean) AS ASSIGNMENT;
|
||||||
|
|
||||||
CREATE CAST (vector AS halfvec)
|
CREATE CAST (vector AS halfvec)
|
||||||
WITH FUNCTION vector_to_halfvec(vector, integer, boolean) AS IMPLICIT;
|
WITH FUNCTION vector_to_halfvec(vector, integer, boolean) AS IMPLICIT;
|
||||||
|
|||||||
@@ -364,9 +364,21 @@ CREATE FUNCTION cosine_distance(halfvec, halfvec) RETURNS float8
|
|||||||
CREATE FUNCTION l1_distance(halfvec, halfvec) RETURNS float8
|
CREATE FUNCTION l1_distance(halfvec, halfvec) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME', 'halfvec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME', 'halfvec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_dims(halfvec) RETURNS integer
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE FUNCTION halfvec_norm(halfvec) RETURNS float8
|
CREATE FUNCTION halfvec_norm(halfvec) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_add(halfvec, halfvec) RETURNS halfvec
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_sub(halfvec, halfvec) RETURNS halfvec
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_mul(halfvec, halfvec) RETURNS halfvec
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE FUNCTION quantize_binary(halfvec) RETURNS bit
|
CREATE FUNCTION quantize_binary(halfvec) RETURNS bit
|
||||||
AS 'MODULE_PATHNAME', 'halfvec_quantize_binary' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME', 'halfvec_quantize_binary' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
@@ -375,6 +387,27 @@ CREATE FUNCTION subvector(halfvec, int, int) RETURNS halfvec
|
|||||||
|
|
||||||
-- halfvec private functions
|
-- halfvec private functions
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_lt(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_le(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_eq(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_ne(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_ge(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_gt(halfvec, halfvec) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION halfvec_cmp(halfvec, halfvec) RETURNS int4
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE FUNCTION halfvec_l2_squared_distance(halfvec, halfvec) RETURNS float8
|
CREATE FUNCTION halfvec_l2_squared_distance(halfvec, halfvec) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
@@ -441,6 +474,56 @@ CREATE OPERATOR <=> (
|
|||||||
COMMUTATOR = '<=>'
|
COMMUTATOR = '<=>'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR + (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_add,
|
||||||
|
COMMUTATOR = +
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR - (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_sub
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR * (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_mul,
|
||||||
|
COMMUTATOR = *
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR < (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_lt,
|
||||||
|
COMMUTATOR = > , NEGATOR = >= ,
|
||||||
|
RESTRICT = scalarltsel, JOIN = scalarltjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <= (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_le,
|
||||||
|
COMMUTATOR = >= , NEGATOR = > ,
|
||||||
|
RESTRICT = scalarlesel, JOIN = scalarlejoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR = (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_eq,
|
||||||
|
COMMUTATOR = = , NEGATOR = <> ,
|
||||||
|
RESTRICT = eqsel, JOIN = eqjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <> (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_ne,
|
||||||
|
COMMUTATOR = <> , NEGATOR = = ,
|
||||||
|
RESTRICT = eqsel, JOIN = eqjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR >= (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_ge,
|
||||||
|
COMMUTATOR = <= , NEGATOR = < ,
|
||||||
|
RESTRICT = scalargesel, JOIN = scalargejoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR > (
|
||||||
|
LEFTARG = halfvec, RIGHTARG = halfvec, PROCEDURE = halfvec_gt,
|
||||||
|
COMMUTATOR = < , NEGATOR = <= ,
|
||||||
|
RESTRICT = scalargtsel, JOIN = scalargtjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
-- halfvec opclasses
|
-- halfvec opclasses
|
||||||
|
|
||||||
CREATE OPERATOR CLASS halfvec_l2_ops
|
CREATE OPERATOR CLASS halfvec_l2_ops
|
||||||
@@ -489,7 +572,7 @@ CREATE FUNCTION vector_to_halfvec(vector, integer, boolean) RETURNS halfvec
|
|||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
CREATE CAST (halfvec AS vector)
|
CREATE CAST (halfvec AS vector)
|
||||||
WITH FUNCTION halfvec_to_vector(halfvec, integer, boolean) AS IMPLICIT;
|
WITH FUNCTION halfvec_to_vector(halfvec, integer, boolean) AS ASSIGNMENT;
|
||||||
|
|
||||||
CREATE CAST (vector AS halfvec)
|
CREATE CAST (vector AS halfvec)
|
||||||
WITH FUNCTION vector_to_halfvec(vector, integer, boolean) AS IMPLICIT;
|
WITH FUNCTION vector_to_halfvec(vector, integer, boolean) AS IMPLICIT;
|
||||||
|
|||||||
@@ -41,6 +41,19 @@ HalfIsInf(half num)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if half is zero
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
HalfIsZero(half num)
|
||||||
|
{
|
||||||
|
#ifdef FLT16_SUPPORT
|
||||||
|
return num == 0;
|
||||||
|
#else
|
||||||
|
return (num & 0x7FFF) == 0x0000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert a half to a float4
|
* Convert a half to a float4
|
||||||
*/
|
*/
|
||||||
|
|||||||
241
src/halfvec.c
241
src/halfvec.c
@@ -146,6 +146,24 @@ halfvec_isspace(char ch)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM < 120003
|
||||||
|
static pg_noinline void
|
||||||
|
float_overflow_error(void)
|
||||||
|
{
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("value out of range: overflow")));
|
||||||
|
}
|
||||||
|
|
||||||
|
static pg_noinline void
|
||||||
|
float_underflow_error(void)
|
||||||
|
{
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("value out of range: underflow")));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert textual representation to internal representation
|
* Convert textual representation to internal representation
|
||||||
*/
|
*/
|
||||||
@@ -677,6 +695,18 @@ halfvec_l1_distance(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_FLOAT8((double) distance);
|
PG_RETURN_FLOAT8((double) distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the dimensions of a half vector
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_dims);
|
||||||
|
Datum
|
||||||
|
halfvec_dims(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
|
||||||
|
PG_RETURN_INT32(a->dim);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the L2 norm of a half vector
|
* Get the L2 norm of a half vector
|
||||||
*/
|
*/
|
||||||
@@ -699,6 +729,126 @@ halfvec_norm(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_FLOAT8(sqrt(norm));
|
PG_RETURN_FLOAT8(sqrt(norm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add half vectors
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_add);
|
||||||
|
Datum
|
||||||
|
halfvec_add(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
half *ax = a->x;
|
||||||
|
half *bx = b->x;
|
||||||
|
HalfVector *result;
|
||||||
|
half *rx;
|
||||||
|
|
||||||
|
CheckDims(a, b);
|
||||||
|
|
||||||
|
result = InitHalfVector(a->dim);
|
||||||
|
rx = result->x;
|
||||||
|
|
||||||
|
/* Auto-vectorized */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
{
|
||||||
|
#ifdef FLT16_SUPPORT
|
||||||
|
rx[i] = ax[i] + bx[i];
|
||||||
|
#else
|
||||||
|
rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) + HalfToFloat4(bx[i]));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for overflow */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
{
|
||||||
|
if (HalfIsInf(rx[i]))
|
||||||
|
float_overflow_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
PG_RETURN_POINTER(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Subtract half vectors
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_sub);
|
||||||
|
Datum
|
||||||
|
halfvec_sub(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
half *ax = a->x;
|
||||||
|
half *bx = b->x;
|
||||||
|
HalfVector *result;
|
||||||
|
half *rx;
|
||||||
|
|
||||||
|
CheckDims(a, b);
|
||||||
|
|
||||||
|
result = InitHalfVector(a->dim);
|
||||||
|
rx = result->x;
|
||||||
|
|
||||||
|
/* Auto-vectorized */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
{
|
||||||
|
#ifdef FLT16_SUPPORT
|
||||||
|
rx[i] = ax[i] - bx[i];
|
||||||
|
#else
|
||||||
|
rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for overflow */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
{
|
||||||
|
if (HalfIsInf(rx[i]))
|
||||||
|
float_overflow_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
PG_RETURN_POINTER(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiply half vectors
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_mul);
|
||||||
|
Datum
|
||||||
|
halfvec_mul(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
half *ax = a->x;
|
||||||
|
half *bx = b->x;
|
||||||
|
HalfVector *result;
|
||||||
|
half *rx;
|
||||||
|
|
||||||
|
CheckDims(a, b);
|
||||||
|
|
||||||
|
result = InitHalfVector(a->dim);
|
||||||
|
rx = result->x;
|
||||||
|
|
||||||
|
/* Auto-vectorized */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
{
|
||||||
|
#ifdef FLT16_SUPPORT
|
||||||
|
rx[i] = ax[i] * bx[i];
|
||||||
|
#else
|
||||||
|
rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) * HalfToFloat4(bx[i]));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for overflow and underflow */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
{
|
||||||
|
if (HalfIsInf(rx[i]))
|
||||||
|
float_overflow_error();
|
||||||
|
|
||||||
|
if (HalfIsZero(rx[i]) && !(HalfIsZero(ax[i]) || HalfIsZero(bx[i])))
|
||||||
|
float_underflow_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
PG_RETURN_POINTER(result);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Quantize a half vector
|
* Quantize a half vector
|
||||||
*/
|
*/
|
||||||
@@ -775,3 +925,94 @@ halfvec_cmp_internal(HalfVector * a, HalfVector * b)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Less than
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_lt);
|
||||||
|
Datum
|
||||||
|
halfvec_lt(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(halfvec_cmp_internal(a, b) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Less than or equal
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_le);
|
||||||
|
Datum
|
||||||
|
halfvec_le(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(halfvec_cmp_internal(a, b) <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Equal
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_eq);
|
||||||
|
Datum
|
||||||
|
halfvec_eq(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(halfvec_cmp_internal(a, b) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not equal
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ne);
|
||||||
|
Datum
|
||||||
|
halfvec_ne(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(halfvec_cmp_internal(a, b) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Greater than or equal
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ge);
|
||||||
|
Datum
|
||||||
|
halfvec_ge(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(halfvec_cmp_internal(a, b) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Greater than
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_gt);
|
||||||
|
Datum
|
||||||
|
halfvec_gt(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(halfvec_cmp_internal(a, b) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare half vectors
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_cmp);
|
||||||
|
Datum
|
||||||
|
halfvec_cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HalfVector *a = PG_GETARG_HALFVEC_P(0);
|
||||||
|
HalfVector *b = PG_GETARG_HALFVEC_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_INT32(halfvec_cmp_internal(a, b));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,149 @@
|
|||||||
|
SELECT '[1,2,3]'::halfvec + '[4,5,6]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
[5,7,9]
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[65519]'::halfvec + '[65519]';
|
||||||
|
ERROR: value out of range: overflow
|
||||||
|
SELECT '[1,2,3]'::halfvec - '[4,5,6]';
|
||||||
|
?column?
|
||||||
|
------------
|
||||||
|
[-3,-3,-3]
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[-65519]'::halfvec - '[65519]';
|
||||||
|
ERROR: value out of range: overflow
|
||||||
|
SELECT '[1,2,3]'::halfvec * '[4,5,6]';
|
||||||
|
?column?
|
||||||
|
-----------
|
||||||
|
[4,10,18]
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[65519]'::halfvec * '[65519]';
|
||||||
|
ERROR: value out of range: overflow
|
||||||
|
SELECT '[1e-7]'::halfvec * '[1e-7]';
|
||||||
|
ERROR: value out of range: underflow
|
||||||
|
SELECT '[1,2,3]'::halfvec < '[1,2,3]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec < '[1,2]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec <= '[1,2,3]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec <= '[1,2]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec = '[1,2,3]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec = '[1,2]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec != '[1,2,3]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec != '[1,2]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec >= '[1,2,3]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec >= '[1,2]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec > '[1,2,3]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec > '[1,2]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[1,2,3]', '[1,2,3]');
|
||||||
|
halfvec_cmp
|
||||||
|
-------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[1,2,3]', '[0,0,0]');
|
||||||
|
halfvec_cmp
|
||||||
|
-------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[0,0,0]', '[1,2,3]');
|
||||||
|
halfvec_cmp
|
||||||
|
-------------
|
||||||
|
-1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[1,2]', '[1,2,3]');
|
||||||
|
halfvec_cmp
|
||||||
|
-------------
|
||||||
|
-1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[1,2,3]', '[1,2]');
|
||||||
|
halfvec_cmp
|
||||||
|
-------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[1,2]', '[2,3,4]');
|
||||||
|
halfvec_cmp
|
||||||
|
-------------
|
||||||
|
-1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[2,3]', '[1,2,3]');
|
||||||
|
halfvec_cmp
|
||||||
|
-------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT halfvec_dims('[1,2,3]'::halfvec);
|
||||||
|
halfvec_dims
|
||||||
|
--------------
|
||||||
|
3
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT round(halfvec_norm('[1,1]')::numeric, 5);
|
SELECT round(halfvec_norm('[1,1]')::numeric, 5);
|
||||||
round
|
round
|
||||||
---------
|
---------
|
||||||
|
|||||||
@@ -1,3 +1,34 @@
|
|||||||
|
SELECT '[1,2,3]'::halfvec + '[4,5,6]';
|
||||||
|
SELECT '[65519]'::halfvec + '[65519]';
|
||||||
|
SELECT '[1,2,3]'::halfvec - '[4,5,6]';
|
||||||
|
SELECT '[-65519]'::halfvec - '[65519]';
|
||||||
|
SELECT '[1,2,3]'::halfvec * '[4,5,6]';
|
||||||
|
SELECT '[65519]'::halfvec * '[65519]';
|
||||||
|
SELECT '[1e-7]'::halfvec * '[1e-7]';
|
||||||
|
|
||||||
|
SELECT '[1,2,3]'::halfvec < '[1,2,3]';
|
||||||
|
SELECT '[1,2,3]'::halfvec < '[1,2]';
|
||||||
|
SELECT '[1,2,3]'::halfvec <= '[1,2,3]';
|
||||||
|
SELECT '[1,2,3]'::halfvec <= '[1,2]';
|
||||||
|
SELECT '[1,2,3]'::halfvec = '[1,2,3]';
|
||||||
|
SELECT '[1,2,3]'::halfvec = '[1,2]';
|
||||||
|
SELECT '[1,2,3]'::halfvec != '[1,2,3]';
|
||||||
|
SELECT '[1,2,3]'::halfvec != '[1,2]';
|
||||||
|
SELECT '[1,2,3]'::halfvec >= '[1,2,3]';
|
||||||
|
SELECT '[1,2,3]'::halfvec >= '[1,2]';
|
||||||
|
SELECT '[1,2,3]'::halfvec > '[1,2,3]';
|
||||||
|
SELECT '[1,2,3]'::halfvec > '[1,2]';
|
||||||
|
|
||||||
|
SELECT halfvec_cmp('[1,2,3]', '[1,2,3]');
|
||||||
|
SELECT halfvec_cmp('[1,2,3]', '[0,0,0]');
|
||||||
|
SELECT halfvec_cmp('[0,0,0]', '[1,2,3]');
|
||||||
|
SELECT halfvec_cmp('[1,2]', '[1,2,3]');
|
||||||
|
SELECT halfvec_cmp('[1,2,3]', '[1,2]');
|
||||||
|
SELECT halfvec_cmp('[1,2]', '[2,3,4]');
|
||||||
|
SELECT halfvec_cmp('[2,3]', '[1,2,3]');
|
||||||
|
|
||||||
|
SELECT halfvec_dims('[1,2,3]'::halfvec);
|
||||||
|
|
||||||
SELECT round(halfvec_norm('[1,1]')::numeric, 5);
|
SELECT round(halfvec_norm('[1,1]')::numeric, 5);
|
||||||
SELECT halfvec_norm('[3,4]');
|
SELECT halfvec_norm('[3,4]');
|
||||||
SELECT halfvec_norm('[0,1]');
|
SELECT halfvec_norm('[0,1]');
|
||||||
|
|||||||
Reference in New Issue
Block a user