From 626870d56dcd8b4b199a643f29880b948641da8e Mon Sep 17 00:00:00 2001 From: Lester Solbakken Date: Mon, 21 Jun 2021 12:21:19 +0200 Subject: Add bit ranking function in Java --- searchlib/abi-spec.json | 4 +++- .../rankingexpression/evaluation/TensorValue.java | 1 + .../searchlib/rankingexpression/rule/Function.java | 4 +++- searchlib/src/main/javacc/RankingExpressionParser.jj | 4 +++- .../evaluation/EvaluationTestCase.java | 18 ++++++++++++++++++ vespajlib/src/main/java/com/yahoo/tensor/Tensor.java | 1 + 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/searchlib/abi-spec.json b/searchlib/abi-spec.json index 5035a5f583f..65151dd6ff0 100644 --- a/searchlib/abi-spec.json +++ b/searchlib/abi-spec.json @@ -1033,6 +1033,7 @@ "public static final int FMOD", "public static final int LDEXP", "public static final int POW", + "public static final int BIT", "public static final int MAP", "public static final int REDUCE", "public static final int JOIN", @@ -1387,7 +1388,8 @@ "public static final enum com.yahoo.searchlib.rankingexpression.rule.Function ldexp", "public static final enum com.yahoo.searchlib.rankingexpression.rule.Function max", "public static final enum com.yahoo.searchlib.rankingexpression.rule.Function min", - "public static final enum com.yahoo.searchlib.rankingexpression.rule.Function pow" + "public static final enum com.yahoo.searchlib.rankingexpression.rule.Function pow", + "public static final enum com.yahoo.searchlib.rankingexpression.rule.Function bit" ] }, "com.yahoo.searchlib.rankingexpression.rule.FunctionNode": { diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java index b109e6503e3..e41732f9d16 100644 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java @@ -156,6 +156,7 @@ public class TensorValue extends Value { case pow: return value.pow(argument); case fmod: return value.fmod(argument); case ldexp: return value.ldexp(argument); + case bit: return value.bit(argument); default: throw new UnsupportedOperationException("Cannot combine two tensors using " + function); } } diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Function.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Function.java index 99afb3b38d0..ad04832053f 100644 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Function.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/Function.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.searchlib.rankingexpression.rule; +import com.yahoo.tensor.Tensor; import com.yahoo.tensor.functions.ScalarFunctions; import java.io.Serializable; @@ -45,7 +46,8 @@ public enum Function implements Serializable { ldexp(2) { public double evaluate(double x, double y) { return x*pow(2,(int)y); } }, max(2) { public double evaluate(double x, double y) { return max(x,y); } }, min(2) { public double evaluate(double x, double y) { return min(x,y); } }, - pow(2) { public double evaluate(double x, double y) { return pow(x,y); } }; + pow(2) { public double evaluate(double x, double y) { return pow(x,y); } }, + bit(2) { public double evaluate(double x, double y) { return ((int)y < 8 && (int)y >= 8 && ((int)x & (1 << (int)y)) != 0) ? 1.0 : 0.0; } }; private final int arity; diff --git a/searchlib/src/main/javacc/RankingExpressionParser.jj b/searchlib/src/main/javacc/RankingExpressionParser.jj index 7506fe250fc..99eff010628 100755 --- a/searchlib/src/main/javacc/RankingExpressionParser.jj +++ b/searchlib/src/main/javacc/RankingExpressionParser.jj @@ -123,6 +123,7 @@ TOKEN : // MAX // MIN | + | | | @@ -733,7 +734,8 @@ Function binaryFunctionName() : { } { return Function.ldexp; } | { return Function.max; } | { return Function.min; } | - { return Function.pow; } + { return Function.pow; } | + { return Function.bit; } } List expressionList() : diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java index d6302d7026e..4a3c4b248be 100644 --- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java +++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java @@ -402,6 +402,24 @@ public class EvaluationTestCase { } + @Test + public void testBitExtraction() { + EvaluationTester tester = new EvaluationTester(); + tester.assertEvaluates(1.0, "bit(-43,7)"); + tester.assertEvaluates(1.0, "bit(-43,6)"); + tester.assertEvaluates(0.0, "bit(-43,5)"); + tester.assertEvaluates(1.0, "bit(-43,4)"); + tester.assertEvaluates(0.0, "bit(-43,3)"); + tester.assertEvaluates(1.0, "bit(-43,2)"); + tester.assertEvaluates(0.0, "bit(-43,1)"); + tester.assertEvaluates(1.0, "bit(-43,0)"); + tester.assertEvaluates( + "tensor(x[40]):[1,1,0,1,0,1,0,1, 0,0,0,0,0,0,0,0, 0,1,0,1,0,1,0,1, 0,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0]", + "tensor(x[40])(bit(tensor0{y:x / 8}, 7 - x % 8))", + "tensor(y[5]):[-43,0,85,127,-128]" + ); + } + @Test public void testCellTypeCasting() { EvaluationTester tester = new EvaluationTester(); diff --git a/vespajlib/src/main/java/com/yahoo/tensor/Tensor.java b/vespajlib/src/main/java/com/yahoo/tensor/Tensor.java index 3133752bc49..ab475e25387 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/Tensor.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/Tensor.java @@ -240,6 +240,7 @@ public interface Tensor { default Tensor equal(Tensor argument) { return join(argument, (a, b) -> ( a == b ? 1.0 : 0.0)); } default Tensor notEqual(Tensor argument) { return join(argument, (a, b) -> ( a != b ? 1.0 : 0.0)); } default Tensor approxEqual(Tensor argument) { return join(argument, (a, b) -> ( approxEquals(a,b) ? 1.0 : 0.0)); } + default Tensor bit(Tensor argument) { return join(argument, (a,b) -> ((int)b < 8 && (int)b >= 0 && ((int)a & (1 << (int)b)) != 0) ? 1.0 : 0.0); } default Tensor avg() { return avg(Collections.emptyList()); } default Tensor avg(String dimension) { return avg(Collections.singletonList(dimension)); } -- cgit v1.2.3