run method
The value, given each of inputs' components in order.
Implementation
List<double> run(List<List<double>> slots) {
final r = _registers;
for (var i = 0; i < inputs.length; i++) {
final input = inputs[i];
final value = slots[i];
for (var lane = 0; lane < input.width; lane++) {
r[input.lane + lane] = value[lane];
}
}
for (var pc = 0; pc < code.length; pc += 8) {
final op = code[pc];
final width = code[pc + 1] & 0xFF;
final flags = code[pc + 1] >> 8;
final dst = code[pc + 2];
final a = code[pc + 3];
final b = code[pc + 4];
final c = code[pc + 5];
// How far each operand moves per lane: nought when its flag spreads
// one lane across the width.
final sa = flags & 1 != 0 ? 0 : 1;
final sb = flags & 2 != 0 ? 0 : 1;
final sc = flags & 4 != 0 ? 0 : 1;
switch (op) {
case ExpressionOp.loadConstant:
for (var i = 0; i < width; i++) {
r[dst + i] = constants[a + i];
}
case ExpressionOp.move:
for (var i = 0; i < width; i++) {
r[dst + i] = r[a + i];
}
case ExpressionOp.swizzle:
for (var i = 0; i < width; i++) {
r[dst + i] = r[a + ((b >> (2 * i)) & 3)];
}
case ExpressionOp.negate:
for (var i = 0; i < width; i++) {
r[dst + i] = -r[a + i];
}
case ExpressionOp.not:
r[dst] = r[a] != 0 ? 0 : 1;
// Each operator as `expressionOperatorAt` computes it, written out
// under its own opcode: no symbol is looked up and no string is
// compared per lane.
case ExpressionOp.add:
for (var i = 0; i < width; i++) {
r[dst + i] = r[a + i * sa] + r[b + i * sb];
}
case ExpressionOp.subtract:
for (var i = 0; i < width; i++) {
r[dst + i] = r[a + i * sa] - r[b + i * sb];
}
case ExpressionOp.multiply:
for (var i = 0; i < width; i++) {
r[dst + i] = r[a + i * sa] * r[b + i * sb];
}
case ExpressionOp.divide:
for (var i = 0; i < width; i++) {
r[dst + i] = r[a + i * sa] / r[b + i * sb];
}
case ExpressionOp.less:
r[dst] = r[a] < r[b] ? 1.0 : 0.0;
case ExpressionOp.lessEqual:
r[dst] = r[a] <= r[b] ? 1.0 : 0.0;
case ExpressionOp.greater:
r[dst] = r[a] > r[b] ? 1.0 : 0.0;
case ExpressionOp.greaterEqual:
r[dst] = r[a] >= r[b] ? 1.0 : 0.0;
case ExpressionOp.equal:
r[dst] = r[a] == r[b] ? 1.0 : 0.0;
case ExpressionOp.notEqual:
r[dst] = r[a] != r[b] ? 1.0 : 0.0;
case ExpressionOp.and:
r[dst] = r[a] != 0 && r[b] != 0 ? 1.0 : 0.0;
case ExpressionOp.or:
r[dst] = r[a] != 0 || r[b] != 0 ? 1.0 : 0.0;
case ExpressionOp.select:
for (var i = 0; i < width; i++) {
r[dst + i] = r[a] != 0 ? r[b + i] : r[c + i];
}
case ExpressionOp.dot:
var sum = 0.0;
for (var i = 0; i < width; i++) {
sum += r[a + i] * r[b + i];
}
r[dst] = sum;
case ExpressionOp.length:
var sum = 0.0;
for (var i = 0; i < width; i++) {
sum += r[a + i] * r[a + i];
}
r[dst] = math.sqrt(sum);
case ExpressionOp.normalize:
var sum = 0.0;
for (var i = 0; i < width; i++) {
sum += r[a + i] * r[a + i];
}
final length = math.sqrt(sum);
for (var i = 0; i < width; i++) {
r[dst + i] = length == 0 ? 0 : r[a + i] / length;
}
case ExpressionOp.mix:
for (var i = 0; i < width; i++) {
r[dst + i] = mixAt(r[a + i * sa], r[b + i * sb], r[c + i * sc]);
}
case ExpressionOp.clamp:
for (var i = 0; i < width; i++) {
r[dst + i] = clampAt(r[a + i * sa], r[b + i * sb], r[c + i * sc]);
}
case ExpressionOp.smoothstep:
for (var i = 0; i < width; i++) {
r[dst + i] = smoothstepAt(
r[a + i * sa],
r[b + i * sb],
r[c + i * sc],
);
}
case ExpressionOp.step:
for (var i = 0; i < width; i++) {
r[dst + i] = stepAt(r[a + i * sa], r[b + i * sb]);
}
case ExpressionOp.pow:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.pow(r[a + i * sa], r[b + i * sb]);
}
case ExpressionOp.min:
for (var i = 0; i < width; i++) {
r[dst + i] = minAt(r[a + i * sa], r[b + i * sb]);
}
case ExpressionOp.max:
for (var i = 0; i < width; i++) {
r[dst + i] = maxAt(r[a + i * sa], r[b + i * sb]);
}
case ExpressionOp.atan2:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.atan2(r[a + i * sa], r[b + i * sb]);
}
case ExpressionOp.abs:
for (var i = 0; i < width; i++) {
r[dst + i] = absAt(r[a + i]);
}
case ExpressionOp.sqrt:
for (var i = 0; i < width; i++) {
r[dst + i] = math.sqrt(r[a + i]);
}
case ExpressionOp.floor:
for (var i = 0; i < width; i++) {
r[dst + i] = floorAt(r[a + i]);
}
case ExpressionOp.fract:
for (var i = 0; i < width; i++) {
r[dst + i] = fractAt(r[a + i]);
}
case ExpressionOp.sin:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.sin(r[a + i]);
}
case ExpressionOp.cos:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.cos(r[a + i]);
}
case ExpressionOp.tan:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.tan(r[a + i]);
}
case ExpressionOp.asin:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.asin(r[a + i]);
}
case ExpressionOp.acos:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.acos(r[a + i]);
}
case ExpressionOp.atan:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.atan(r[a + i]);
}
case ExpressionOp.exp:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.exp(r[a + i]);
}
case ExpressionOp.log:
for (var i = 0; i < width; i++) {
r[dst + i] = Portable.log(r[a + i]);
}
case ExpressionOp.sign:
for (var i = 0; i < width; i++) {
r[dst + i] = signAt(r[a + i]);
}
default:
throw StateError('no opcode $op');
}
}
return <double>[for (var i = 0; i < resultWidth; i++) r[resultLane + i]];
}