Skip to content

Commit bf7451f

Browse files
committed
Support arithmetic operations for dense_vectors: scalar version
Adds support for arithmetic operations - '+', '-', '*' and '/' when one operands is a dense_vector and other is scalar. Performs the arithmetic operation on each element of the dense_vector against the scalar operand. Closes #140538
1 parent 1098504 commit bf7451f

File tree

42 files changed

+4910
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+4910
-26
lines changed

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/util/NumericUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public static double asFiniteNumber(double dbl) {
166166
*/
167167
public static float asFiniteNumber(float flt) {
168168
if (Double.isNaN(flt) || Double.isInfinite(flt)) {
169-
throw new ArithmeticException("not a finite double number: " + flt);
169+
throw new ArithmeticException("not a finite float number: " + flt);
170170
}
171171
return flt;
172172
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.compute.ann;
9+
10+
import java.lang.annotation.ElementType;
11+
import java.lang.annotation.Retention;
12+
import java.lang.annotation.RetentionPolicy;
13+
import java.lang.annotation.Target;
14+
15+
@Target(ElementType.METHOD)
16+
@Retention(RetentionPolicy.SOURCE)
17+
public @interface DenseVectorEvaluator {
18+
/**
19+
* Extra part of the name of the evaluator. Use for disambiguating
20+
* when there are multiple ways to evaluate a function.
21+
*/
22+
String extraName() default "";
23+
24+
/**
25+
* Exceptions thrown by the process method to catch and convert
26+
* into a warning and turn into a null value.
27+
*/
28+
Class<? extends Exception>[] warnExceptions() default {};
29+
}

x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/DenseVectorEvaluatorImplementer.java

Lines changed: 409 additions & 0 deletions
Large diffs are not rendered by default.

x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorProcessor.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package org.elasticsearch.compute.gen;
99

1010
import org.elasticsearch.compute.ann.ConvertEvaluator;
11+
import org.elasticsearch.compute.ann.DenseVectorEvaluator;
1112
import org.elasticsearch.compute.ann.Evaluator;
1213
import org.elasticsearch.compute.ann.MvEvaluator;
1314

@@ -39,7 +40,8 @@ public Set<String> getSupportedOptions() {
3940

4041
@Override
4142
public Set<String> getSupportedAnnotationTypes() {
42-
return Set.of(Evaluator.class.getName(), MvEvaluator.class.getName(), ConvertEvaluator.class.getName());
43+
return Set.of(Evaluator.class.getName(), MvEvaluator.class.getName(), ConvertEvaluator.class.getName(),
44+
DenseVectorEvaluator.class.getName());
4345
}
4446

4547
@Override
@@ -68,7 +70,7 @@ public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv
6870
for (Element evaluatorMethod : roundEnvironment.getElementsAnnotatedWith(ann)) {
6971
var warnExceptionsTypes = Annotations.listAttributeValues(
7072
evaluatorMethod,
71-
Set.of(Evaluator.class, MvEvaluator.class, ConvertEvaluator.class),
73+
Set.of(Evaluator.class, MvEvaluator.class, ConvertEvaluator.class, DenseVectorEvaluator.class),
7274
"warnExceptions"
7375
);
7476
Evaluator evaluatorAnn = evaluatorMethod.getAnnotation(Evaluator.class);
@@ -134,6 +136,26 @@ public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv
134136
throw e;
135137
}
136138
}
139+
DenseVectorEvaluator denseVectorEvaluatorAnn = evaluatorMethod.getAnnotation(DenseVectorEvaluator.class);
140+
if (denseVectorEvaluatorAnn != null) {
141+
try {
142+
AggregatorProcessor.write(
143+
evaluatorMethod,
144+
"evaluator",
145+
new DenseVectorEvaluatorImplementer(
146+
env.getElementUtils(),
147+
env.getTypeUtils(),
148+
(ExecutableElement) evaluatorMethod,
149+
denseVectorEvaluatorAnn.extraName(),
150+
warnExceptionsTypes
151+
).sourceFile(),
152+
env
153+
);
154+
} catch (Exception e) {
155+
env.getMessager().printMessage(Diagnostic.Kind.ERROR, "failed to build " + evaluatorMethod.getEnclosingElement());
156+
throw e;
157+
}
158+
}
137159
}
138160
}
139161
return true;
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
id:l, vector_field_1:dense_vector, vector_field_2:dense_vector
2-
0, [1.0, 2.0, 3.0], [0.1, 0.2, 0.3]
3-
1, [4.0, 5.0, 6.0], [0.4, 0.5, 0.6]
4-
2, [9.0, 8.0, 7.0], [0.9, 0.8, 0.7]
5-
3, [0.054, 0.032, 0.012], [1.0, 2.0, 3.0]
1+
id:l, vector_field_1:dense_vector, vector_field_2:dense_vector, int_field:integer
2+
0, [1.0, 2.0, 3.0], [0.1, 0.2, 0.3], 4
3+
1, [4.0, 5.0, 6.0], [0.4, 0.5, 0.6], 5
4+
2, [9.0, 8.0, 7.0], [0.9, 0.8, 0.7], 6
5+
3, [0.054, 0.032, 0.012], [1.0, 2.0, 3.0], 7

