opensource_community
← Return to test report
ENGINEERING REPORT / UPDATED 2026-08-17

Hashcat HIP Adaptation and Cross-Platform Validation on Hygon DCU

Validation across DTK 25.04.2–26.04 and gfx936 / gfx906-Z100, covering ABI analysis, code changes, build troubleshooting, HIP/OpenCL comparison, multi-algorithm performance, and sustained-load behavior.

Project directory:/path/to/hashcat Test environment: two DCU node groups (location, cluster, and node names redacted) Hashcat: v7.1.2 Author: opensource_community

1. Executive Summary

Hashcat v7.1.2 includes a HIP backend, but its built-in HIP ABI is incompatible with Hygon DTK's libgalaxyhip.so, preventing device initialization. This work identified and fixed the compatibility issue on gfx936 with DTK 25.04.2, then applied the same adaptation to gfx906/Z100 with DTK 26.04. The resulting evidence covers ABI analysis, conditional compilation, runtime checks, and cross-version regression.

Validation platforms2 setsgfx936 / gfx906
HIP SHA2-2565.914 GH/s45 seconds continuous load
OpenCL SHA2-2565.913 GH/s45 seconds continuous load
DTK ABIaligned25.04.2 / 26.04

1.1 Cross-version validation environments

Platform A · baseline

  • DTK 25.04.2 / HIP 6.3.25422
  • BW / gfx936 / 80 MCUs
  • VRAM: 65,520 MB; core clock: 1500 MHz
  • Supports both HIP and OpenCL, enabling a same-device backend comparison

Platform B · migration

  • DTK 26.04 / HIP 6.3.26113
  • Z100 (device output Device 66a1) / gfx906 / 64 MCUs
  • VRAM: 16,368 MB; core clock: 1700 MHz
  • Validates HIP only; OpenCL runtime is not available in this computing environment
Core conclusion: The same DTK HIP adaptation supports device enumeration, HIPRTC compilation, benchmarking, and normal process exit on two DCU generations and two DTK versions. On gfx936, SHA2-256 throughput differs by less than 0.01% between HIP and OpenCL. On gfx906/Z100, HIP passed checks across 10 algorithms and a 60-second stability run. These results address different questions; they are not a same-device backend comparison.

2. Test environment and artifacts

2.1 Software environment

  • Hashcat: v7.1.2
  • DTK: 25.04.2
  • HIP: 6.3.25422
  • OpenCL: OpenCL 2.1s C-3000-APP (3452.0)
  • Kernel: 5.10.134-17.1.3.sga8.x86_64
  • System: Sugon OS 8.9

2.2 Hardware environment

  • Test node: <compute-node> (name redacted)
  • DCU name: BW
  • ISA: gfx936:sramecc+:xnack-
  • Device type: HCU
  • Compute units: 80
  • VRAM: 65520 MB
  • Core clock: 1500 MHz

2.3 Build artifacts

PurposepathSizeSHA-256
DTK HIP adapted versionhashcat-hip-dtk1,332,656 Bbe0b2201c913828488dfe07ce64eef3f481c97ae4cfe41d4af8ffc1549df1e36
OpenCL baseline versionhashcat-opencl-original1,332,656 Ba25c3b28ad1c980aef71457ff0cc7d367dd0e4165ab2dc6ac9d20fcb48208994

The binary example path is /path/to/hashcat/. The OpenCL baseline version is kept separately for regression verification and performance comparison.

3. Compatibility behavior and root-cause analysis

3.1 Login node and compute node behavior

The login node does not expose /dev/kfd, so it can be used to inspect HIP symbols in the binary but not to verify device execution. On an allocated DCU compute node, rocminfo, hy-smi, and OpenCL detect the device as expected.

rocminfo:
  Name:           gfx936
  Marketing Name: BW
  Device Type:    HCU
  Compute Unit:   80

3.2 HIP initialization before adaptation

