Skip to content

Commit 78fea43

Browse files
authored
Merge pull request #33 from gomlx/dotgeneral-api-fix
Fix DotGeneral output dtype and update compute dependency
2 parents 36ac40e + 6c3ecdd commit 78fea43

4 files changed

Lines changed: 34 additions & 11 deletions

File tree

compute/xla/function.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ func (f *Function) Parent() compute.Function {
4343
return f.parent
4444
}
4545

46+
// Builder returns the builder for this function.
47+
func (f *Function) Builder() compute.Builder {
48+
return f.builder
49+
}
50+
51+
// Shape returns the shape of a value in the function.
52+
func (f *Function) Shape(v compute.Value) (shapes.Shape, error) {
53+
var s shapes.Shape
54+
n, ok := v.(*Node)
55+
if !ok {
56+
return s, errors.Errorf("value is not a Node for a XLA backend, instead got a %T", v)
57+
}
58+
if err := f.CheckValid(); err != nil {
59+
return s, err
60+
}
61+
return n.shape, nil
62+
}
63+
4664
// Closure creates a new closure function, within this function.
4765
func (f *Function) Closure() (compute.Function, error) {
4866
if err := f.CheckValid(); err != nil {

compute/xla/ops_dotgeneral.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import (
2323
// - Contracted (contracting axes), where the output does multiply the values and reduce sum
2424
// those dimensions.
2525
//
26-
// It follows that the resulting dimension number starts with the batch dimension, then the 'lhs'
27-
// non-contracting/non-batch dimension, and finally the 'rhs' non-contracting/non-batch dimension.
26+
// The resulting shape is [batchIndices..., <lhs cross indices...>, <rhs cross indices...>], the
27+
// indices come in the order they were provided. The output dtype is by default the same as
28+
// the input, except if configured otherwise in config.OutputDType.
29+
//
2830
// It provides the basic means of implementing Einsum.
2931
//
3032
// The XLA implementation only supports accumulation in F32 (if different than the input dtypes).
@@ -39,11 +41,14 @@ func (f *Function) DotGeneral(
3941
}
4042
lhsNode := nodes[0]
4143
rhsNode := nodes[1]
42-
dtype := lhsNode.shape.DType
43-
accumulationDType := dtype
44+
inputDType := lhsNode.shape.DType
45+
accumulationDType := inputDType
4446
if config.AccumulatorDType != dtypes.InvalidDType {
4547
accumulationDType = config.AccumulatorDType
4648
}
49+
if config.OutputDType == dtypes.InvalidDType {
50+
config.OutputDType = inputDType
51+
}
4752

4853
// Introduce a dependency to create a schedule barrier to prevent the compiler to try
4954
// to start processing weights too early (like converting them to the accumulationDType).
@@ -55,14 +60,14 @@ func (f *Function) DotGeneral(
5560
// The CUDA backend does not seem to need this (likely they do something like that internally).
5661
isCPU := f.builder.backend.plugin.IsCPU()
5762
lhsReady, rhsReady := lhsNode, rhsNode
58-
if accumulationDType != dtype && isCPU {
63+
if accumulationDType != inputDType && isCPU {
5964
lhsReady, rhsReady, err = dotGeneralAddDependency(f, lhsReady, rhsReady)
6065
if err != nil {
6166
return nil, err
6267
}
6368
}
6469

65-
if accumulationDType != dtype {
70+
if accumulationDType != inputDType {
6671
if accumulationDType != dtypes.F32 {
6772
// XLA only supports accumulation in F32 (if different than the input dtypes).
6873
// For other accumulation dtypes, we convert the inputs to the type.
@@ -76,7 +81,7 @@ func (f *Function) DotGeneral(
7681
return nil, errors.WithMessagef(err, "failed to convert rhs to accumulation dtype")
7782
}
7883
lhsReady, rhsReady = lhsReadyValue.(*Node), rhsReadyValue.(*Node)
79-
dtype = accumulationDType
84+
inputDType = accumulationDType
8085
}
8186
}
8287

@@ -89,7 +94,7 @@ func (f *Function) DotGeneral(
8994
//
9095
// So we make a simplification here: we only set the "dot_algorithm" is the plugin is not CUDA.
9196
useTF32 := accumulationDType == dtypes.F32 && f.builder.backend.DotGeneralUseTF32
92-
if useTF32 || accumulationDType != dtype {
97+
if useTF32 || accumulationDType != inputDType {
9398
isCUDA := f.builder.backend.plugin.IsCUDA()
9499
if isCUDA {
95100
// Set "precision_config"

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.26
44

55
require (
66
github.com/gofrs/flock v0.13.0
7-
github.com/gomlx/compute v0.0.0-20260502161841-2635c422f98b
7+
github.com/gomlx/compute v0.0.0-20260505135155-9f8cc2c04803
88
github.com/janpfeifer/go-benchmarks v0.1.1
99
github.com/pkg/errors v0.9.1
1010
github.com/stretchr/testify v1.11.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
77
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
88
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
99
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
10-
github.com/gomlx/compute v0.0.0-20260502161841-2635c422f98b h1:eI6OSkBrZlBIJFWhnMQQvDiYYxmhKEOoPE48F2xj89k=
11-
github.com/gomlx/compute v0.0.0-20260502161841-2635c422f98b/go.mod h1:MDTT683Wvq7IMSKXDGLvV3Co7HDpx/Xsgp2RbF5lhNM=
10+
github.com/gomlx/compute v0.0.0-20260505135155-9f8cc2c04803 h1:9wh+H/ui5eD4ah4tA7vRTN/FiGljh8tOelKjpm1gbV4=
11+
github.com/gomlx/compute v0.0.0-20260505135155-9f8cc2c04803/go.mod h1:MDTT683Wvq7IMSKXDGLvV3Co7HDpx/Xsgp2RbF5lhNM=
1212
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
1313
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
1414
github.com/janpfeifer/go-benchmarks v0.1.1 h1:gLLy07/JrOKSnMWeUxSnjTdhkglgmrNR2IBDnR4kRqw=

0 commit comments

Comments
 (0)