x-pack/plugin/esql/qa/testFixtures/src/main/resources/dense_vector-arithmetic.csv-spec

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ null
8686
null
8787
;
8888

89+
addDenseVectorInt
90+
required_capability: dense_vector_arithmetic
91+
FROM dense_vector_arithmetic
92+
| eval result_vector = vector_field_1 + int_field
93+
| SORT id
94+
| KEEP result_vector;
95+
96+
result_vector:dense_vector
97+
[5.0, 6.0, 7.0]
98+
[9.0, 10.0, 11.0]
99+
[15.0, 14.0, 13.0]
100+
[7.054, 7.032, 7.012]
101+
;
102+
89103
// tests for sub operation
90104

91105
subDenseVectors
@@ -174,6 +188,20 @@ null
174188
null
175189
;
176190

191+
subDenseVectorInt
192+
required_capability: dense_vector_arithmetic
193+
FROM dense_vector_arithmetic
194+
| eval result_vector = vector_field_1 - int_field
195+
| SORT id
196+
| KEEP result_vector;
197+
198+
result_vector:dense_vector
199+
[-3.0, -2.0, -1.0]
200+
[-1.0, 0.0, 1.0]
201+
[3.0, 2.0, 1.0]
202+
[-6.946, -6.968, -6.988]
203+
;
204+
177205
// tests for mul operation
178206

179207
mulDenseVectors
@@ -262,6 +290,20 @@ null
262290
null
263291
;
264292

293+
mulDenseVectorInt
294+
required_capability: dense_vector_arithmetic
295+
FROM dense_vector_arithmetic
296+
| eval result_vector = vector_field_1 * int_field
297+
| SORT id
298+
| KEEP result_vector;
299+
300+
result_vector:dense_vector
301+
[4.0, 8.0, 12.0]
302+
[20.0, 25.0, 30.0]
303+
[54.0, 48.0, 42.0]
304+
[0.37800002, 0.224, 0.084]
305+
;
306+
265307
// tests for div operation
266308

267309
divDenseVectors
@@ -349,3 +391,17 @@ null
349391
null
350392
null
351393
;
394+
395+
divDenseVectorInt
396+
required_capability: dense_vector_arithmetic
397+
FROM dense_vector_arithmetic
398+
| eval result_vector = vector_field_1 / int_field
399+
| SORT id
400+
| KEEP result_vector;
401+
402+
result_vector:dense_vector
403+
[0.25, 0.5, 0.75]
404+
[0.8, 1.0, 1.2]
405+
[1.5, 1.3333334, 1.1666666]
406+
[0.007714286, 0.004571429, 0.0017142857]
407+
;

x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-dense_vector_arithmetic.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
"m": 16,
2121
"ef_construction": 100
2222
}
23+
},
24+
"int_field": {
25+
"type": "integer"
2326
}
2427
}
2528
}

x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/AddDenseVectorDoubleEvaluator.java

Lines changed: 149 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)