./hashcat -II --backend-ignore-cuda --backend-ignore-opencl

hashcat (v7.1.2) starting in backend information mode
hipDeviceGetAttribute(): invalid argument
No devices found/left.

OpenCL detects the BW device. This confirms that the hardware, job allocation, driver, and device permissions are working, narrowing the investigation to Hashcat's host-side HIP API compatibility layer.

3.3 HIP ABI mismatch

To preserve runtime loading, Hashcat declares the HIP interfaces it needs in include/ext_hip.h instead of depending on the system HIP headers at build time. Hashcat 7.1.2's bundled declarations follow a newer ROCm ABI, while DTK 25.04.2's hip_runtime_defines.h uses a different, older layout.

DTK PropertiesDTK 25.04.2 ValuePurpose
hipDeviceAttributeMaxThreadsPerBlock18Maximum threads per block
hipDeviceAttributeMaxSharedMemoryPerBlock25Shared memory per block
hipDeviceAttributeTotalConstantMemory26Total constant memory
hipDeviceAttributeWarpSize27Wavefront width
hipDeviceAttributeClockRate29Device clock rate
hipDeviceAttributeMultiprocessorCount32Compute-unit count
hipDeviceAttributeComputeCapabilityMajor/Minor36 / 37Compute capability
hipDeviceAttributePciBusId/PciDeviceId39 / 40PCI bus and device IDs
hipDeviceAttributeIntegrated42Integrated-device flag
hipDeviceAttributeKernelExecTimeout79Kernel timeout attribute

A separate probe confirms that DTK reports sizeof(hipDeviceProp_t) = 792. Key field offsets are totalGlobalMem=256, regsPerBlock=272, warpSize=276, clockRate=308, major=328, multiProcessorCount=336, and gcnArchName=396. These offsets differ substantially from Hashcat's bundled structure definition.

4. Code changes

The adaptation is opt-in, so the default build remains unchanged. Changes are limited to the build switch, HIP type definitions, device-attribute initialization, dynamic-library lifetime, and adaptation notes.

Step 1: Add independent build switch
src/Makefile

Add DTK_HIP ?= 0. Build with make DTK_HIP=1 only when HC_HIP_DTK is enabled; otherwise, the default ROCm ABI remains unchanged.

DTK_HIP ?= 0

ifeq ($(DTK_HIP),1)
CFLAGS += -DHC_HIP_DTK
endif
Step 2: Align DTK Device Property Enumeration
include/ext_hip.h

Under the HC_HIP_DTK conditional, define the DTK attribute IDs used by Hashcat explicitly. Keep the original full enumeration in the #else branch so the default ROCm build is unaffected.

Step 3: Align the 792-byte device attribute structure
include/ext_hip.h

Define a DTK-compatible hipDeviceProp_t layout so that values written by hipGetDeviceProperties() match the offsets Hashcat reads, especially for regsPerBlock and gcnArchName.

Step 4: Compatible with missing register attributes
src/backend.c

The older DTK structure has no regsPerMultiprocessor field, and querying attribute 69 returns hipErrorInvalidValue. The DTK branch therefore uses prop.regsPerBlock as a conservative fallback.

#if defined (HC_HIP_DTK)
device_param->regsPerMultiprocessor = prop.regsPerBlock;
#else
device_param->regsPerMultiprocessor = prop.regsPerMultiprocessor;
#endif
Step 5: Complete the diagnostic log
src/ext_hip.c

The diagnostic log now reports both the device ID and attribute ID, making it easier to map runtime results to specific ABI fields. The patch also corrects the hipGetDeviceProperties call.

hipDeviceGetAttribute(dev=0, attrib=69): invalid argument
Step 6: Keep HIP libraries loaded until process exit
src/ext_hip.c / src/ext_hiprtc.c

DTK's HIP/HIPRTC shared libraries register C++ shutdown callbacks. If Hashcat calls dlclose() early, libstdc++ may invoke a callback during process shutdown after its library has been unloaded, jumping to an invalid address. The DTK build therefore keeps both libraries loaded until process exit and lets the operating system reclaim them.

