diff options
author | Lester Solbakken <lesters@oath.com> | 2019-10-11 09:40:18 +0200 |
---|---|---|
committer | Lester Solbakken <lesters@oath.com> | 2019-10-11 09:40:18 +0200 |
commit | d78ad93a081552d5f671e266a15c0de770305c92 (patch) | |
tree | fc13f929ae0e0be6eb4fe3f81ecb0d37eb82ec57 /model-evaluation | |
parent | 28913b4f7dc9597966c6e93f1a77af923549eea2 (diff) |
Support missing values in expression evaluation in Java
Diffstat (limited to 'model-evaluation')
-rw-r--r-- | model-evaluation/src/main/java/ai/vespa/models/evaluation/LazyArrayContext.java | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/model-evaluation/src/main/java/ai/vespa/models/evaluation/LazyArrayContext.java b/model-evaluation/src/main/java/ai/vespa/models/evaluation/LazyArrayContext.java index 4d1b5a97583..9045e335167 100644 --- a/model-evaluation/src/main/java/ai/vespa/models/evaluation/LazyArrayContext.java +++ b/model-evaluation/src/main/java/ai/vespa/models/evaluation/LazyArrayContext.java @@ -16,6 +16,7 @@ import com.yahoo.searchlib.rankingexpression.rule.ReferenceNode; import com.yahoo.tensor.TensorType; import java.util.Arrays; +import java.util.BitSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -28,10 +29,7 @@ import java.util.Set; */ public final class LazyArrayContext extends Context implements ContextIndex { - public final static Value defaultContextValue = DoubleValue.zero; - private final ExpressionFunction function; - private final IndexedBindings indexedBindings; private LazyArrayContext(ExpressionFunction function, IndexedBindings indexedBindings) { @@ -43,9 +41,10 @@ public final class LazyArrayContext extends Context implements ContextIndex { LazyArrayContext(ExpressionFunction function, Map<FunctionReference, ExpressionFunction> referencedFunctions, List<Constant> constants, - Model model) { + Model model, + Value missingValue) { this.function = function; - this.indexedBindings = new IndexedBindings(function, referencedFunctions, constants, this, model); + this.indexedBindings = new IndexedBindings(function, referencedFunctions, constants, this, model, missingValue); } /** @@ -121,6 +120,11 @@ public final class LazyArrayContext extends Context implements ContextIndex { return index; } + boolean isMissing(String name) { + Integer index = indexedBindings.indexOf(name); + return index == null || indexedBindings.isMissing(index); + } + /** * Creates a copy of this context suitable for evaluating against the same ranking expression * in a different thread or for re-binding free variables. @@ -134,18 +138,28 @@ public final class LazyArrayContext extends Context implements ContextIndex { /** The mapping from variable name to index */ private final ImmutableMap<String, Integer> nameToIndex; - /** The names which neeeds to be bound externally when envoking this (i.e not constant or invocation */ + /** The names which needs to be bound externally when envoking this (i.e not constant or invocation */ private final ImmutableSet<String> arguments; /** The current values set, pre-converted to doubles */ private final Value[] values; + /** The values that actually have been set */ + private final BitSet setValues; + + /** The value to return if not set */ + private final Value missingValue; + private IndexedBindings(ImmutableMap<String, Integer> nameToIndex, Value[] values, - ImmutableSet<String> arguments) { + ImmutableSet<String> arguments, + BitSet setValues, + Value missingValue) { this.nameToIndex = nameToIndex; this.values = values; this.arguments = arguments; + this.setValues = setValues; + this.missingValue = missingValue.freeze(); } /** @@ -156,15 +170,18 @@ public final class LazyArrayContext extends Context implements ContextIndex { Map<FunctionReference, ExpressionFunction> referencedFunctions, List<Constant> constants, LazyArrayContext owner, - Model model) { + Model model, + Value missingValue) { // 1. Determine and prepare bind targets Set<String> bindTargets = new LinkedHashSet<>(); Set<String> arguments = new LinkedHashSet<>(); // Arguments: Bind targets which need to be bound before invocation extractBindTargets(function.getBody().getRoot(), referencedFunctions, bindTargets, arguments); this.arguments = ImmutableSet.copyOf(arguments); + this.missingValue = missingValue.freeze(); values = new Value[bindTargets.size()]; - Arrays.fill(values, defaultContextValue); + Arrays.fill(values, this.missingValue); + setValues = new BitSet(bindTargets.size()); int i = 0; ImmutableMap.Builder<String, Integer> nameToIndexBuilder = new ImmutableMap.Builder<>(); @@ -172,19 +189,22 @@ public final class LazyArrayContext extends Context implements ContextIndex { nameToIndexBuilder.put(variable, i++); nameToIndex = nameToIndexBuilder.build(); - // 2. Bind the bind targets for (Constant constant : constants) { String constantReference = "constant(" + constant.name() + ")"; Integer index = nameToIndex.get(constantReference); - if (index != null) + if (index != null) { values[index] = new TensorValue(constant.value()); + setValues.set(index); + } } for (Map.Entry<FunctionReference, ExpressionFunction> referencedFunction : referencedFunctions.entrySet()) { Integer index = nameToIndex.get(referencedFunction.getKey().serialForm()); - if (index != null) // Referenced in this, so bind it + if (index != null) { // Referenced in this, so bind it values[index] = new LazyValue(referencedFunction.getKey(), owner, model); + setValues.set(index); + } } } @@ -227,16 +247,26 @@ public final class LazyArrayContext extends Context implements ContextIndex { } Value get(int index) { return values[index]; } - void set(int index, Value value) { values[index] = value; } + void set(int index, Value value) { + values[index] = value; + setValues.set(index); + } + Set<String> names() { return nameToIndex.keySet(); } Set<String> arguments() { return arguments; } Integer indexOf(String name) { return nameToIndex.get(name); } + boolean isMissing(int index) { return ! setValues.get(index); } IndexedBindings copy(Context context) { Value[] valueCopy = new Value[values.length]; - for (int i = 0; i < values.length; i++) - valueCopy[i] = values[i] instanceof LazyValue ? ((LazyValue)values[i]).copyFor(context) : values[i]; - return new IndexedBindings(nameToIndex, valueCopy, arguments); + BitSet setValuesCopy = new BitSet(values.length); + for (int i = 0; i < values.length; i++) { + valueCopy[i] = values[i] instanceof LazyValue ? ((LazyValue) values[i]).copyFor(context) : values[i]; + if (setValues.get(i)) { + setValuesCopy.set(i); + } + } + return new IndexedBindings(nameToIndex, valueCopy, arguments, setValuesCopy, missingValue); } } |