use of com.yahoo.tensor.TensorAddress in project vespa by vespa-engine.
the class Join method partialCommonAddress.
private TensorAddress partialCommonAddress(Tensor.Cell cell, int[] indexMap) {
TensorAddress address = cell.getKey();
String[] labels = new String[indexMap.length];
for (int i = 0; i < labels.length; ++i) {
labels[i] = address.label(indexMap[i]);
}
return TensorAddress.of(labels);
}
use of com.yahoo.tensor.TensorAddress in project vespa by vespa-engine.
the class Join method mappedHashJoin.
private Tensor mappedHashJoin(Tensor a, Tensor b, TensorType joinedType) {
TensorType commonDimensionType = commonDimensions(a, b);
if (commonDimensionType.dimensions().isEmpty()) {
// fallback
return mappedGeneralJoin(a, b, joinedType);
}
boolean swapTensors = a.size() > b.size();
if (swapTensors) {
Tensor temp = a;
a = b;
b = temp;
}
// Map dimension indexes to common and joined type
int[] aIndexesInCommon = mapIndexes(commonDimensionType, a.type());
int[] bIndexesInCommon = mapIndexes(commonDimensionType, b.type());
int[] aIndexesInJoined = mapIndexes(a.type(), joinedType);
int[] bIndexesInJoined = mapIndexes(b.type(), joinedType);
// Iterate once through the smaller tensor and construct a hash map for common dimensions
Map<TensorAddress, List<Tensor.Cell>> aCellsByCommonAddress = new HashMap<>();
for (Iterator<Tensor.Cell> cellIterator = a.cellIterator(); cellIterator.hasNext(); ) {
Tensor.Cell aCell = cellIterator.next();
TensorAddress partialCommonAddress = partialCommonAddress(aCell, aIndexesInCommon);
aCellsByCommonAddress.putIfAbsent(partialCommonAddress, new ArrayList<>());
aCellsByCommonAddress.get(partialCommonAddress).add(aCell);
}
// Iterate once through the larger tensor and use the hash map to find joinable cells
Tensor.Builder builder = Tensor.Builder.of(joinedType);
for (Iterator<Tensor.Cell> cellIterator = b.cellIterator(); cellIterator.hasNext(); ) {
Tensor.Cell bCell = cellIterator.next();
TensorAddress partialCommonAddress = partialCommonAddress(bCell, bIndexesInCommon);
for (Tensor.Cell aCell : aCellsByCommonAddress.getOrDefault(partialCommonAddress, Collections.emptyList())) {
TensorAddress combinedAddress = joinAddresses(aCell.getKey(), aIndexesInJoined, bCell.getKey(), bIndexesInJoined, joinedType);
// not combinable
if (combinedAddress == null)
continue;
double combinedValue = swapTensors ? combinator.applyAsDouble(bCell.getValue(), aCell.getValue()) : combinator.applyAsDouble(aCell.getValue(), bCell.getValue());
builder.cell(combinedAddress, combinedValue);
}
}
return builder.build();
}
use of com.yahoo.tensor.TensorAddress in project vespa by vespa-engine.
the class Reduce method evaluate.
@Override
public <NAMETYPE extends TypeContext.Name> Tensor evaluate(EvaluationContext<NAMETYPE> context) {
Tensor argument = this.argument.evaluate(context);
if (!dimensions.isEmpty() && !argument.type().dimensionNames().containsAll(dimensions))
throw new IllegalArgumentException("Cannot reduce " + argument + " over dimensions " + dimensions + ": Not all those dimensions are present in this tensor");
// Special case: Reduce all
if (dimensions.isEmpty() || dimensions.size() == argument.type().dimensions().size())
if (argument.type().dimensions().size() == 1 && argument instanceof IndexedTensor)
return reduceIndexedVector((IndexedTensor) argument);
else
return reduceAllGeneral(argument);
TensorType reducedType = type(argument.type());
// Reduce cells
Map<TensorAddress, ValueAggregator> aggregatingCells = new HashMap<>();
for (Iterator<Tensor.Cell> i = argument.cellIterator(); i.hasNext(); ) {
Map.Entry<TensorAddress, Double> cell = i.next();
TensorAddress reducedAddress = reduceDimensions(cell.getKey(), argument.type(), reducedType);
aggregatingCells.putIfAbsent(reducedAddress, ValueAggregator.ofType(aggregator));
aggregatingCells.get(reducedAddress).aggregate(cell.getValue());
}
Tensor.Builder reducedBuilder = Tensor.Builder.of(reducedType);
for (Map.Entry<TensorAddress, ValueAggregator> aggregatingCell : aggregatingCells.entrySet()) reducedBuilder.cell(aggregatingCell.getKey(), aggregatingCell.getValue().aggregatedValue());
return reducedBuilder.build();
}
use of com.yahoo.tensor.TensorAddress in project vespa by vespa-engine.
the class Rename method evaluate.
@Override
public <NAMETYPE extends TypeContext.Name> Tensor evaluate(EvaluationContext<NAMETYPE> context) {
Tensor tensor = argument.evaluate(context);
TensorType renamedType = type(tensor.type());
// an array which lists the index of each label in the renamed type
int[] toIndexes = new int[tensor.type().dimensions().size()];
for (int i = 0; i < tensor.type().dimensions().size(); i++) {
String dimensionName = tensor.type().dimensions().get(i).name();
String newDimensionName = fromToMap.getOrDefault(dimensionName, dimensionName);
toIndexes[i] = renamedType.indexOfDimension(newDimensionName).get();
}
Tensor.Builder builder = Tensor.Builder.of(renamedType);
for (Iterator<Tensor.Cell> i = tensor.cellIterator(); i.hasNext(); ) {
Map.Entry<TensorAddress, Double> cell = i.next();
TensorAddress renamedAddress = rename(cell.getKey(), toIndexes);
builder.cell(renamedAddress, cell.getValue());
}
return builder.build();
}
Aggregations