Step 7: Save product and adaptation documentation
.gitignore / docs/dtk-hip-adaptation.md

The generated binary is not checked into version control. The report documents the build, validation, and version constraints; the OpenCL baseline binary is kept separately for regression tests and performance comparisons.

5. Fault localization and debugging

  1. Confirmed binary contains HIP:Checked hipInit、hipDeviceGetAttribute、hiprtcCompileProgram , and --backend-ignore-hip parameters.
  2. Eliminate misjudgment of no-card nodes:The login node is missing /dev/kfd; After switching to the assigned computing node, the DCU and driver are normal.
  3. Establish an OpenCL baseline:OpenCL detects the BW device and completes the MD5 benchmark, confirming that the hardware and Hashcat core are functioning.
  4. Enhanced logging post-lock enumeration:First failed attribute changes from opaque error to attrib=69, and then use the DTK header file to compile the detection program to check the value and structure offset item by item.
  5. First ABI fix:After aligning the property enum and structure layout, device enumeration advanced to the register-property query. Runtime testing confirmed that DTK does not support attribute 69.
  6. Register-property fallback: A probe reported prop.regsPerBlock=196608, while attribute 69 returned an error. The adaptation uses this value as a conservative fallback.
  7. HIP device enumeration passed:Hashcat reports HIP 6.3.25422, BW, 80 MCUs, 65,520 MB, and the PCI address.
  8. HIPRTC Verification:MD5 and NTLM benchmark succeeded, proving that gfx936 .
  9. found exit phase SIGSEGV:The calculation result has been output, but the exit code is 139. Use GDB to locate atexit_thread.cc:75, the top of the stack is the unsigned unloaded address.
  10. Fix DSO lifecycle:DTK branch retains HIP/HIPRTC DSO until the process exits, and then the benchmark exit code returns to 0.
  11. Correctness verification: An actual MD5 dictionary attack passed the self-test and recovered e11c594e6a2f4eb499cceadfca988595:13LEXON.

5.1 Key GDB backtrace

Thread 1 "hashcat-hip-dtk" received signal SIGSEGV
0x000015552f2620e0 in ?? ()
#0  0x000015552f2620e0 in ?? ()
#1  (anonymous namespace)::run
    at libstdc++-v3/libsupc++/atexit_thread.cc:75
#2  __run_exit_handlers () from /lib64/libc.so.6
#3  exit () from /lib64/libc.so.6

The traceback indicates that the dynamic library had been unloaded while a function pointer was still retained during processor shutdown. After correcting the DSO lifetime, the same test exited normally, confirming this diagnosis.

6. Git and compilation process

6.1 Initialize the Git baseline

To ensure that the adaptation process is traceable, the source code baseline can be established first, and then the DTK HIP adaptation changes can be recorded in an independent branch. The following commands show a reference flow.

cd /path/to/hashcat
git init -b dtk-hip-adaptation
git add -A
git commit -m "baseline: import hashcat 7.1.2 source tree"

# After making and verifying the changes
git add .gitignore include/ext_hip.h src/Makefile \
  src/backend.c src/ext_hip.c src/ext_hiprtc.c \
  docs/dtk-hip-adaptation.md
git commit -m "feat: adapt HIP backend for DTK 25.04.2"
SubmitDescription
Baseline commit ID redactedHashcat v7.1.2 source tree baseline
Adaptation commit ID redactedDTK 25.04.2 HIP backend adaptation

6.2 Compilation steps

Build note: Object-file names do not encode preprocessor definitions. Run make clean before switching between the default build and DTK_HIP=1 to avoid reusing objects compiled against a different ABI.
cd /path/to/hashcat

# Preserve the original binary
cp -p hashcat hashcat-opencl-original

