Skip to content

Update QoLA/AITER #599

Open
Micky774 wants to merge 54 commits into
devfrom
zain/qola/aiter-update
Open

Update QoLA/AITER #599
Micky774 wants to merge 54 commits into
devfrom
zain/qola/aiter-update

Conversation

@Micky774

Copy link
Copy Markdown
Contributor

Description

Updates QoLA as well as moves up the pinned AITER commit

Fixes # (issue)

Type of change

  • Documentation change (change only to the documentation, either a fix or a new content)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Infra/Build change
  • Code refactoring

Changes

Please list the changes introduced in this PR:

  • Change A
  • Change B

Checklist:

  • I have read and followed the contributing guidelines
  • The functionality is complete
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@Micky774 Micky774 added the ci-level 3 CI test level 3 label May 28, 2026
Comment thread transformer_engine/common/ck_fused_attn/CMakeLists.txt Outdated
Comment thread transformer_engine/common/ck_fused_attn/src/ck_fused_attn_bwd.cpp
# commit QoLA will actually check out and build, not whatever happens to be
# the submodule's current HEAD at configure time.
set(__QOLA_MANIFEST "${CMAKE_CURRENT_LIST_DIR}/qola_manifest.toml")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${__QOLA_MANIFEST}")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AITER_SHA is not cached variable. Why is CMAKE_CONFIGURE_DEPENDS needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mainly have it so that direct cmake or ninja building will catch on manifest changes since I use it for incremental builds (and am thinking about including an incremental build option for TE's AITER FA backend). It's not strictly necessary, just a nice to have in such a workflow

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it also trigger re-executing of QoLA cli in the parent (ck_used_attn/ ) CMAkeLists.txt?

Comment thread transformer_engine/common/ck_fused_attn/CMakeLists.txt
return nullptr;
}
void* ptr = nullptr;
if(hipMallocAsync(&ptr, bytes, stream) != hipSuccess){

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emm, if we let hip runtime to allocate and manage our buffers, this will create a series of issues. For example, if Pytorch or JAX users pre-allocate 97% of HBM, then our hipMallocAsync will return out of memory.

If what new aiter needs for fmha_args.workspace_alloc is a lambda, we can fake it to give jax/pytorch generated workspace buffer ptr?

// callback thread, which holds runtime locks — calling any HIP API from it
// (including hipHostFree) deadlocks against concurrent main-thread HIP
// calls. Defer the free to ck_tile::pinned_host_releaser's worker thread.
fmha_args.pinned_host_alloc = [](size_t bytes) -> std::shared_ptr<void> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emm, why do they need host memory allocated? Is it for inference?

Again, can we fake the lambda to use pytorch/jax generated workspace?

@VeeraRajasekhar VeeraRajasekhar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified that ROCm/rocm-libraries#6764 exists in the current pinned aiter commit.

size_t head_dim_v,
int64_t window_size_left,
int64_t window_size_right,
bool is_training, bool cuda_graph) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding, is_ck_backend_supported is the only consumer of the new graph-capture gate, but it's called without deterministic (TransformerEngine\transformer_engine\common\fused_attn_rocm\fused_attn.cpp line 320) even though nvte_get_fused_attn_backend has it in scope (TransformerEngine\transformer_engine\common\fused_attn_rocm\fused_attn.cpp line 282).

Since deterministic bwd forces the non-graph-safe CK v2 path, is_ck_bwd_graph_capture_safe cannot make the right call without it. See my other related comments above for what could be added to fix.

You should include here the bool deterministic as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

is_v3_arch &&
dropout == 0.f &&
bias_type == NVTE_Bias_Type::NVTE_NO_BIAS &&
max_seqlen_q >= 16;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add && !deterministic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

// unaffected). Determinism also forces v2 but is invisible here, so it is handled
// on the framework side.
if(is_training && cuda_graph &&
!is_ck_bwd_graph_capture_safe(bias_type, dropout, max_seqlen_q)){

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should include here the deterministic as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

static bool is_ck_bwd_graph_capture_safe(
NVTE_Bias_Type bias_type,
float dropout,
size_t max_seqlen_q) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add bool deterministic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

window_size_left,
window_size_right)){
window_size_right,
is_training, cuda_graph)){

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass here the deterministic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@ipanfilo

ipanfilo commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

The latest fixes for determinism seem not helping on gfx942

@Micky774

Micky774 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Alright looks like the failures are unrelated now.

Comment thread transformer_engine/common/ck_fused_attn/src/ck_fused_attn_bwd.cpp
if(bytes == 0){
return nullptr;
}
constexpr size_t kAlign = 256;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this kAlign=256 coming from?

is_training, Q_type, KV_type, qkv_layout, bias_type, attn_mask_type, softmax_type, dropout,
h_q, h_kv, max_seqlen_q, max_seqlen_kv, d_qk, d_v, window_size_left, window_size_right,
return_max_logit, cuda_graph, false);
return_max_logit, false, false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we enable cuda_graph=true before?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was ignored before, so we can set it to false arbitrarily. I've added a comment clarifying this.

