diff options
author | Lester Solbakken <lesters@users.noreply.github.com> | 2018-10-01 14:22:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-01 14:22:55 +0200 |
commit | fbca8fc6115fbf924cc688d927c50d8e9d99a321 (patch) | |
tree | caf9b072fdaf5b7aff2c6dad5056402caed3a393 /config-model | |
parent | e317da1b538ced3dd49d7f582a1c942a4a00d772 (diff) | |
parent | da1a20ab27fff180baf3f574774c3bbb57488fee (diff) |
Merge pull request #7155 from vespa-engine/bratseth/expose-type-information
Bratseth/expose type information
Diffstat (limited to 'config-model')
3 files changed, 50 insertions, 23 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java index 4c8b5910b78..3d1ef48c9dd 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java @@ -6,6 +6,7 @@ import com.yahoo.search.query.profile.QueryProfileRegistry; import com.yahoo.searchdefinition.RankProfile; import com.yahoo.searchdefinition.RankProfileRegistry; import com.yahoo.searchdefinition.Search; +import com.yahoo.searchlib.rankingexpression.ExpressionFunction; import com.yahoo.searchlib.rankingexpression.RankingExpression; import com.yahoo.searchlib.rankingexpression.Reference; import com.yahoo.searchlib.rankingexpression.rule.ExpressionNode; @@ -60,7 +61,7 @@ public class RankingExpressionTypeResolver extends Processor { private void resolveTypesIn(RankProfile profile, boolean validate) { TypeContext<Reference> context = profile.typeContext(queryProfiles); for (Map.Entry<String, RankProfile.RankingExpressionFunction> function : profile.getFunctions().entrySet()) { - if ( ! function.getValue().function().arguments().isEmpty()) continue; + if (hasUntypedArguments(function.getValue().function())) continue; TensorType type = resolveType(function.getValue().function().getBody(), "function '" + function.getKey() + "'", context); @@ -74,6 +75,10 @@ public class RankingExpressionTypeResolver extends Processor { } } + private boolean hasUntypedArguments(ExpressionFunction function) { + return function.arguments().size() > function.argumentTypes().size(); + } + private TensorType resolveType(RankingExpression expression, String expressionDescription, TypeContext context) { if (expression == null) return null; return resolveType(expression.getRoot(), expressionDescription, context); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java b/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java index 9ed82b9eef5..d2d5ecbd5aa 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java @@ -54,7 +54,7 @@ public class MlModelsTest { assertEquals("test", config.rankprofile(2).name()); RankProfilesConfig.Rankprofile.Fef test = config.rankprofile(2).fef(); - // Compare string content in a denser for that config: + // Compare profile content in a denser format than config: StringBuilder b = new StringBuilder(); for (RankProfilesConfig.Rankprofile.Fef.Property p : test.property()) b.append(p.name()).append(": ").append(p.value()).append("\n"); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java b/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java index 22bba9dd079..10de10bcdfe 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java @@ -36,6 +36,27 @@ import static org.junit.Assert.assertTrue; */ public class ModelEvaluationTest { + /** Tests that we do not load models (which would waste memory) when not requested */ + @Test + public void testMl_serving_not_activated() { + Path appDir = Path.fromString("src/test/cfg/application/ml_serving_not_activated"); + try { + ImportedModelTester tester = new ImportedModelTester("ml_serving", appDir); + VespaModel model = tester.createVespaModel(); + ContainerCluster cluster = model.getContainerClusters().get("container"); + assertNull(cluster.getComponentsMap().get(new ComponentId(ModelsEvaluator.class.getName()))); + + RankProfilesConfig.Builder b = new RankProfilesConfig.Builder(); + cluster.getConfig(b); + RankProfilesConfig config = new RankProfilesConfig(b); + + assertEquals(0, config.rankprofile().size()); + } + finally { + IOUtils.recursiveDeleteDir(appDir.append(ApplicationPackage.MODELS_GENERATED_DIR).toFile()); + } + } + @Test public void testMl_serving() throws IOException { Path appDir = Path.fromString("src/test/cfg/application/ml_serving"); @@ -58,27 +79,6 @@ public class ModelEvaluationTest { } } - /** Tests that we do not load models (which will waste memory) when not requested */ - @Test - public void testMl_serving_not_activated() { - Path appDir = Path.fromString("src/test/cfg/application/ml_serving_not_activated"); - try { - ImportedModelTester tester = new ImportedModelTester("ml_serving", appDir); - VespaModel model = tester.createVespaModel(); - ContainerCluster cluster = model.getContainerClusters().get("container"); - assertNull(cluster.getComponentsMap().get(new ComponentId(ModelsEvaluator.class.getName()))); - - RankProfilesConfig.Builder b = new RankProfilesConfig.Builder(); - cluster.getConfig(b); - RankProfilesConfig config = new RankProfilesConfig(b); - - assertEquals(0, config.rankprofile().size()); - } - finally { - IOUtils.recursiveDeleteDir(appDir.append(ApplicationPackage.MODELS_GENERATED_DIR).toFile()); - } - } - private void assertHasMlModels(VespaModel model) { ContainerCluster cluster = model.getContainerClusters().get("container"); assertNotNull(cluster.getComponentsMap().get(new ComponentId(ModelsEvaluator.class.getName()))); @@ -90,6 +90,7 @@ public class ModelEvaluationTest { RankProfilesConfig.Builder b = new RankProfilesConfig.Builder(); cluster.getConfig(b); RankProfilesConfig config = new RankProfilesConfig(b); + System.out.println(config); RankingConstantsConfig.Builder cb = new RankingConstantsConfig.Builder(); cluster.getConfig(cb); @@ -102,6 +103,12 @@ public class ModelEvaluationTest { assertTrue(modelNames.contains("mnist_softmax")); assertTrue(modelNames.contains("mnist_softmax_saved")); + // Compare profile content in a denser format than config: + StringBuilder sb = new StringBuilder(); + for (RankProfilesConfig.Rankprofile.Fef.Property p : findProfile("mnist_saved", config).property()) + sb.append(p.name()).append(": ").append(p.value()).append("\n"); + assertEquals(mnistProfile, sb.toString()); + ModelsEvaluator evaluator = new ModelsEvaluator(new ToleratingMissingConstantFilesRankProfilesConfigImporter(MockFileAcquirer.returnFile(null)) .importFrom(config, constantsConfig)); @@ -136,6 +143,21 @@ public class ModelEvaluationTest { assertNotNull(tensorflow_mnist_softmax.evaluatorOf("serving_default", "y")); } + private final String mnistProfile = + "rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add).rankingScript: join(reduce(join(rename(input, (d0, d1), (d0, d4)), constant(mnist_saved_dnn_hidden1_weights_read), f(a,b)(a * b)), sum, d4), constant(mnist_saved_dnn_hidden1_bias_read), f(a,b)(a + b))\n" + + "rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add).type: tensor(d3[300])\n" + + "rankingExpression(serving_default.y).rankingScript: join(reduce(join(map(join(reduce(join(join(join(rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add), 0.009999999776482582, f(a,b)(a * b)), rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add), f(a,b)(max(a,b))), constant(mnist_saved_dnn_hidden2_weights_read), f(a,b)(a * b)), sum, d3), constant(mnist_saved_dnn_hidden2_bias_read), f(a,b)(a + b)), f(a)(1.050701 * if (a >= 0, a, 1.673263 * (exp(a) - 1)))), constant(mnist_saved_dnn_outputs_weights_read), f(a,b)(a * b)), sum, d2), constant(mnist_saved_dnn_outputs_bias_read), f(a,b)(a + b))\n" + + "rankingExpression(serving_default.y).input.type: tensor(d0[],d1[784])\n" + + "rankingExpression(serving_default.y).type: tensor(d1[10])\n"; + + private RankProfilesConfig.Rankprofile.Fef findProfile(String name, RankProfilesConfig config) { + for (RankProfilesConfig.Rankprofile profile : config.rankprofile()) { + if (profile.name().equals(name)) + return profile.fef(); + } + throw new IllegalArgumentException("No profile named " + name); + } + // We don't have function file distribution so just return empty tensor constants private static class ToleratingMissingConstantFilesRankProfilesConfigImporter extends RankProfilesConfigImporter { |