public NodeCompiler(RegisterState registers) { _registers = registers; _nodeGrouper = new NodeGrouper(registers); _constantCompiler = new ConstantCompiler(_nodeGrouper); _matrixMultiplicationCompiler = new MatrixMultiplicationCompiler(this); }
public void ReduceTree(NodeGrouper nodeGrouper) { var templateMatcher = new TemplateMatcher(nodeGrouper); Roots = Roots.ToDictionary(r => r.Key, r => templateMatcher.Reduce(r.Value)); NoOutputInstructions = NoOutputInstructions.ToDictionary(r => r.Key, r => templateMatcher.Reduce(r.Value)); }
public HlslTreeNode[] TryGetContext(IList <HlslTreeNode> components) { var firstComponent = components[0]; if (!(firstComponent is DivisionOperation firstDivision)) { return(null); } var firstLengthContext = _nodeGrouper.LengthGrouper.TryGetLengthContext(firstDivision.Divisor); if (firstLengthContext == null) { return(null); } int dimension = firstLengthContext.Length; if (firstLengthContext.Any(c => NodeGrouper.AreNodesEquivalent(firstDivision.Dividend, c)) == false) { return(null); } for (int i = 1; i < dimension; i++) { if (i >= components.Count) { return(null); } var nextComponent = components[i]; if (!(nextComponent is DivisionOperation nextDivision)) { return(null); } if (NodeGrouper.AreNodesEquivalent(nextDivision.Divisor, firstDivision.Divisor) == false) { return(null); } if (firstLengthContext.Any(c => NodeGrouper.AreNodesEquivalent(nextDivision.Dividend, c)) == false) { return(null); } } return(components .Take(dimension) .Cast <DivisionOperation>() .Select(c => c.Dividend) .ToArray()); }
public string Compile(ConstantNode[] group) { ConstantNode first = group[0]; int count = group.Length; if (count == 1) { return(CompileConstant(first)); } if (group.All(c => NodeGrouper.AreNodesEquivalent(c, first))) { return(CompileConstant(first)); } string components = string.Join(", ", group.Select(CompileConstant)); return($"float{count}({components})"); }
public HlslTreeNode[] TryGetContext(IList <HlslTreeNode> components) { var firstComponent = components[0]; if (!(firstComponent is DivisionOperation firstDivision) || !(firstDivision.Divisor is LengthOperation firstLength)) { return(null); } if (!firstLength.X.Inputs.Any(c => NodeGrouper.AreNodesEquivalent(firstDivision.Dividend, c))) { return(null); } int normalizeComponentCount = 1; for (int i = 1; i < components.Count; i++) { if (IsNormalizeGroupComponent(components[i], firstDivision, firstLength)) { normalizeComponentCount++; } else { break; } } if (normalizeComponentCount < 2) { return(null); } return(components .Take(normalizeComponentCount) .Cast <DivisionOperation>() .Select(c => c.Dividend) .ToArray()); }
public NormalizeGrouper(NodeGrouper nodeGrouper) { _nodeGrouper = nodeGrouper; }
private static bool IsNormalizeGroupComponent(HlslTreeNode nextComponent, DivisionOperation firstDivision, LengthOperation firstLength) { return(nextComponent is DivisionOperation nextDivision && NodeGrouper.AreNodesEquivalent(nextDivision.Divisor, firstDivision.Divisor) && firstLength.X.Inputs.Any(c => NodeGrouper.AreNodesEquivalent(nextDivision.Dividend, c))); }
public MatrixMultiplicationContext TryGetMultiplicationGroup(IList <HlslTreeNode> components) { const bool allowMatrix = true; var first = components[0]; var firstDotProductNode = _nodeGrouper.DotProductGrouper.TryGetDotProductGroup(first, allowMatrix); if (firstDotProductNode == null) { return(null); } int dimension = firstDotProductNode.Dimension; if (components.Count < dimension) { return(null); } HlslTreeNode[] firstMatrixRow = TryGetMatrixRow(firstDotProductNode); if (firstMatrixRow == null) { return(null); } HlslTreeNode[] vector = firstDotProductNode.Value1 == firstMatrixRow ? firstDotProductNode.Value2 : firstDotProductNode.Value1; var matrixRows = new HlslTreeNode[dimension][]; matrixRows[0] = firstMatrixRow; for (int i = 1; i < dimension; i++) { var next = components[i]; var dotProductNode = _nodeGrouper.DotProductGrouper.TryGetDotProductGroup(next, dimension, allowMatrix); if (dotProductNode == null) { return(null); } HlslTreeNode[] matrixRow = TryGetMatrixRow(dotProductNode); if (matrixRow == null) { return(null); } matrixRows[i] = matrixRow; HlslTreeNode[] nextVector = dotProductNode.Value1 == matrixRow ? dotProductNode.Value2 : dotProductNode.Value1; if (NodeGrouper.IsVectorEquivalent(vector, nextVector) == false) { return(null); } } ConstantDeclaration matrix = TryGetMatrixDeclaration(matrixRows); if (matrix == null) { return(null); } bool matrixByVector = firstMatrixRow .Cast <RegisterInputNode>() .All(row => row.ComponentIndex == 0); SwizzleVector(vector, firstMatrixRow, matrixByVector); return(new MatrixMultiplicationContext(vector, matrix, matrixByVector)); }
public MatrixMultiplicationGrouper(NodeGrouper nodeGrouper, RegisterState registers) { _nodeGrouper = nodeGrouper; _registers = registers; }
public ConstantCompiler(NodeGrouper nodeGrouper) { _nodeGrouper = nodeGrouper; }
// Vector by matrix multiplication has a pattern of: // float2(dot(m_row1, v), dot(m_row2, v)) // float3(dot(m_row1, v), dot(m_row2, v), dot(m_row3, v)) // float4(dot(m_row1, v), dot(m_row2, v), dot(m_row3, v), dot(m_row4, v)) public MatrixMultiplicationContext TryGetMultiplicationGroup(IList <HlslTreeNode> components) { const bool allowMatrix = true; if (!(components[0] is DotProductOperation firstDot)) { return(null); } int dimension = firstDot.X.Length; if (components.Count < dimension) { return(null); } GroupNode firstMatrixRow = TryGetMatrixRow(firstDot, firstDot, 0); if (firstMatrixRow == null) { return(null); } GroupNode vector = firstDot.X == firstMatrixRow ? firstDot.Y : firstDot.X; var matrixRows = new List <GroupNode>(); matrixRows.Add(firstMatrixRow); for (int i = 1; i < components.Count; i++) { if (!(components[i] is DotProductOperation nextDot)) { break; } GroupNode matrixRow = TryGetMatrixRow(nextDot, firstDot, i); if (matrixRow == null) { break; } GroupNode nextVector = nextDot.X == matrixRow ? nextDot.Y : nextDot.X; if (!NodeGrouper.AreNodesEquivalent(vector, nextVector)) { break; } matrixRows.Add(matrixRow); } if (matrixRows.Count < 2) { return(null); } ConstantDeclaration matrix = TryGetMatrixDeclaration(matrixRows); if (matrix == null) { return(null); } bool matrixByVector = firstMatrixRow.Inputs .Cast <RegisterInputNode>() .All(row => row.ComponentIndex == 0); vector = SwizzleVector(vector, firstMatrixRow, matrixByVector); return(new MatrixMultiplicationContext(vector, matrix, matrixByVector, matrixRows.Count)); }
public DotProductGrouper(NodeGrouper nodeGrouper) { _nodeGrouper = nodeGrouper; }