Skip to content

Commit 2af062d

Browse files
committed
Remove DynamicReshape and DynamicBroadcastInDim ops
These operations are being moved to a separate PR to allow the Shape and shape inference changes to be merged independently.
1 parent 4b692f1 commit 2af062d

4 files changed

Lines changed: 80 additions & 280 deletions

File tree

internal/optypes/gen_optype_enumer.go

Lines changed: 80 additions & 88 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/optypes/optypes.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,10 @@ const (
102102
CollectivePermute
103103
Composite
104104
CustomCall
105-
DynamicBroadcastInDim
106105
DynamicConv
107106
DynamicGather
108107
DynamicIota
109108
DynamicPad
110-
DynamicReshape
111109
GetDimensionSize
112110
GetTupleElement
113111
Infeed

pkg/stablehlo/ops.go

Lines changed: 0 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,142 +1728,6 @@ func GetDimensionSize(operand *Value, dimension int) (*Value, error) {
17281728
return stmt.Outputs[0], nil
17291729
}
17301730

1731-
// DynamicReshape reshapes the operand to a shape specified by a 1D tensor,
1732-
// with caller-provided bounds for the output dimensions.
1733-
//
1734-
// This is the dynamic version of Reshape where the output shape is determined at runtime.
1735-
// The total number of elements must remain the same.
1736-
//
1737-
// Parameters:
1738-
// - operand: the tensor to reshape.
1739-
// - outputShape: a 1D tensor of i32 or i64 values specifying the target shape dimensions.
1740-
// - bounds: dimension bounds for the output shape. Must have length equal to output rank.
1741-
// Use the actual dimension value for known dimensions, or an upper bound for dynamic ones.
1742-
//
1743-
// XLA requires bounded dynamic dimensions, so bounds must be provided. The caller should
1744-
// determine these bounds before generating StableHLO (e.g., from model configuration or
1745-
// by analyzing the computation graph).
1746-
func DynamicReshape(operand *Value, outputShape *Value, bounds []int) (*Value, error) {
1747-
op := optypes.DynamicReshape
1748-
fn := operand.fn
1749-
if fn.Returned {
1750-
return nil, errors.Errorf("cannot add operation %s after returning, in function %q",
1751-
op, fn.Name)
1752-
}
1753-
if outputShape.fn != fn {
1754-
return nil, errors.Errorf("cannot add operation %s to function %q, because operand and outputShape are from different functions",
1755-
op, fn.Name)
1756-
}
1757-
1758-
// Validate outputShape is 1D tensor of integer type
1759-
if outputShape.shape.Rank() != 1 {
1760-
return nil, errors.Errorf("outputShape must be a 1D tensor, got rank %d",
1761-
outputShape.shape.Rank())
1762-
}
1763-
if !outputShape.shape.DType.IsInt() {
1764-
return nil, errors.Errorf("outputShape must be integer type, got %s",
1765-
outputShape.shape.DType)
1766-
}
1767-
1768-
// Get output rank from the shape tensor
1769-
outputRank := outputShape.shape.Dimensions[0]
1770-
if outputRank < 0 {
1771-
return nil, errors.Errorf("outputShape tensor has dynamic size, cannot determine output rank")
1772-
}
1773-
1774-
// Validate bounds length
1775-
if len(bounds) != outputRank {
1776-
return nil, errors.Errorf("bounds length (%d) must match output rank (%d)",
1777-
len(bounds), outputRank)
1778-
}
1779-
1780-
// Create output shape with dynamic dimensions and caller-provided bounds
1781-
resultShape := operand.shape.Clone()
1782-
resultShape.Dimensions = make([]int, outputRank)
1783-
resultShape.DimensionBounds = make([]int, outputRank)
1784-
for i := 0; i < outputRank; i++ {
1785-
resultShape.Dimensions[i] = shapes.DimUnknown // Dynamic
1786-
resultShape.DimensionBounds[i] = bounds[i]
1787-
}
1788-
// dynamic_reshape requires bounded output in XLA, so we must encode bounds
1789-
resultShape.EncodeBounds = true
1790-
1791-
stmt := fn.addOp(op, resultShape, operand, outputShape)
1792-
return stmt.Outputs[0], nil
1793-
}
1794-
1795-
// DynamicBroadcastInDim broadcasts the operand to a shape specified by a 1D tensor,
1796-
// with caller-provided bounds for the output dimensions.
1797-
//
1798-
// This is the dynamic version of BroadcastInDim where the output shape is determined at runtime.
1799-
//
1800-
// Parameters:
1801-
// - operand: the tensor to broadcast.
1802-
// - outputDimensions: a 1D tensor of i32 or i64 values specifying the target shape.
1803-
// - broadcastDimensions: maps operand axes to output axes (like BroadcastInDim).
1804-
// - bounds: dimension bounds for the output shape. Must have length equal to output rank.
1805-
//
1806-
// XLA requires bounded dynamic dimensions, so bounds must be provided. The caller should
1807-
// determine these bounds before generating StableHLO (e.g., from model configuration or
1808-
// by analyzing the computation graph).
1809-
func DynamicBroadcastInDim(operand *Value, outputDimensions *Value, broadcastDimensions []int, bounds []int) (*Value, error) {
1810-
op := optypes.DynamicBroadcastInDim
1811-
fn := operand.fn
1812-
if fn.Returned {
1813-
return nil, errors.Errorf("cannot add operation %s after returning, in function %q",
1814-
op, fn.Name)
1815-
}
1816-
if outputDimensions.fn != fn {
1817-
return nil, errors.Errorf("cannot add operation %s to function %q, because operand and outputDimensions are from different functions",
1818-
op, fn.Name)
1819-
}
1820-
1821-
// Validate outputDimensions is 1D tensor of integer type
1822-
if outputDimensions.shape.Rank() != 1 {
1823-
return nil, errors.Errorf("outputDimensions must be a 1D tensor, got rank %d",
1824-
outputDimensions.shape.Rank())
1825-
}
1826-
if !outputDimensions.shape.DType.IsInt() {
1827-
return nil, errors.Errorf("outputDimensions must be integer type, got %s",
1828-
outputDimensions.shape.DType)
1829-
}
1830-
1831-
// Validate broadcastDimensions length matches operand rank
1832-
if len(broadcastDimensions) != operand.shape.Rank() {
1833-
return nil, errors.Errorf("broadcastDimensions length (%d) must match operand rank (%d)",
1834-
len(broadcastDimensions), operand.shape.Rank())
1835-
}
1836-
1837-
// Get output rank from the dimensions tensor
1838-
outputRank := outputDimensions.shape.Dimensions[0]
1839-
if outputRank < 0 {
1840-
return nil, errors.Errorf("outputDimensions tensor has dynamic size, cannot determine output rank")
1841-
}
1842-
1843-
// Validate bounds length
1844-
if len(bounds) != outputRank {
1845-
return nil, errors.Errorf("bounds length (%d) must match output rank (%d)",
1846-
len(bounds), outputRank)
1847-
}
1848-
1849-
// Create output shape with dynamic dimensions and caller-provided bounds
1850-
outputShape := operand.shape.Clone()
1851-
outputShape.Dimensions = make([]int, outputRank)
1852-
outputShape.DimensionBounds = make([]int, outputRank)
1853-
for i := 0; i < outputRank; i++ {
1854-
outputShape.Dimensions[i] = shapes.DimUnknown // Dynamic
1855-
outputShape.DimensionBounds[i] = bounds[i]
1856-
}
1857-
// dynamic_broadcast_in_dim requires bounded output in XLA, so we must encode bounds
1858-
outputShape.EncodeBounds = true
1859-
1860-
stmt := fn.addOp(op, outputShape, operand, outputDimensions)
1861-
stmt.Attributes = map[string]any{
1862-
"broadcast_dimensions": intSliceToArrayI64StableHLO(broadcastDimensions),
1863-
}
1864-
return stmt.Outputs[0], nil
1865-
}
1866-
18671731
// While executes body repeatedly while condition returns true.
18681732
//
18691733
// The While operation implements a loop that continues executing the body function

0 commit comments

Comments
 (0)