use of com.yahoo.searchlib.rankingexpression.integration.tensorflow.importer.OrderedTensorType in project vespa by vespa-engine.
the class OrderedTensorTypeTestCase method testToFromSpec.
@Test
public void testToFromSpec() {
String spec = "tensor(b[],c{},a[3])";
OrderedTensorType type = OrderedTensorType.fromSpec(spec);
assertEquals(spec, type.toString());
assertEquals("tensor(a[3],b[],c{})", type.type().toString());
}
use of com.yahoo.searchlib.rankingexpression.integration.tensorflow.importer.OrderedTensorType in project vespa by vespa-engine.
the class TensorFlowImporter method importInputExpression.
private static void importInputExpression(TensorFlowModel model, TensorFlowOperation operation) {
if (operation.isInput() && isSignatureInput(model, operation)) {
// All inputs must have dimensions with standard naming convention: d0, d1, ...
OrderedTensorType standardNamingConvention = OrderedTensorType.fromTensorFlowType(operation.node());
model.argument(operation.node().getName(), standardNamingConvention.type());
model.requiredMacro(operation.vespaName(), standardNamingConvention.type());
}
}
use of com.yahoo.searchlib.rankingexpression.integration.tensorflow.importer.OrderedTensorType in project vespa by vespa-engine.
the class ExpandDims method lazyGetType.
@Override
protected OrderedTensorType lazyGetType() {
if (!allInputTypesPresent(2)) {
return null;
}
TensorFlowOperation axisOperation = inputs().get(1);
if (!axisOperation.getConstantValue().isPresent()) {
throw new IllegalArgumentException("ExpandDims in " + node.getName() + ": " + "axis must be a constant.");
}
Tensor axis = axisOperation.getConstantValue().get().asTensor();
if (axis.type().rank() != 0) {
throw new IllegalArgumentException("ExpandDims in " + node.getName() + ": " + "axis argument must be a scalar.");
}
OrderedTensorType inputType = inputs.get(0).type().get();
int dimensionToInsert = (int) axis.asDouble();
if (dimensionToInsert < 0) {
dimensionToInsert = inputType.dimensions().size() - dimensionToInsert;
}
OrderedTensorType.Builder typeBuilder = new OrderedTensorType.Builder(node);
expandDimensions = new ArrayList<>();
int dimensionIndex = 0;
for (TensorType.Dimension dimension : inputType.dimensions()) {
if (dimensionIndex == dimensionToInsert) {
String name = String.format("%s_%d", vespaName(), dimensionIndex);
expandDimensions.add(name);
typeBuilder.add(TensorType.Dimension.indexed(name, 1L));
}
typeBuilder.add(dimension);
dimensionIndex++;
}
return typeBuilder.build();
}
use of com.yahoo.searchlib.rankingexpression.integration.tensorflow.importer.OrderedTensorType in project vespa by vespa-engine.
the class Join method addDimensionNameConstraints.
@Override
public void addDimensionNameConstraints(DimensionRenamer renamer) {
if (!allInputTypesPresent(2)) {
return;
}
OrderedTensorType a = largestInput().type().get();
OrderedTensorType b = smallestInput().type().get();
int sizeDifference = a.rank() - b.rank();
for (int i = 0; i < b.rank(); ++i) {
String bDim = b.dimensions().get(i).name();
String aDim = a.dimensions().get(i + sizeDifference).name();
renamer.addConstraint(aDim, bDim, DimensionRenamer::equals, this);
}
}
use of com.yahoo.searchlib.rankingexpression.integration.tensorflow.importer.OrderedTensorType in project vespa by vespa-engine.
the class Join method lazyGetType.
@Override
protected OrderedTensorType lazyGetType() {
if (!allInputTypesPresent(2)) {
return null;
}
OrderedTensorType a = largestInput().type().get();
OrderedTensorType b = smallestInput().type().get();
// Well now we have potentially entered the wonderful world of "broadcasting"
// https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
// In broadcasting, the size of each dimension is compared element-wise,
// starting with the trailing dimensions and working forward. A special
// case occurs when the size of one dimension is 1, while the other is not.
// Then the dimension with size 1 is "stretched" to be of compatible size.
//
// An example:
//
// Tensor A: d0[5], d1[1], d2[3], d3[1]
// Tensor B: d1[4], d2[1], d3[2]
//
// In TensorFlow and using the above rules of broadcasting, the resulting
// type is:
// d0[5], d1[4], d2[3], d2[2]
//
// However, in Vespa's tensor logic, the join of the two above tensors would
// result in a tensor of type:
// d0[5], d1[1], d2[1], d3[1]
//
// By reducing the dimensions of size 1 in each tensor before joining,
// we get equal results as in TensorFlow.
OrderedTensorType.Builder builder = new OrderedTensorType.Builder(node);
int sizeDifference = a.rank() - b.rank();
for (int i = 0; i < a.rank(); ++i) {
TensorType.Dimension aDim = a.dimensions().get(i);
long size = aDim.size().orElse(-1L);
if (i - sizeDifference >= 0) {
TensorType.Dimension bDim = b.dimensions().get(i - sizeDifference);
size = Math.max(size, bDim.size().orElse(-1L));
}
if (aDim.type() == TensorType.Dimension.Type.indexedBound) {
builder.add(TensorType.Dimension.indexed(aDim.name(), size));
} else if (aDim.type() == TensorType.Dimension.Type.indexedUnbound) {
builder.add(TensorType.Dimension.indexed(aDim.name()));
} else if (aDim.type() == TensorType.Dimension.Type.mapped) {
builder.add(TensorType.Dimension.mapped(aDim.name()));
}
}
return builder.build();
}
Aggregations