# Clean and build the DTK-specific version
make clean
make DTK_HIP=1 ENABLE_LTO=0
mv hashcat hashcat-hip-dtk

# Basic checks
./hashcat-hip-dtk --version
sha256sum hashcat-hip-dtk hashcat-opencl-original

ENABLE_LTO=0 reduces link complexity during adaptation debugging and keeps builds predictable. The DTK-specific code is enabled with DTK_HIP=1.

6.3 DTK 26.04 toolchain and scheduling notes

On the migration platform, the newer GCC module conflicts with the system toolchain. System GCC 4.8.5 also lacks the AVX512F intrinsics required by the bridges module. The tested build uses DTK's dcc (Clang 17) for source files and system GCC for final archive linking. The bridges module is not built; it is outside the core hashing functionality evaluated here.

Compiler and static archives

If dcc is asked to create the final .a archive directly, it may treat the archive as a source file. Use make DTK_HIP=1 ENABLE_LTO=0 and verify that the final linker can consume the archive.

Where to define attribute overrides

Place DTK attribute-override macros after the enum declaration. Defining them earlier replaces enum member names during preprocessing and causes compilation errors. In the DTK structure, fields Hashcat never reads can be represented by same-sized placeholders, but verify the total structure size and every relevant offset with a probe program.

File visibility on compute nodes

A login node's temporary directory may not be mounted on compute nodes. Place the binary, OpenCL/, modules/, and hashcat.hcstat2 in a shared project directory. User paths, partition names, and node names are represented by placeholders in this report.

Batch and interactive jobs

In this environment, batch jobs failed with a site-specific signal while interactive jobs using the same resources ran normally. This points to a scheduling-policy or job-script issue; the evidence does not implicate Hashcat. For reproduction, use the partition and resource settings in the site's documentation.

6.4 Verification commands

ssh <compute-node>
cd /path/to/hashcat

# Enable HIP only
./hashcat-hip-dtk -II \
  --backend-ignore-cuda \
  --backend-ignore-opencl

# Enable OpenCL only
./hashcat-opencl-original -II \
  --backend-ignore-cuda \
  --backend-ignore-hip

7. Cross-version ABI and platform migration verification

The ABI probe was rebuilt against the DTK 26.04 headers and compared item by item with the DTK 25.04.2 results. All 12 device-attribute enum values used by this adaptation match: 18, 25, 26, 27, 29, 32, 36, 37, 39, 40, 42, and 79.

ABI check itemDTK 25.04.2DTK 26.04Result
sizeof(hipDeviceProp_t)792792consistent
totalGlobalMem / regsPerBlock / warpSize256 / 272 / 276256 / 272 / 276consistent
clockRate / major / multiProcessorCount308 / 328 / 336308 / 328 / 336consistent
gcnArchName396396consistent
Migration conclusion: The DTK 25.04.2 adaptation also works on 26.04 in the tested environment. This is an observed compatibility result, not a guarantee for future DTK releases; recheck enum values, structure size, and field offsets after each upgrade.

8. Functional and correctness verification

Verification itemCommand/ModeResult
HIP device enumeration-II --backend-ignore-cuda --backend-ignore-openclPassed
HIPRTC optimized kernelMD5 benchmarkPassed
MD5 benchmark-b -m 039342.9 MH/s
NTLM benchmark-b -m 100063283.5 MH/s
Self-testMD5 dictionary actual attackPassed
Recovered hashexample0.hash + example.dictRecovered 13LEXON
Resource release and exitafter benchmarkingExit code 0
./hashcat-hip-dtk -m 0 -a 0 example0.hash example.dict \
  --backend-ignore-cuda --backend-ignore-opencl \
  --potfile-disable --restore-disable

Recovered:
e11c594e6a2f4eb499cceadfca988595:13LEXON

The final status code for this dictionary test is 1: the input contains 6494 hashes, 1 of which is restored when the small dictionary is exhausted. Both self-test and target recovery were successful, so this status code reflects task completion conditions rather than a HIP backend exception.

8.1 gfx906/Z100 device verification

HIP.Version.: 6.3.26113

Backend Device ID #01
  Name...........: Device 66a1
  Processor(s)...: 64
  Preferred.Thrd.: 64
  Clock..........: 1700
  Memory.Total...: 16368 MB
  Memory.Free....: 16101 MB
  Memory.Unified.: 0
  Local.Memory...: 64 KB
  PCI.Addr.BDFe..: <redacted>

Device enumeration, HIPRTC kernel compilation, attribute queries, multi-algorithm benchmarking, and exit-code checks all passed. Environment-specific identifiers, including PCI addresses, are redacted.

9. Performance verification and comparison

9.1 Same-card backend comparison on gfx936

To avoid short runs masking differences in sustained performance, both backends ran the same SHA2-256 brute-force workload over the full printable 8-bit character set, with a key space of 95^8 = 6,634,204,312,890,625. Unlikely target hashes kept the DCU fully loaded. Each run lasted about 45 seconds, while hy-smi sampled power, temperature, and utilization every two seconds.

# HIP
./hashcat-hip-dtk -m 1400 -a 3 \
  ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff \
  '?a?a?a?a?a?a?a?a' -O -w 3 --runtime 45 \
  --status --status-timer 5 --potfile-disable --restore-disable \
  --backend-ignore-cuda --backend-ignore-opencl

# OpenCL: same attack parameters; only the backend and binary change
./hashcat-opencl-original -m 1400 -a 3 \
  ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff \
  '?a?a?a?a?a?a?a?a' -O -w 3 --runtime 45 \
  --status --status-timer 5 --potfile-disable --restore-disable \
  --backend-ignore-cuda --backend-ignore-hip

9.2 gfx936 core results

MetricHIPOpenCLInterpretation
Mean throughput (10 samples)5913.79 MH/s5913.48 MH/sHIP is about 0.005% faster; the difference is negligible
Final stable speed5914.3 MH/s5913.8 MH/sThe difference is less than 0.01%
Speed range5911.5–5914.35910.4–5914.0Variation was minimal
Average power consumption at full load368.8 W369.7 WA 0.9 W difference, within sampling variation
Full-load power range365–369 W367–370 WComparable within sampling variation
Average temperature61.0°C61.1°CComparable within sampling variation
Maximum temperature61°C62°CNo significant difference
Average utilization100%100%Both runs sustained full utilization
Host memory8173 MB6132 MBHIP used about 2,041 MB more host memory
End conditionRuntime limit reachedRuntime limit reachedBoth runs stopped as expected

9.2.1 Throughput comparison

HIP
5913.79 MH/s
OpenCL
5913.48 MH/s

Bars are normalized to 5,914.1 MH/s. The two are indistinguishable to the naked eye, consistent with the conclusion that the numerical difference is less than 0.01%.

9.3 Automatic tuning and resource differences

Scheduling parametersHIPOpenCL
Accel627
Loops10241024
Threads1024256
Vector width11
Single scheduling time84.95 ms95.55 ms
Preferred thread multiple6432

The two backends selected different workgroups and acceleration combinations, but the final throughput was consistent, indicating that both paths can fully utilize the DCU. HIP's significantly higher host memory footprint was the clearest resource difference in this test.

9.4 Comparing cumulative work counters

HIP completed 266,757,734,400 operations and OpenCL completed 270,092,206,080. Although the OpenCL total is about 1.25% higher, its final status sample occurred at roughly 46 seconds, versus 45 seconds for HIP; initialization, status refresh, and stop times were not identical. The comparison therefore uses Hashcat's ten continuous throughput samples and draws no performance conclusion from cumulative work totals.

9.5 gfx906/Z100 multi-algorithm HIP benchmark

This migration platform provides HIP but not OpenCL. These results verify algorithm coverage and platform stability; they do not support a comparison with OpenCL on this device.

