Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class XPackLicenseState {
);
messages.put(XPackField.REDACT_PROCESSOR, new String[] { "Executing a redact processor in an ingest pipeline will fail." });
messages.put(XPackField.INFERENCE, new String[] { "The Inference API is disabled" });
messages.put(XPackField.GPU_INDEXING, new String[] { "Indexing using a GPU is disabled." });
EXPIRATION_MESSAGES = Collections.unmodifiableMap(messages);
}

Expand All @@ -109,6 +110,7 @@ public class XPackLicenseState {
messages.put(XPackField.REDACT_PROCESSOR, XPackLicenseState::redactProcessorAcknowledgementMessages);
messages.put(XPackField.ESQL, XPackLicenseState::esqlAcknowledgementMessages);
messages.put(XPackField.INFERENCE, XPackLicenseState::inferenceApiAcknowledgementMessages);
messages.put(XPackField.GPU_INDEXING, XPackLicenseState::gpuIndexingAcknowledgementMessages);
ACKNOWLEDGMENT_MESSAGES = Collections.unmodifiableMap(messages);
}

Expand Down Expand Up @@ -376,6 +378,22 @@ private static String[] redactProcessorAcknowledgementMessages(OperationMode cur
return Strings.EMPTY_ARRAY;
}

private static String[] gpuIndexingAcknowledgementMessages(OperationMode currentMode, OperationMode newMode) {
switch (newMode) {
case BASIC:
case STANDARD:
case GOLD:
case PLATINUM:
switch (currentMode) {
case TRIAL:
case ENTERPRISE:
return new String[] { "Indexing using a GPU will be disabled" };
}
break;
}
return Strings.EMPTY_ARRAY;
}

private static boolean isBasic(OperationMode mode) {
return mode == OperationMode.BASIC;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public final class XPackField {

/** Name constant for the redact processor feature. */
public static final String REDACT_PROCESSOR = "redact_processor";
/** Name constant for the GPU indexing feature. */
public static final String GPU_INDEXING = "gpu_indexing";
public static final String ENTERPRISE_GEOIP_DOWNLOADER = "enterprise_geoip_downloader";
/** Name for Universal Profiling. */
public static final String UNIVERSAL_PROFILING = "universal_profiling";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,28 @@
import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper;
import org.elasticsearch.index.mapper.vectors.VectorsFormatProvider;
import org.elasticsearch.license.License;
import org.elasticsearch.license.LicenseUtils;
import org.elasticsearch.license.LicensedFeature;
import org.elasticsearch.logging.LogManager;
import org.elasticsearch.logging.Logger;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.internal.InternalVectorFormatProviderPlugin;
import org.elasticsearch.xpack.core.XPackField;
import org.elasticsearch.xpack.core.XPackPlugin;

import java.util.List;

public class GPUPlugin extends Plugin implements InternalVectorFormatProviderPlugin {

private static final Logger log = LogManager.getLogger(GPUPlugin.class);

public static final FeatureFlag GPU_FORMAT = new FeatureFlag("gpu_vectors_indexing");

private static final License.OperationMode MINIMUM_ALLOWED_LICENSE = License.OperationMode.ENTERPRISE;
public static final LicensedFeature.Momentary GPU_INDEXING_FEATURE = LicensedFeature.momentary(
null,
XPackField.GPU_INDEXING,
License.OperationMode.ENTERPRISE
);

private final GpuMode gpuMode;

Expand Down Expand Up @@ -75,7 +86,7 @@ public List<Setting<?>> getSettings() {
// Allow tests to override the license state
protected boolean isGpuIndexingFeatureAllowed() {
var licenseState = XPackPlugin.getSharedLicenseState();
return licenseState != null && licenseState.isAllowedByLicense(MINIMUM_ALLOWED_LICENSE);
return licenseState != null && GPU_INDEXING_FEATURE.check(licenseState);
}

@Override
Expand Down Expand Up @@ -115,9 +126,35 @@ public ReferenceDocs referenceDocs() {
@Override
public VectorsFormatProvider getVectorsFormatProvider() {
return (indexSettings, indexOptions, similarity, elementType) -> {
if (GPU_FORMAT.isEnabled() && isGpuIndexingFeatureAllowed()) {
if ((gpuMode == GpuMode.TRUE || (gpuMode == GpuMode.AUTO && GPUSupport.isSupported()))
&& vectorIndexAndElementTypeSupported(indexOptions.getType(), elementType)) {
if (GPU_FORMAT.isEnabled()) {
if (gpuMode == GpuMode.TRUE) {
assert GPUSupport.isSupported();
if (isGpuIndexingFeatureAllowed() == false) {
log.error(
String.format(
"[%s] is set to TRUE, but it is not allowed by the current license",
VECTORS_INDEXING_USE_GPU_NODE_SETTING.getKey()
),
LicenseUtils.newComplianceException(XPackField.GPU_INDEXING)
);
return null;
}
}

if (gpuMode == GpuMode.AUTO && GPUSupport.isSupported()) {
if (isGpuIndexingFeatureAllowed() == false) {
log.warn(
String.format(
"The current configuration supports GPU indexing, but it is not allowed by the current license. "
+ "If this is intentional, it is possible to suppress this message by setting [%s] to FALSE",
VECTORS_INDEXING_USE_GPU_NODE_SETTING.getKey()
)
);
return null;
}
}

if (vectorIndexAndElementTypeSupported(indexOptions.getType(), elementType)) {
return getVectorsFormat(indexOptions, similarity);
}
}
Expand Down