Comment thread transformer_engine/common/fused_attn_rocm/fused_attn_ck.cpp
Comment thread transformer_engine/common/ck_fused_attn/src/ck_fused_attn_bwd.cpp Outdated
@Micky774
Micky774 force-pushed the zain/qola/aiter-update branch from fec6d6b to cf46085 Compare July 13, 2026 21:10
// illegal under HIP-graph capture. So reserve a capture-safe upper bound instead.
//
// The dq_acc split count is ceil(seqlen_k / kN0) where kN0 is the dispatched bwd KV tile
// (bn0). The largest bn0 across supported archs is kCkBwdMaxKvTile (per the CK codegen bwd

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bn0 is the same as kN0?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a naming difference in different parts of the backend, but it's passed as the same var.

// least one extra split for any actually-dispatched kN0 (all <= kCkBwdMaxKvTile), which
// covers inter-sequence padding of up to a whole tile per sequence -- far above the
// few-token THD alignment padding used in practice.
constexpr uint64_t kCkBwdMaxKvTile = 256;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emm, this const is copied from CK source code? If so, it may be changed later in CK which can cause our issue.

const size_t a16_hdim = (args.d_qk == 192) ? 192 : 128;
const size_t dq_acc_seq = args.is_v3_atomic_fp32 ? seqlen_q : a16_seq;
const size_t dq_acc_hdim = args.is_v3_atomic_fp32 ? args.d_qk : a16_hdim;
const size_t eff_batch = (args.is_group_mode() && args.is_v3_atomic_fp32) ? 1 : args.b;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my mind, effective batch should be related to whether it's in group mode or not. bf16 or fp32 atomic mode should not affect it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, let's put a comment of this code pointer so in the future we can understand where this piece of hardcoding code is from.

Comment thread transformer_engine/common/ck_fused_attn/src/ck_fused_attn_bwd.cpp
Comment thread transformer_engine/common/ck_fused_attn/src/ck_fused_attn_bwd.cpp
// host-side; v3 (asm) allocates only dq_acc. v3 is tried first but may fall
// back to v2, so reserve the larger of the two. The launcher symbol is forced
// local by QoLA's export script, so the v2 size is queried through QoLA.
const size_t v2_bytes = QOLA_NS(mha_bwd_workspace_size)(make_bwd_traits(args));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remind me where the mha_bwd_workspace_size is defined?

If the v2_bytes sometimes under estimate the real CK needs, can we change the mha_bwd_workspace_size there? Then we don't need to have std::max over three items. (We can just std::max over v3 asm needs and v2 ck needs)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if mha_bwd_workspace_size is defined in CK or qola, maybe should also put v3_dq_acc_bytes into qola

const size_t a16_hdim = (args.d_qk == 192) ? 192 : 128;
const size_t dq_acc_seq = args.is_v3_atomic_fp32 ? seqlen_q : a16_seq;
const size_t dq_acc_hdim = args.is_v3_atomic_fp32 ? args.d_qk : a16_hdim;
const size_t eff_batch = (args.is_group_mode() && args.is_v3_atomic_fp32) ? 1 : args.b;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, let's put a comment of this code pointer so in the future we can understand where this piece of hardcoding code is from.

}
const size_t seqlen_q = args.is_group_mode() ? args.max_tokens_q : args.s_q;
const size_t elem = args.is_v3_atomic_fp32 ? 4 : 2;
const size_t a16_seq = (args.s_q + 15) / 16 * 16;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, let's add non 16 multiple sq's to our unit tests to see what will happen.

// host-side; v3 (asm) allocates only dq_acc. v3 is tried first but may fall
// back to v2, so reserve the larger of the two. The launcher symbol is forced
// local by QoLA's export script, so the v2 size is queried through QoLA.
const size_t v2_bytes = QOLA_NS(mha_bwd_workspace_size)(make_bwd_traits(args));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if mha_bwd_workspace_size is defined in CK or qola, maybe should also put v3_dq_acc_bytes into qola

fmha_args.mask_type = static_cast<int>(static_cast<mask_enum>(args.attn_mask_type));
fmha_args.use_asm_v3 = args.uses_bwd_v3;
// Mirrors AITER's small-seqlen guard at aiter/ops/mha.py:1689.
fmha_args.use_asm_v3 = (args.s_q < 16) ? false : args.uses_bwd_v3;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: have such a testcase (s_q<16) to see if things work as our expectation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have several where s_q=1 which trigger this code path. Specifically it was put in as a response to a failing test case originally.

Comment thread 3rdparty/ck_jit
Comment thread transformer_engine/jax/csrc/extensions/attention.cpp Outdated
Comment thread ci/ck_jit_prebuild.txt
@Micky774
Micky774 requested a review from ipanfilo July 22, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-level 3 CI test level 3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants