Skip to content

Commit 44f8bce

Browse files
Katharine Hyattclaude
andcommitted
Get the hipTENSOR tests passing
The plan is the main fix: unlike cuTENSOR, hipTENSOR 2.2 does not copy the objects a plan is built from, it keeps pointers to the operation descriptor, the plan preference, the tensor descriptors and the mode arrays and dereferences them on every execution. Destroying or garbage collecting any of them gave anything from a NOT_SUPPORTED to a segfault, so the plan now owns them all and releases them, in order, when it is freed itself. Work around two more hipTENSOR quirks: - its elementwise and reduction kernels ignore the mode labels and walk each tensor in the order its modes were declared, silently producing garbage once those orders differ. Permuting the lengths and strides in each operand's descriptor puts them all in the output's mode order, which costs nothing and makes arbitrary mode orders work. - it has the two binary operators of an elementwise trinary operation the wrong way round, so swap them to get the documented semantics. Complex operands need a complex compute descriptor (a real one fails plan creation with EXECUTION_FAILED), and the compute type tables are trimmed to the combinations the library actually implements, with an error message that lists them instead of a bare KeyError. On the test side, contractions.jl never imported hipTENSOR and called a compute descriptor conversion that does not exist, the type lists are cut down to the supported combinations, and the sub-tests that were commented out are restored. Two limitations we cannot work around are recorded there: hipTENSOR silently ignores OP_CONJ on a contraction's inputs (@test_broken, so we notice when that is fixed), and it rounds the elementwise α/β/γ scalars to single precision even for a double precision compute descriptor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent a238ec2 commit 44f8bce

10 files changed

Lines changed: 341 additions & 296 deletions

File tree

src/tensor/hipTENSOR.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
module hipTENSOR
22

3-
using AMDGPU
43
using AMDGPU
54
using AMDGPU: @gcsafe_ccall, @checked, @enum_without_prefix, @debug_ccall
65
using AMDGPU: Mem
6+
7+
using BFloat16s: BFloat16
78
import AMDGPU: libhiptensor, HandleCache, HIP, library_state
89
import AMDGPU.Mem: alloc_or_retry!
910
import .HIP: HIPContext, HIPStream, hipStream_t

src/tensor/libhiptensor.jl

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ end
3333
end
3434

3535
@inline function check(f)
36-
retry_if(res) = res in (HIPTENSOR_STATUS_NOT_INITIALIZED,
37-
HIPTENSOR_STATUS_ALLOC_FAILED,
38-
HIPTENSOR_STATUS_INTERNAL_ERROR)
36+
# only an allocation failure is worth retrying after reclaiming memory; the other
37+
# statuses are permanent and should be reported to the caller as-is
38+
retry_if(res) = res == HIPTENSOR_STATUS_ALLOC_FAILED
3939
res = retry_reclaim(f, retry_if)
4040

4141
if res != HIPTENSOR_STATUS_SUCCESS
@@ -121,9 +121,9 @@ const hiptensorTensorDescriptor_t = Ptr{hiptensorTensorDescriptor}
121121
HIPTENSOR_C_64U = 27
122122
end
123123

