mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-23 04:20:56 +08:00
Compare commits
6 Commits
minivec-e2
...
minivec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
421116c8cd | ||
|
|
3623c64d82 | ||
|
|
18be1fda24 | ||
|
|
e10a5c90df | ||
|
|
3b0976b725 | ||
|
|
724bde5020 |
@@ -69,11 +69,6 @@ CheckElement(fp8 value)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATA_EXCEPTION),
|
||||
errmsg("NaN not allowed in minivec")));
|
||||
|
||||
if (Fp8IsInf(value))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATA_EXCEPTION),
|
||||
errmsg("infinite value not allowed in minivec")));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -174,7 +169,7 @@ minivec_in(PG_FUNCTION_ARGS)
|
||||
x[dim] = Float4ToFp8Unchecked(val);
|
||||
|
||||
/* Check for range error like float4in */
|
||||
if ((errno == ERANGE && isinf(val)) || (Fp8IsInf(x[dim]) && !isinf(val)))
|
||||
if ((errno == ERANGE && isinf(val)) || (Fp8IsNan(x[dim]) && !isnan(val)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("\"%s\" is out of range for type minivec", pnstrdup(pt, stringEnd - pt))));
|
||||
@@ -657,7 +652,6 @@ MinivecL1Distance(int dim, fp8 * ax, fp8 * bx)
|
||||
{
|
||||
float distance = 0.0;
|
||||
|
||||
/* Auto-vectorized */
|
||||
for (int i = 0; i < dim; i++)
|
||||
distance += fabsf(Fp8ToFloat4(ax[i]) - Fp8ToFloat4(bx[i]));
|
||||
|
||||
@@ -702,7 +696,6 @@ minivec_l2_norm(PG_FUNCTION_ARGS)
|
||||
fp8 *ax = a->x;
|
||||
double norm = 0.0;
|
||||
|
||||
/* Auto-vectorized */
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
{
|
||||
double axi = (double) Fp8ToFloat4(ax[i]);
|
||||
@@ -729,7 +722,6 @@ minivec_l2_normalize(PG_FUNCTION_ARGS)
|
||||
result = InitMiniVector(a->dim);
|
||||
rx = result->x;
|
||||
|
||||
/* Auto-vectorized */
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
norm += (double) Fp8ToFloat4(ax[i]) * (double) Fp8ToFloat4(ax[i]);
|
||||
|
||||
@@ -744,7 +736,7 @@ minivec_l2_normalize(PG_FUNCTION_ARGS)
|
||||
/* Check for overflow */
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
{
|
||||
if (Fp8IsInf(rx[i]))
|
||||
if (Fp8IsNan(rx[i]))
|
||||
float_overflow_error();
|
||||
}
|
||||
}
|
||||
@@ -771,14 +763,13 @@ minivec_add(PG_FUNCTION_ARGS)
|
||||
result = InitMiniVector(a->dim);
|
||||
rx = result->x;
|
||||
|
||||
/* Auto-vectorized */
|
||||
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||
rx[i] = Float4ToFp8Unchecked(Fp8ToFloat4(ax[i]) + Fp8ToFloat4(bx[i]));
|
||||
|
||||
/* Check for overflow */
|
||||
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||
{
|
||||
if (Fp8IsInf(rx[i]))
|
||||
if (Fp8IsNan(rx[i]))
|
||||
float_overflow_error();
|
||||
}
|
||||
|
||||
@@ -804,14 +795,13 @@ minivec_sub(PG_FUNCTION_ARGS)
|
||||
result = InitMiniVector(a->dim);
|
||||
rx = result->x;
|
||||
|
||||
/* Auto-vectorized */
|
||||
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||
rx[i] = ax[i] - bx[i];
|
||||
rx[i] = Float4ToFp8Unchecked(Fp8ToFloat4(ax[i]) - Fp8ToFloat4(bx[i]));
|
||||
|
||||
/* Check for overflow */
|
||||
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||
{
|
||||
if (Fp8IsInf(rx[i]))
|
||||
if (Fp8IsNan(rx[i]))
|
||||
float_overflow_error();
|
||||
}
|
||||
|
||||
@@ -837,14 +827,13 @@ minivec_mul(PG_FUNCTION_ARGS)
|
||||
result = InitMiniVector(a->dim);
|
||||
rx = result->x;
|
||||
|
||||
/* Auto-vectorized */
|
||||
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||
rx[i] = Float4ToFp8Unchecked(Fp8ToFloat4(ax[i]) * Fp8ToFloat4(bx[i]));
|
||||
|
||||
/* Check for overflow and underflow */
|
||||
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||
{
|
||||
if (Fp8IsInf(rx[i]))
|
||||
if (Fp8IsNan(rx[i]))
|
||||
float_overflow_error();
|
||||
|
||||
if (Fp8IsZero(rx[i]) && !(Fp8IsZero(ax[i]) || Fp8IsZero(bx[i])))
|
||||
|
||||
@@ -26,16 +26,7 @@ MiniVector *InitMiniVector(int dim);
|
||||
static inline bool
|
||||
Fp8IsNan(fp8 num)
|
||||
{
|
||||
return (num & 0x7C) == 0x7C && (num & 0x7F) != 0x7C;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if fp8 is infinite
|
||||
*/
|
||||
static inline bool
|
||||
Fp8IsInf(fp8 num)
|
||||
{
|
||||
return (num & 0x7F) == 0x7C;
|
||||
return (num & 0x7F) == 0x7F;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -55,7 +46,7 @@ Fp8ToFloat4(fp8 num)
|
||||
{
|
||||
/* Lookup table for non-sign bits */
|
||||
/* Uses uint32 for correctness */
|
||||
uint32 lookup[128] = {0, 931135488, 939524096, 943718400, 947912704, 950009856, 952107008, 954204160, 956301312, 958398464, 960495616, 962592768, 964689920, 966787072, 968884224, 970981376, 973078528, 975175680, 977272832, 979369984, 981467136, 983564288, 985661440, 987758592, 989855744, 991952896, 994050048, 996147200, 998244352, 1000341504, 1002438656, 1004535808, 1006632960, 1008730112, 1010827264, 1012924416, 1015021568, 1017118720, 1019215872, 1021313024, 1023410176, 1025507328, 1027604480, 1029701632, 1031798784, 1033895936, 1035993088, 1038090240, 1040187392, 1042284544, 1044381696, 1046478848, 1048576000, 1050673152, 1052770304, 1054867456, 1056964608, 1059061760, 1061158912, 1063256064, 1065353216, 1067450368, 1069547520, 1071644672, 1073741824, 1075838976, 1077936128, 1080033280, 1082130432, 1084227584, 1086324736, 1088421888, 1090519040, 1092616192, 1094713344, 1096810496, 1098907648, 1101004800, 1103101952, 1105199104, 1107296256, 1109393408, 1111490560, 1113587712, 1115684864, 1117782016, 1119879168, 1121976320, 1124073472, 1126170624, 1128267776, 1130364928, 1132462080, 1134559232, 1136656384, 1138753536, 1140850688, 1142947840, 1145044992, 1147142144, 1149239296, 1151336448, 1153433600, 1155530752, 1157627904, 1159725056, 1161822208, 1163919360, 1166016512, 1168113664, 1170210816, 1172307968, 1174405120, 1176502272, 1178599424, 1180696576, 1182793728, 1184890880, 1186988032, 1189085184, 1191182336, 1193279488, 1195376640, 1197473792, 2139095040, 2145386496, 2143289344, 2145386496};
|
||||
uint32 lookup[128] = {0, 989855744, 998244352, 1002438656, 1006632960, 1008730112, 1010827264, 1012924416, 1015021568, 1016070144, 1017118720, 1018167296, 1019215872, 1020264448, 1021313024, 1022361600, 1023410176, 1024458752, 1025507328, 1026555904, 1027604480, 1028653056, 1029701632, 1030750208, 1031798784, 1032847360, 1033895936, 1034944512, 1035993088, 1037041664, 1038090240, 1039138816, 1040187392, 1041235968, 1042284544, 1043333120, 1044381696, 1045430272, 1046478848, 1047527424, 1048576000, 1049624576, 1050673152, 1051721728, 1052770304, 1053818880, 1054867456, 1055916032, 1056964608, 1058013184, 1059061760, 1060110336, 1061158912, 1062207488, 1063256064, 1064304640, 1065353216, 1066401792, 1067450368, 1068498944, 1069547520, 1070596096, 1071644672, 1072693248, 1073741824, 1074790400, 1075838976, 1076887552, 1077936128, 1078984704, 1080033280, 1081081856, 1082130432, 1083179008, 1084227584, 1085276160, 1086324736, 1087373312, 1088421888, 1089470464, 1090519040, 1091567616, 1092616192, 1093664768, 1094713344, 1095761920, 1096810496, 1097859072, 1098907648, 1099956224, 1101004800, 1102053376, 1103101952, 1104150528, 1105199104, 1106247680, 1107296256, 1108344832, 1109393408, 1110441984, 1111490560, 1112539136, 1113587712, 1114636288, 1115684864, 1116733440, 1117782016, 1118830592, 1119879168, 1120927744, 1121976320, 1123024896, 1124073472, 1125122048, 1126170624, 1127219200, 1128267776, 1129316352, 1130364928, 1131413504, 1132462080, 1133510656, 1134559232, 1135607808, 1136656384, 1137704960, 1138753536, 2146435072};
|
||||
|
||||
union
|
||||
{
|
||||
@@ -93,57 +84,52 @@ Float4ToFp8Unchecked(float num)
|
||||
/* Sign */
|
||||
result = (bin & 0x80000000) >> 24;
|
||||
|
||||
if (isinf(num))
|
||||
{
|
||||
/* Infinite */
|
||||
result |= 0x7C;
|
||||
}
|
||||
else if (isnan(num))
|
||||
if (isinf(num) || isnan(num))
|
||||
{
|
||||
/* NaN */
|
||||
result |= 0x7F;
|
||||
}
|
||||
else if (exponent > 98)
|
||||
else if (exponent > 114)
|
||||
{
|
||||
int m;
|
||||
int gr;
|
||||
int s;
|
||||
|
||||
exponent -= 127;
|
||||
s = mantissa & 0x000FFFFF;
|
||||
s = mantissa & 0x0007FFFF;
|
||||
|
||||
/* Subnormal */
|
||||
if (exponent < -14)
|
||||
if (exponent < -6)
|
||||
{
|
||||
int diff = -exponent - 14;
|
||||
int diff = -exponent - 6;
|
||||
|
||||
mantissa >>= diff;
|
||||
mantissa += 1 << (23 - diff);
|
||||
s |= mantissa & 0x000FFFFF;
|
||||
s |= mantissa & 0x0007FFFF;
|
||||
}
|
||||
|
||||
m = mantissa >> 21;
|
||||
m = mantissa >> 20;
|
||||
|
||||
/* Round */
|
||||
gr = (mantissa >> 20) % 4;
|
||||
gr = (mantissa >> 19) % 4;
|
||||
if (gr == 3 || (gr == 1 && s != 0))
|
||||
m += 1;
|
||||
|
||||
if (m == 4)
|
||||
if (m == 8)
|
||||
{
|
||||
m = 0;
|
||||
exponent += 1;
|
||||
}
|
||||
|
||||
if (exponent > 15)
|
||||
if (exponent > 8)
|
||||
{
|
||||
/* Infinite */
|
||||
result |= 0x7C;
|
||||
/* Infinite, which is NaN */
|
||||
result |= 0x7F;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exponent >= -14)
|
||||
result |= (exponent + 15) << 2;
|
||||
if (exponent >= -6)
|
||||
result |= (exponent + 7) << 3;
|
||||
|
||||
result |= m;
|
||||
}
|
||||
@@ -160,7 +146,7 @@ Float4ToFp8(float num)
|
||||
{
|
||||
fp8 result = Float4ToFp8Unchecked(num);
|
||||
|
||||
if (unlikely(Fp8IsInf(result)) && !isinf(num))
|
||||
if (unlikely(Fp8IsNan(result)) && !isinf(num))
|
||||
{
|
||||
char *buf = palloc(FLOAT_SHORTEST_DECIMAL_LEN);
|
||||
|
||||
|
||||
@@ -154,8 +154,8 @@ SELECT '[1,2,3]'::vector::minivec(3);
|
||||
|
||||
SELECT '[1,2,3]'::vector::minivec(2);
|
||||
ERROR: expected 2 dimensions, not 3
|
||||
SELECT '[61440]'::vector::minivec;
|
||||
ERROR: "61440" is out of range for type minivec
|
||||
SELECT '[465]'::vector::minivec;
|
||||
ERROR: "465" is out of range for type minivec
|
||||
SELECT '[1e-8]'::vector::minivec;
|
||||
minivec
|
||||
---------
|
||||
@@ -190,8 +190,8 @@ SELECT '{1,2,3}'::real[]::minivec(3);
|
||||
|
||||
SELECT '{1,2,3}'::real[]::minivec(2);
|
||||
ERROR: expected 2 dimensions, not 3
|
||||
SELECT '{61440,-61440}'::real[]::minivec;
|
||||
ERROR: "61440" is out of range for type minivec
|
||||
SELECT '{465,-465}'::real[]::minivec;
|
||||
ERROR: "465" is out of range for type minivec
|
||||
SELECT '{1e-8,-1e-8}'::real[]::minivec;
|
||||
minivec
|
||||
---------
|
||||
|
||||
@@ -37,22 +37,20 @@ ERROR: NaN not allowed in minivec
|
||||
LINE 1: SELECT '[NaN,1]'::minivec;
|
||||
^
|
||||
SELECT '[Infinity,1]'::minivec;
|
||||
ERROR: infinite value not allowed in minivec
|
||||
ERROR: "Infinity" is out of range for type minivec
|
||||
LINE 1: SELECT '[Infinity,1]'::minivec;
|
||||
^
|
||||
SELECT '[-Infinity,1]'::minivec;
|
||||
ERROR: infinite value not allowed in minivec
|
||||
ERROR: "-Infinity" is out of range for type minivec
|
||||
LINE 1: SELECT '[-Infinity,1]'::minivec;
|
||||
^
|
||||
SELECT '[61439,-61439]'::minivec;
|
||||
minivec
|
||||
----------------
|
||||
[57344,-57344]
|
||||
(1 row)
|
||||
|
||||
SELECT '[61440,-61440]'::minivec;
|
||||
ERROR: "61440" is out of range for type minivec
|
||||
LINE 1: SELECT '[61440,-61440]'::minivec;
|
||||
SELECT '[65519,-65519]'::minivec;
|
||||
ERROR: "65519" is out of range for type minivec
|
||||
LINE 1: SELECT '[65519,-65519]'::minivec;
|
||||
^
|
||||
SELECT '[65520,-65520]'::minivec;
|
||||
ERROR: "65520" is out of range for type minivec
|
||||
LINE 1: SELECT '[65520,-65520]'::minivec;
|
||||
^
|
||||
SELECT '[1e-8,-1e-8]'::minivec;
|
||||
minivec
|
||||
@@ -165,30 +163,30 @@ ERROR: expected 2 dimensions, not 3
|
||||
SELECT '[1,2,3]'::minivec + '[4,5,6]';
|
||||
?column?
|
||||
----------
|
||||
[5,7,8]
|
||||
[5,7,9]
|
||||
(1 row)
|
||||
|
||||
SELECT '[61439]'::minivec + '[61439]';
|
||||
SELECT '[448]'::minivec + '[448]';
|
||||
ERROR: value out of range: overflow
|
||||
SELECT '[1,2]'::minivec + '[3]';
|
||||
ERROR: different minivec dimensions 2 and 1
|
||||
SELECT '[1,2,3]'::minivec - '[4,5,6]';
|
||||
ERROR: value out of range: overflow
|
||||
SELECT '[-61439]'::minivec - '[61439]';
|
||||
?column?
|
||||
----------
|
||||
[-0]
|
||||
?column?
|
||||
------------
|
||||
[-3,-3,-3]
|
||||
(1 row)
|
||||
|
||||
SELECT '[-448]'::minivec - '[448]';
|
||||
ERROR: value out of range: overflow
|
||||
SELECT '[1,2]'::minivec - '[3]';
|
||||
ERROR: different minivec dimensions 2 and 1
|
||||
SELECT '[1,2,3]'::minivec * '[4,5,6]';
|
||||
?column?
|
||||
-----------
|
||||
[4,10,16]
|
||||
[4,10,18]
|
||||
(1 row)
|
||||
|
||||
SELECT '[61439]'::minivec * '[61439]';
|
||||
SELECT '[448]'::minivec * '[448]';
|
||||
ERROR: value out of range: overflow
|
||||
SELECT '[1e-7]'::minivec * '[1e-7]';
|
||||
?column?
|
||||
@@ -399,7 +397,7 @@ SELECT inner_product('[448]'::minivec, '[448]');
|
||||
SELECT inner_product('[1,1,1,1,1,1,1,1,1]'::minivec, '[1,2,3,4,5,6,7,8,9]');
|
||||
inner_product
|
||||
---------------
|
||||
44
|
||||
45
|
||||
(1 row)
|
||||
|
||||
SELECT '[1,2]'::minivec <#> '[3,4]';
|
||||
@@ -493,7 +491,7 @@ SELECT l1_distance('[1,2,3,4,5,6,7,8,9]'::minivec, '[1,2,3,4,5,6,7,8,9]');
|
||||
SELECT l1_distance('[1,2,3,4,5,6,7,8,9]'::minivec, '[0,3,2,5,4,7,6,9,8]');
|
||||
l1_distance
|
||||
-------------
|
||||
7
|
||||
9
|
||||
(1 row)
|
||||
|
||||
SELECT '[0,0]'::minivec <+> '[3,4]';
|
||||
@@ -503,9 +501,9 @@ SELECT '[0,0]'::minivec <+> '[3,4]';
|
||||
(1 row)
|
||||
|
||||
SELECT l2_normalize('[3,4]'::minivec);
|
||||
l2_normalize
|
||||
--------------
|
||||
[0.625,0.75]
|
||||
l2_normalize
|
||||
----------------
|
||||
[0.625,0.8125]
|
||||
(1 row)
|
||||
|
||||
SELECT l2_normalize('[3,0]'::minivec);
|
||||
|
||||
@@ -41,7 +41,7 @@ SELECT '{1e-8,-1e-8}'::real[]::halfvec;
|
||||
SELECT '[1,2,3]'::vector::minivec;
|
||||
SELECT '[1,2,3]'::vector::minivec(3);
|
||||
SELECT '[1,2,3]'::vector::minivec(2);
|
||||
SELECT '[61440]'::vector::minivec;
|
||||
SELECT '[465]'::vector::minivec;
|
||||
SELECT '[1e-8]'::vector::minivec;
|
||||
|
||||
SELECT '[1,2,3]'::minivec::vector;
|
||||
@@ -51,7 +51,7 @@ SELECT '[1,2,3]'::minivec::vector(2);
|
||||
SELECT '{1,2,3}'::real[]::minivec;
|
||||
SELECT '{1,2,3}'::real[]::minivec(3);
|
||||
SELECT '{1,2,3}'::real[]::minivec(2);
|
||||
SELECT '{61440,-61440}'::real[]::minivec;
|
||||
SELECT '{465,-465}'::real[]::minivec;
|
||||
SELECT '{1e-8,-1e-8}'::real[]::minivec;
|
||||
|
||||
SELECT '[0,1.5,0,3.5,0]'::vector::sparsevec;
|
||||
|
||||
@@ -7,8 +7,8 @@ SELECT '[hello,1]'::minivec;
|
||||
SELECT '[NaN,1]'::minivec;
|
||||
SELECT '[Infinity,1]'::minivec;
|
||||
SELECT '[-Infinity,1]'::minivec;
|
||||
SELECT '[61439,-61439]'::minivec;
|
||||
SELECT '[61440,-61440]'::minivec;
|
||||
SELECT '[65519,-65519]'::minivec;
|
||||
SELECT '[65520,-65520]'::minivec;
|
||||
SELECT '[1e-8,-1e-8]'::minivec;
|
||||
SELECT '[4e38,1]'::minivec;
|
||||
SELECT '[1e-46,1]'::minivec;
|
||||
@@ -38,15 +38,15 @@ SELECT unnest('{"[1,2,3]", "[4,5,6]"}'::minivec[]);
|
||||
SELECT '{"[1,2,3]"}'::minivec(2)[];
|
||||
|
||||
SELECT '[1,2,3]'::minivec + '[4,5,6]';
|
||||
SELECT '[61439]'::minivec + '[61439]';
|
||||
SELECT '[448]'::minivec + '[448]';
|
||||
SELECT '[1,2]'::minivec + '[3]';
|
||||
|
||||
SELECT '[1,2,3]'::minivec - '[4,5,6]';
|
||||
SELECT '[-61439]'::minivec - '[61439]';
|
||||
SELECT '[-448]'::minivec - '[448]';
|
||||
SELECT '[1,2]'::minivec - '[3]';
|
||||
|
||||
SELECT '[1,2,3]'::minivec * '[4,5,6]';
|
||||
SELECT '[61439]'::minivec * '[61439]';
|
||||
SELECT '[448]'::minivec * '[448]';
|
||||
SELECT '[1e-7]'::minivec * '[1e-7]';
|
||||
SELECT '[1,2]'::minivec * '[3]';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user