Skip to content

Commit fd8f602

Browse files
Merge branch 'main' into 2025/06/30/add-node-level-write-load-stats
2 parents b8d8e56 + ddc1df5 commit fd8f602

File tree

561 files changed

+16597
-5428
lines changed

Some content is hidden

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

561 files changed

+16597
-5428
lines changed

.buildkite/hooks/pre-command

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ if [[ "${USE_LUCENE_SNAPSHOT_CREDS:-}" == "true" ]]; then
6464
unset data
6565
fi
6666

67+
if [[ "${USE_MAVEN_GPG:-}" == "true" ]]; then
68+
vault_path="kv/ci-shared/release-eng/team-release-secrets/es-delivery/gpg"
69+
ORG_GRADLE_PROJECT_signingKey=$(vault kv get --field="private_key" $vault_path)
70+
ORG_GRADLE_PROJECT_signingPassword=$(vault kv get --field="passphase" $vault_path)
71+
export ORG_GRADLE_PROJECT_signingKey
72+
export ORG_GRADLE_PROJECT_signingPassword
73+
fi
74+
6775
if [[ "${USE_DRA_CREDENTIALS:-}" == "true" ]]; then
6876
DRA_VAULT_ROLE_ID_SECRET=$(vault read -field=role-id secret/ci/elastic-elasticsearch/legacy-vault-credentials)
6977
export DRA_VAULT_ROLE_ID_SECRET

.buildkite/pipelines/dra-workflow.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ steps:
22
- command: .buildkite/scripts/dra-workflow.sh
33
env:
44
USE_DRA_CREDENTIALS: "true"
5+
USE_MAVEN_GPG: "true"
56
USE_PROD_DOCKER_CREDENTIALS: "true"
67
agents:
78
provider: gcp

.buildkite/scripts/run-bc-upgrade-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ select(.active_release == true) |
2424
(.build_candidates | to_entries | sort_by(.value.completed_at))) |
2525
last | .value.manifest_url")"
2626

27-
if [[ -z "$MANIFEST_URL" ]]; then
27+
if [[ -z "$MANIFEST_URL" ]] || [[ "$MANIFEST_URL" == "null" ]]; then
2828
echo "No snapshots or build candidates for branch [$BUILDKITE_BRANCH]."
2929
echo "Skipping BC upgrade tests."
3030
exit 0

.buildkite/scripts/run-pr-upgrade-tests.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ fi
1818

1919
# Identify the merge base of the current commit (branch) and the base branch of the pull request.
2020
# PR upgrade tests are run from the merge base to the current commit.
21-
BASE_COMMIT=$(git merge-base $BUILDKITE_PULL_REQUEST_BASE_BRANCH $BUILDKITE_COMMIT)
21+
git fetch origin $BUILDKITE_PULL_REQUEST_BASE_BRANCH
22+
BASE_COMMIT=$(git merge-base origin/$BUILDKITE_PULL_REQUEST_BASE_BRANCH $BUILDKITE_COMMIT)
2223

2324
VERSION=$(sed -n 's/^elasticsearch[[:space:]]*=[[:space:]]*\(.*\)/\1/p' build-tools-internal/version.properties)
2425

benchmarks/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import org.elasticsearch.gradle.OS
1313
apply plugin: org.elasticsearch.gradle.internal.ElasticsearchJavaBasePlugin
1414
apply plugin: 'java-library'
1515
apply plugin: 'application'
16+
apply plugin: 'elasticsearch.mrjar'
1617

1718
var os = org.gradle.internal.os.OperatingSystem.current()
1819