124-
function hiptensorCreateTensorDescriptor(handle, desc, numModes, lens, strides, dataType,
124+
@checked function hiptensorCreateTensorDescriptor(handle, desc, numModes, lens, strides, dataType,
125125
alignmentRequirement)
126-
@debug_ccall libhiptensor.hiptensorCreateTensorDescriptor(handle::hiptensorHandle_t,
126+
@ccall libhiptensor.hiptensorCreateTensorDescriptor(handle::hiptensorHandle_t,
127127
desc::Ptr{hiptensorTensorDescriptor_t},
128128
numModes::UInt32, lens::Ptr{Int64},
129129
strides::Ptr{Int64},
@@ -225,8 +225,8 @@ end
225225
sizeInBytes::Csize_t)::hiptensorStatus_t
226226
end
227227

228-
function hiptensorOperationDescriptorGetAttribute(handle, desc, attr, buf, sizeInBytes)
229-
@debug_ccall libhiptensor.hiptensorOperationDescriptorGetAttribute(handle::hiptensorHandle_t,
228+
@checked function hiptensorOperationDescriptorGetAttribute(handle, desc, attr, buf, sizeInBytes)
229+
@ccall libhiptensor.hiptensorOperationDescriptorGetAttribute(handle::hiptensorHandle_t,
230230
desc::hiptensorOperationDescriptor_t,
231231
attr::hiptensorOperationDescriptorAttribute_t,
232232
buf::Ptr{Cvoid},
@@ -284,8 +284,8 @@ const hiptensorPlan_t = Ptr{hiptensorPlan}
284284
HIPTENSOR_PLAN_REQUIRED_WORKSPACE = 0
285285
end
286286

287-
function hiptensorPlanGetAttribute(handle, plan, attr, buf, sizeInBytes)
288-
@debug_ccall libhiptensor.hiptensorPlanGetAttribute(handle::hiptensorHandle_t,
287+
@checked function hiptensorPlanGetAttribute(handle, plan, attr, buf, sizeInBytes)
288+
@ccall libhiptensor.hiptensorPlanGetAttribute(handle::hiptensorHandle_t,
289289
plan::hiptensorPlan_t,
290290
attr::hiptensorPlanAttribute_t,
291291
buf::Ptr{Cvoid},
@@ -319,8 +319,8 @@ end
319319
descCompute::hiptensorComputeDescriptor_t)::hiptensorStatus_t
320320
end
321321

322-
function hiptensorCreatePlan(handle, plan, desc, pref, workspaceSizeLimit)
323-
@debug_ccall libhiptensor.hiptensorCreatePlan(handle::hiptensorHandle_t,
322+
@checked function hiptensorCreatePlan(handle, plan, desc, pref, workspaceSizeLimit)
323+
@ccall libhiptensor.hiptensorCreatePlan(handle::hiptensorHandle_t,
324324
plan::Ptr{hiptensorPlan_t},
325325
desc::hiptensorOperationDescriptor_t,
326326
pref::hiptensorPlanPreference_t,
@@ -337,13 +337,13 @@ end
337337
alpha::Ptr{Cvoid}, A::Ptr{Cvoid}, B::Ptr{Cvoid},
338338
beta::Ptr{Cvoid}, C::Ptr{Cvoid}, D::Ptr{Cvoid},
339339
workspace::Ptr{Cvoid}, workspaceSize::UInt64,
340-
stream::Cint)::hiptensorStatus_t
340+
stream::hipStream_t)::hiptensorStatus_t
341341
end
342342

343343
@checked function hiptensorPermute(handle, plan, alpha, A, B, stream)
344344
@ccall libhiptensor.hiptensorPermute(handle::hiptensorHandle_t, plan::hiptensorPlan_t,
345345
alpha::Ptr{Cvoid}, A::Ptr{Cvoid}, B::Ptr{Cvoid},
346-
stream::Cint)::hiptensorStatus_t
346+
stream::hipStream_t)::hiptensorStatus_t
347347
end
348348

349349
@checked function hiptensorCreateElementwiseBinary(handle, desc, descA, modeA, opA, descC, modeC,
@@ -368,7 +368,7 @@ end
368368
alpha::Ptr{Cvoid}, A::Ptr{Cvoid},
369369
gamma::Ptr{Cvoid}, C::Ptr{Cvoid},
370370
D::Ptr{Cvoid},
371-
stream::Cint)::hiptensorStatus_t
371+
stream::hipStream_t)::hiptensorStatus_t
372372
end
373373

374374
@checked function hiptensorCreateElementwiseTrinary(handle, desc, descA, modeA, opA, descB, modeB,
@@ -400,12 +400,12 @@ end
400400
beta::Ptr{Cvoid}, B::Ptr{Cvoid},
401401
gamma::Ptr{Cvoid}, C::Ptr{Cvoid},
402402
D::Ptr{Cvoid},
403-
stream::Cint)::hiptensorStatus_t
403+
stream::hipStream_t)::hiptensorStatus_t
404404
end
405405

406-
function hiptensorCreateReduction(handle, desc, descA, modeA, opA, descC, modeC, opC, descD,
406+
@checked function hiptensorCreateReduction(handle, desc, descA, modeA, opA, descC, modeC, opC, descD,
407407
modeD, opReduce, descCompute)
408-
@debug_ccall libhiptensor.hiptensorCreateReduction(handle::hiptensorHandle_t,
408+
@ccall libhiptensor.hiptensorCreateReduction(handle::hiptensorHandle_t,
409409
desc::Ptr{hiptensorOperationDescriptor_t},
410410
descA::hiptensorTensorDescriptor_t,
411411
modeA::Ptr{Int32},
@@ -419,13 +419,13 @@ function hiptensorCreateReduction(handle, desc, descA, modeA, opA, descC, modeC,
419419
descCompute::hiptensorComputeDescriptor_t)::hiptensorStatus_t
420420
end
421421

422-
function hiptensorReduce(handle, plan, alpha, A, beta, C, D, workspace, workspaceSize,
422+
@checked function hiptensorReduce(handle, plan, alpha, A, beta, C, D, workspace, workspaceSize,
423423
stream)
424-
@debug_ccall libhiptensor.hiptensorReduce(handle::hiptensorHandle_t, plan::hiptensorPlan_t,
424+
@ccall libhiptensor.hiptensorReduce(handle::hiptensorHandle_t, plan::hiptensorPlan_t,
425425
alpha::Ptr{Cvoid}, A::Ptr{Cvoid}, beta::Ptr{Cvoid},
426426
C::Ptr{Cvoid}, D::Ptr{Cvoid}, workspace::Ptr{Cvoid},
427427
workspaceSize::UInt64,
428-
stream::Cint)::hiptensorStatus_t
428+
stream::hipStream_t)::hiptensorStatus_t
429429
end
430430

431431
# typedef void ( * hiptensorLoggerCallback_t ) ( int32_t logContext , const char * funcName , const char * msg )

0 commit comments

Comments
 (0)