AlgorithmModegfx906/Z100 HIPScheduling parameters
MD5026819.9 MH/s74 / 1024 / 512 / 1
NTLM100043045.1 MH/s62 / 1024 / 1024 / 1
SHA2-25614004054.0 MH/s22 / 512 / 512 / 1
SHA2-51217001180.9 MH/s12 / 256 / 512 / 1
NetNTLMv2550027703.4 MH/s224 / 1024 / 128 / 1
RIPEMD16060005678.6 MH/s16 / 1024 / 512 / 1
WPA-EAPOL22000476.0 kH/s22 / 256 / 512 / 1
bcrypt320020936 H/s2 / 32 / 16 / 1
Kerberos 5 TGS-REP13100170.5 MH/s62 / 128 / 32 / 1
DPAPI masterkey1530081172 H/s22 / 250 / 512 / 1

Scheduling parameters are listed as Accel / Loops / Threads / Vector width.

9.6 Sustained load and cross-device comparison

algorithm10 seconds60 secondsDifference
SHA2-2564054.0 MH/s4053.9 MH/s< 0.01%
bcrypt20933 H/s20936 H/s< 0.01%
Algorithmgfx906/Z100gfx936/BWZ100 / BW throughput
MD526.82 GH/s39.34 GH/s68%
NTLM43.05 GH/s63.28 GH/s68%
SHA2-2564.05 GH/s5.91 GH/s69%

This set of ratios is an actual observation of two complete machine environments, including multiple differences in computing units, architectures, memory subsystems, software versions, and tuning parameters. It cannot be derived solely from the 64/80 computing unit ratio, nor does it represent a fixed ratio for all hash-modes.

10. Conclusions, recommendations and known limitations

10.1 Availability

HIP device enumeration, HIPRTC compilation, kernel loading, a real cracking run, and normal process exit all passed. The minimum adaptation objective is met.

10.2 Performance

In the SHA2-256 test, both HIP and OpenCL achieved about 5.914 GH/s, with a throughput difference below 0.01%. These measurements show no meaningful performance difference.

10.3 DTK version coverage

The tested ABI values match between DTK 25.04.2 and 26.04, and the adaptation runs on both gfx936 and gfx906. Recheck the ABI after each DTK upgrade.

10.4 Known limitations

10.5 Further work

  1. Extend testing to common workloads: -m 1000, -m 10900, -m 22000, and -m 3200.
  2. Run HIP and OpenCL stability tests for one to four hours while monitoring temperature, power, driver logs, and error counts.
  3. Add runtime probes or compile-time assertions for the DTK ABI to catch layout changes after upgrades.
  4. To pursue further speedups, investigate HIPRTC compilation parameters, register occupancy, wavefront behavior, and workload-specific tuning.

11. Appendix: Reproduction and Audit Commands

11.1 View code changes

cd /path/to/hashcat
git status
git log --oneline --decorate -5
git show --stat <adaptation-commit>
git show <adaptation-commit>

11.2 Rebuild

make clean
make DTK_HIP=1 ENABLE_LTO=0
mv hashcat hashcat-hip-dtk

11.3 Basic verification

ssh <compute-node>
cd /path/to/hashcat

./hashcat-hip-dtk -II --backend-ignore-cuda --backend-ignore-opencl
./hashcat-hip-dtk -b -m 0 --backend-ignore-cuda --backend-ignore-opencl --runtime 10
./hashcat-hip-dtk -b -m 1000 --backend-ignore-cuda --backend-ignore-opencl --runtime 10

11.4 Key file index

fileFunction
src/MakefileDTK_HIP=1 Build entrance
include/ext_hip.hDTK enumeration and structure ABI
src/backend.cdevice attribute initialization compatible with
src/ext_hip.cHIP dynamic loading, logging and DSO life cycle
src/ext_hiprtc.cHIPRTC DSO life cycle
docs/dtk-hip-adaptation.mdBrief adaptation record in the warehouse