@@ -46,6 +47,7 @@ dependencies {
4647
api(project(':x-pack:plugin:core'))
4748
api(project(':x-pack:plugin:esql'))
4849
api(project(':x-pack:plugin:esql:compute'))
50+
implementation project(path: ':libs:native')
4951
implementation project(path: ':libs:simdvec')
5052
expression(project(path: ':modules:lang-expression', configuration: 'zip'))
5153
painless(project(path: ':modules:lang-painless', configuration: 'zip'))
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
package org.elasticsearch.benchmark.vector;
10+
11+
import org.apache.lucene.util.VectorUtil;
12+
import org.elasticsearch.common.logging.LogConfigurator;
13+
import org.elasticsearch.common.logging.NodeNamePatternConverter;
14+
import org.elasticsearch.nativeaccess.NativeAccess;
15+
import org.elasticsearch.nativeaccess.VectorSimilarityFunctions;
16+
import org.openjdk.jmh.annotations.Benchmark;
17+
import org.openjdk.jmh.annotations.BenchmarkMode;
18+
import org.openjdk.jmh.annotations.Fork;
19+
import org.openjdk.jmh.annotations.Level;
20+
import org.openjdk.jmh.annotations.Measurement;
21+
import org.openjdk.jmh.annotations.Mode;
22+
import org.openjdk.jmh.annotations.OutputTimeUnit;
23+
import org.openjdk.jmh.annotations.Param;
24+
import org.openjdk.jmh.annotations.Scope;
25+
import org.openjdk.jmh.annotations.Setup;
26+
import org.openjdk.jmh.annotations.State;
27+
import org.openjdk.jmh.annotations.TearDown;
28+
import org.openjdk.jmh.annotations.Warmup;
29+
30+
import java.lang.foreign.Arena;
31+
import java.lang.foreign.MemorySegment;
32+
import java.util.concurrent.ThreadLocalRandom;
33+
import java.util.concurrent.TimeUnit;
34+
35+
@BenchmarkMode(Mode.AverageTime)
36+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
37+
@State(Scope.Benchmark)
38+
@Warmup(iterations = 3, time = 1)
39+
@Measurement(iterations = 5, time = 1)
40+
public class JDKVectorInt7uBenchmark {
41+
42+
static {
43+
NodeNamePatternConverter.setGlobalNodeName("foo");
44+
LogConfigurator.loadLog4jPlugins();
45+
LogConfigurator.configureESLogging(); // native access requires logging to be initialized
46+
}
47+
48+
byte[] byteArrayA;
49+
byte[] byteArrayB;
50+
MemorySegment heapSegA, heapSegB;
51+
MemorySegment nativeSegA, nativeSegB;
52+
53+
Arena arena;
54+
55+
@Param({ "1", "128", "207", "256", "300", "512", "702", "1024" })
56+
public int size;
57+
58+
@Setup(Level.Iteration)
59+
public void init() {
60+
byteArrayA = new byte[size];
61+
byteArrayB = new byte[size];
62+
for (int i = 0; i < size; ++i) {
63+
randomInt7BytesBetween(byteArrayA);
64+
randomInt7BytesBetween(byteArrayB);
65+
}
66+
heapSegA = MemorySegment.ofArray(byteArrayA);
67+
heapSegB = MemorySegment.ofArray(byteArrayB);
68+
69+
arena = Arena.ofConfined();
70+
nativeSegA = arena.allocate((long) byteArrayA.length);
71+
MemorySegment.copy(MemorySegment.ofArray(byteArrayA), 0L, nativeSegA, 0L, byteArrayA.length);
72+
nativeSegB = arena.allocate((long) byteArrayB.length);
73+
MemorySegment.copy(MemorySegment.ofArray(byteArrayB), 0L, nativeSegB, 0L, byteArrayB.length);
74+
}
75+
76+
@TearDown
77+
public void teardown() {
78+
arena.close();
79+
}
80+
81+
@Benchmark
82+
@Fork(value = 3, jvmArgsPrepend = { "--add-modules=jdk.incubator.vector" })
83+
public int dotProductLucene() {
84+
return VectorUtil.dotProduct(byteArrayA, byteArrayB);
85+
}
86+
87+
@Benchmark
88+
@Fork(value = 3, jvmArgsPrepend = { "--add-modules=jdk.incubator.vector" })
89+
public int dotProductNativeWithNativeSeg() {
90+
return dotProduct7u(nativeSegA, nativeSegB, size);
91+
}
92+
93+
@Benchmark
94+
@Fork(value = 3, jvmArgsPrepend = { "--add-modules=jdk.incubator.vector" })
95+
public int dotProductNativeWithHeapSeg() {
96+
return dotProduct7u(heapSegA, heapSegB, size);
97+
}
98+
99+
static final VectorSimilarityFunctions vectorSimilarityFunctions = vectorSimilarityFunctions();
100+
101+
static VectorSimilarityFunctions vectorSimilarityFunctions() {
102+
return NativeAccess.instance().getVectorSimilarityFunctions().get();
103+
}
104+
105+
int dotProduct7u(MemorySegment a, MemorySegment b, int length) {
106+
try {
107+
return (int) vectorSimilarityFunctions.dotProductHandle7u().invokeExact(a, b, length);
108+
} catch (Throwable e) {
109+
if (e instanceof Error err) {
110+
throw err;
111+
} else if (e instanceof RuntimeException re) {
112+
throw re;
113+
} else {
114+
throw new RuntimeException(e);
115+
}
116+
}
117+
}
118+
119+
// Unsigned int7 byte vectors have values in the range of 0 to 127 (inclusive).
120+
static final byte MIN_INT7_VALUE = 0;
121+
static final byte MAX_INT7_VALUE = 127;
122+
123+
static void randomInt7BytesBetween(byte[] bytes) {
124+
var random = ThreadLocalRandom.current();
125+
for (int i = 0, len = bytes.length; i < len;) {
126+
bytes[i++] = (byte) random.nextInt(MIN_INT7_VALUE, MAX_INT7_VALUE + 1);
127+
}
128+
}
129+
}

benchmarks/src/main/java/org/elasticsearch/benchmark/vector/OptimizedScalarQuantizerBenchmark.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ public class OptimizedScalarQuantizerBenchmark {
4343

4444
float[] vector;
4545
float[] centroid;
46-
byte[] destination;
46+
byte[] legacyDestination;
47+
int[] destination;
4748

4849
@Param({ "1", "4", "7" })
4950
byte bits;
@@ -54,7 +55,8 @@ public class OptimizedScalarQuantizerBenchmark {
5455
public void init() {
5556
ThreadLocalRandom random = ThreadLocalRandom.current();
5657
// random byte arrays for binary methods
57-
destination = new byte[dims];
58+
legacyDestination = new byte[dims];
59+
destination = new int[dims];
5860
vector = new float[dims];
5961
centroid = new float[dims];
6062
for (int i = 0; i < dims; ++i) {
@@ -65,13 +67,20 @@ public void init() {
6567

6668
@Benchmark
6769
public byte[] scalar() {
68-
osq.scalarQuantize(vector, destination, bits, centroid);
69-
return destination;
70+
osq.legacyScalarQuantize(vector, legacyDestination, bits, centroid);
71+
return legacyDestination;
72+
}
73+
74+
@Benchmark
75+
@Fork(jvmArgsPrepend = { "--add-modules=jdk.incubator.vector" })
76+
public byte[] legacyVector() {
77+
osq.legacyScalarQuantize(vector, legacyDestination, bits, centroid);
78+
return legacyDestination;
7079
}
7180

7281
@Benchmark
7382
@Fork(jvmArgsPrepend = { "--add-modules=jdk.incubator.vector" })
74-
public byte[] vector() {
83+
public int[] vector() {
7584
osq.scalarQuantize(vector, destination, bits, centroid);
7685
return destination;
7786
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.benchmark.vector;
11+
12+
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
13+
14+
import org.apache.lucene.util.Constants;
15+
import org.elasticsearch.test.ESTestCase;
16+
import org.junit.BeforeClass;
17+
import org.openjdk.jmh.annotations.Param;
18+
19+
import java.util.Arrays;
20+
21+
public class JDKVectorInt7uBenchmarkTests extends ESTestCase {
22+
23+
final double delta = 1e-3;
24+
final int size;
25+
26+
public JDKVectorInt7uBenchmarkTests(int size) {
27+
this.size = size;
28+
}
29+
30+
@BeforeClass
31+
public static void skipWindows() {
32+
assumeFalse("doesn't work on windows yet", Constants.WINDOWS);
33+
}
34+
35+
static boolean supportsHeapSegments() {
36+
return Runtime.version().feature() >= 22;
37+
}
38+
39+
public void testDotProduct() {
40+
for (int i = 0; i < 100; i++) {
41+
var bench = new JDKVectorInt7uBenchmark();
42+
bench.size = size;
43+
bench.init();
44+
try {
45+
float expected = dotProductScalar(bench.byteArrayA, bench.byteArrayB);
46+
assertEquals(expected, bench.dotProductLucene(), delta);
47+
assertEquals(expected, bench.dotProductNativeWithNativeSeg(), delta);
48+
if (supportsHeapSegments()) {
49+
assertEquals(expected, bench.dotProductNativeWithHeapSeg(), delta);
50+
}
51+
} finally {
52+
bench.teardown();
53+
}
54+
}
55+
}
56+
57+
@ParametersFactory
58+
public static Iterable<Object[]> parametersFactory() {
59+
try {
60+
var params = JDKVectorInt7uBenchmark.class.getField("size").getAnnotationsByType(Param.class)[0].value();
61+
return () -> Arrays.stream(params).map(Integer::parseInt).map(i -> new Object[] { i }).iterator();
62+
} catch (NoSuchFieldException e) {
63+
throw new AssertionError(e);
64+
}
65+
}
66+
67+
/** Computes the dot product of the given vectors a and b. */
68+
static int dotProductScalar(byte[] a, byte[] b) {
69+
int res = 0;
70+
for (int i = 0; i < a.length; i++) {
71+
res += a[i] * b[i];
72+
}
73+
return res;
74+
}
75+
}

build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/PublishPlugin.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@
1010
package org.elasticsearch.gradle.internal.conventions;
1111

1212
import groovy.util.Node;
13+
import nmcp.NmcpPlugin;
1314

1415
import com.github.jengelman.gradle.plugins.shadow.ShadowExtension;
1516
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin;
1617

17-
import nmcp.NmcpPlugin;
18-
1918
import org.elasticsearch.gradle.internal.conventions.info.GitInfo;
2019
import org.elasticsearch.gradle.internal.conventions.precommit.PomValidationPrecommitPlugin;
2120
import org.elasticsearch.gradle.internal.conventions.util.Util;
@@ -41,6 +40,8 @@
4140
import org.gradle.api.tasks.bundling.Jar;
4241
import org.gradle.initialization.layout.BuildLayout;
4342
import org.gradle.language.base.plugins.LifecycleBasePlugin;
43+
import org.gradle.plugins.signing.SigningExtension;
44+
import org.gradle.plugins.signing.SigningPlugin;
4445
import org.w3c.dom.Element;
4546

4647
import java.io.File;
@@ -69,6 +70,7 @@ public void apply(Project project) {
6970
project.getPluginManager().apply(PomValidationPrecommitPlugin.class);
7071
project.getPluginManager().apply(LicensingPlugin.class);
7172
project.getPluginManager().apply(NmcpPlugin.class);
73+
project.getPluginManager().apply(SigningPlugin.class);
7274
configureJavadocJar(project);
7375
configureSourcesJar(project);
7476
configurePomGeneration(project);
@@ -79,6 +81,13 @@ public void apply(Project project) {
7981
private void configurePublications(Project project) {
8082
var publishingExtension = project.getExtensions().getByType(PublishingExtension.class);
8183
var publication = publishingExtension.getPublications().create("elastic", MavenPublication.class);
84+
Provider<String> signingKey = project.getProviders().gradleProperty("signingKey");
85+
if (signingKey.isPresent()) {
86+
SigningExtension signing = project.getExtensions().getByType(SigningExtension.class);
87+
signing.useInMemoryPgpKeys(signingKey.get(), project.getProviders().gradleProperty("signingPassword").get());
88+
signing.sign(publication);
89+
}
90+
8291
project.afterEvaluate(project1 -> {
8392
if (project1.getPlugins().hasPlugin(ShadowPlugin.class)) {
8493
configureWithShadowPlugin(project1, publication);
@@ -166,6 +175,8 @@ private void addNameAndDescriptionToPom(Project project, NamedDomainObjectSet<Ma
166175
private static void configureWithShadowPlugin(Project project, MavenPublication publication) {
167176
var shadow = project.getExtensions().getByType(ShadowExtension.class);
168177
shadow.component(publication);
178+
publication.artifact(project.getTasks().named("javadocJar"));
179+
publication.artifact(project.getTasks().named("sourcesJar"));
169180
}
170181

171182
private static void addScmInfo(XmlProvider xml, GitInfo gitInfo) {

0 commit comments

Comments
 (0)