CoolFace
Datasetpublic

willychan21/ParallelKernelBench_Problems

ParallelKernelBench (benchmark) Reference problems for ParallelKernelBench: a benchmark for LLM-generated multi-GPU CUDA kernels. This dataset contains 87 reference implementations in reference/ and the input tensor specification in utils/input_output_tensors.py. Files Path Description data/problems.parquet One row per problem (tabular access) reference/*.py Reference solution() implementations utils/input_output_tensors.py Input/output tensor… See the full description on the dataset page: https://huggingface.co/datasets/willychan21/ParallelKernelBench_Problems.

sourceHugging Faceapache-2.0updated 4mo agoView on Hugging Face
0likes263downloads
50_moe_ep_wide.py310 linesDownload Raw Back to reference
1from typing import List, Optional, Tuple, Union2 3import torch4import torch.distributed as dist5 6 7class _AllToAll(torch.autograd.Function):8    @staticmethod9    def forward(ctx, group, input, output_split_sizes, input_split_sizes):10        ctx.group = group11        ctx.output_split_sizes = output_split_sizes12        ctx.input_split_sizes = input_split_sizes13        if dist.get_world_size(group=group) == 1:14            return input.contiguous()15        input = input.contiguous()16        if output_split_sizes is None:17            output = torch.empty_like(input)18        else:19            output = torch.empty(20                size=(sum(output_split_sizes), input.size(1)),21                dtype=input.dtype,22                device=input.device,23            )24        dist.all_to_all_single(25            output,26            input,27            output_split_sizes=output_split_sizes,28            input_split_sizes=input_split_sizes,29            group=group,30        )31        return output32 33    @staticmethod34    def backward(ctx, grad_output):35        return (36            None,37            _AllToAll.apply(38                ctx.group, grad_output, ctx.input_split_sizes, ctx.output_split_sizes39            ),40            None,41            None,42        )43 44 45def _all_to_all(46    group: dist.ProcessGroup,47    input: torch.Tensor,48    output_split_sizes: Optional[List[int]],49    input_split_sizes: Optional[List[int]],50) -> torch.Tensor:51    return _AllToAll.apply(group, input, output_split_sizes, input_split_sizes)52 53 54def _preprocess(55    expert_mask: torch.Tensor,56    num_experts: int,57    ep_group: dist.ProcessGroup,58) -> Tuple[List[int], List[int], torch.Tensor, torch.Tensor]:59    ep_size = ep_group.size()60    num_local_experts = num_experts // ep_size61    rank = dist.get_rank(ep_group)62    num_local_tokens_per_expert = expert_mask.sum(dim=(1, 2))63    input_splits = (64        num_local_tokens_per_expert.reshape(ep_size, num_local_experts).sum(dim=1).tolist()65    )66    num_local_tokens_per_expert_flat = num_local_tokens_per_expert.contiguous().view(-1)67    output_size = ep_size * num_local_tokens_per_expert_flat.numel()68    num_global_tokens_per_expert_flat = torch.empty(69        output_size,70        dtype=num_local_tokens_per_expert.dtype,71        device=num_local_tokens_per_expert.device,72    )73    dist.all_gather_into_tensor(74        num_global_tokens_per_expert_flat, num_local_tokens_per_expert_flat, group=ep_group75    )76    num_global_tokens_per_expert = num_global_tokens_per_expert_flat.view(77        ep_size, num_local_tokens_per_expert.size(0)78    )79    start_idx, end_idx = rank * num_local_experts, (rank + 1) * num_local_experts80    num_global_tokens_per_local_expert = num_global_tokens_per_expert[81        :, start_idx:end_idx82    ].contiguous()83    output_splits = num_global_tokens_per_local_expert.sum(dim=1).tolist()84    num_global_sum_tokens_per_local_expert = num_global_tokens_per_local_expert.sum(85        dim=086    ).to(torch.device("cpu"), non_blocking=True)87    num_global_tokens_per_local_expert = num_global_tokens_per_local_expert.view(88        -1, num_local_experts89    ).to(torch.device("cpu"), non_blocking=True)90    return (91        input_splits,92        output_splits,93        num_global_tokens_per_local_expert,94        num_global_sum_tokens_per_local_expert,95    )96 97 98def _permute(99    tokens: torch.Tensor, routing_map: torch.Tensor100) -> Tuple[torch.Tensor, torch.Tensor]:101    num_tokens, _ = tokens.shape102    num_experts = routing_map.shape[0]103    routing_map = routing_map.bool()104    token_indices = (105        torch.arange(num_tokens, device=routing_map.device)106        .unsqueeze(0)107        .expand(num_experts, -1)108    )109    sorted_indices = token_indices.masked_select(routing_map)110    permuted_input = tokens.index_select(0, sorted_indices)111    return permuted_input, sorted_indices112 113 114def _sort_chunks_by_idxs(115    input: torch.Tensor,116    split_sizes: Union[torch.Tensor, List[int]],117    sorted_idxs: List[int],118) -> torch.Tensor:119    if isinstance(split_sizes, torch.Tensor):120        split_sizes = split_sizes.tolist()121    chunks = torch.split(input, split_sizes, dim=0)122    return torch.cat([chunks[i] for i in sorted_idxs], dim=0)123 124 125def _generate_weights_idx(126    routing_weights: torch.Tensor,127    selected_experts: torch.Tensor,128    num_experts: int,129) -> torch.Tensor:130    num_tokens, topk = routing_weights.shape131    weights_idx = torch.zeros(132        (num_tokens, num_experts),133        dtype=routing_weights.dtype,134        device=routing_weights.device,135    )136    weights_idx.scatter_add_(1, selected_experts, routing_weights)137    return weights_idx138 139 140def _unpermute(141    tokens: torch.Tensor,142    routing_weights: torch.Tensor,143    hidden_states_shape: torch.Size,144    permutation_mapping: torch.Tensor,145    routing_map: torch.Tensor,146) -> torch.Tensor:147    tokens_weight = routing_weights.T.contiguous().masked_select(routing_map.bool())148    tokens = tokens * tokens_weight.unsqueeze(-1)149    hidden_dim = hidden_states_shape[-1]150    unpermuted_tokens = torch.zeros(151        hidden_states_shape, device=tokens.device, dtype=tokens.dtype152    )153    expanded_mapping = permutation_mapping.unsqueeze(1).expand(-1, hidden_dim)154    unpermuted_tokens.scatter_add_(0, expanded_mapping, tokens)155    return unpermuted_tokens156 157 158def token_pre_all2all(159    hidden_states: torch.Tensor,160    expert_mask: torch.Tensor,161    num_experts: int,162    input_splits: List[int],163    output_splits: List[int],164    num_global_tokens_per_local_expert: torch.Tensor,165    group: Optional[dist.ProcessGroup] = None,166) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Size]:167    group = group or dist.group.WORLD168    hidden_dim = hidden_states.size(-1)169    hidden_states = hidden_states.reshape(-1, hidden_dim)170    org_hidden_states_shape = hidden_states.shape171    routing_map = expert_mask.sum(dim=1)172 173    local_permuted_hidden_states, local_input_permutation_mapping = _permute(174        hidden_states, routing_map175    )176    expected_tokens = sum(input_splits)177    actual_tokens = local_permuted_hidden_states.shape[0]178    if expected_tokens != actual_tokens:179        raise RuntimeError(180            f"EP split mismatch: input_splits sum ({expected_tokens}) != "181            f"permuted tokens ({actual_tokens})"182        )183 184    global_permuted_hidden_states = _all_to_all(185        group, local_permuted_hidden_states, output_splits, input_splits186    )187    num_local_experts = num_experts // dist.get_world_size(group)188    permute_order = (189        torch.arange(num_experts).reshape(-1, num_local_experts).T.ravel().tolist()190    )191    split_sizes = num_global_tokens_per_local_expert.ravel().tolist()192    global_permuted_hidden_states = _sort_chunks_by_idxs(193        global_permuted_hidden_states, split_sizes, permute_order194    )195    return (196        global_permuted_hidden_states,197        routing_map,198        local_input_permutation_mapping,199        org_hidden_states_shape,200    )201 202 203def tokens_post_all2all(204    expert_outputs: torch.Tensor,205    routing_weights: torch.Tensor,206    selected_experts: torch.Tensor,207    num_experts: int,208    input_splits: List[int],209    output_splits: List[int],210    num_global_tokens_per_local_expert: torch.Tensor,211    routing_map: torch.Tensor,212    local_input_permutation_mapping: torch.Tensor,213    org_hidden_states_shape: torch.Size,214    group: Optional[dist.ProcessGroup] = None,215) -> torch.Tensor:216    group = group or dist.group.WORLD217    num_local_experts = num_experts // dist.get_world_size(group)218    unpermute_order = (219        torch.arange(num_experts).reshape(num_local_experts, -1).T.ravel().tolist()220    )221    split_sizes = num_global_tokens_per_local_expert.T.ravel().tolist()222    expert_outputs = _sort_chunks_by_idxs(223        expert_outputs, split_sizes, unpermute_order224    )225    unpermute_outputs = _all_to_all(group, expert_outputs, input_splits, output_splits)226    weights_idx = _generate_weights_idx(routing_weights, selected_experts, num_experts)227    unpermute_outputs = _unpermute(228        unpermute_outputs,229        weights_idx,230        org_hidden_states_shape,231        local_input_permutation_mapping,232        routing_map,233    )234    return unpermute_outputs235 236 237def expert_forward(238    x: torch.Tensor,239    gate_proj: torch.nn.Linear,240    up_proj: torch.nn.Linear,241    down_proj: torch.nn.Linear,242) -> torch.Tensor:243    gate = torch.nn.functional.silu(gate_proj(x))244    up = up_proj(x)245    return down_proj(gate * up)246 247 248def solution(249    hidden_states: torch.Tensor,250    gate_weight: torch.Tensor,251    gate_bias: Optional[torch.Tensor],252    gate_proj: torch.nn.Linear,253    up_proj: torch.nn.Linear,254    down_proj: torch.nn.Linear,255    num_experts: int,256    top_k: int,257    group: Optional[dist.ProcessGroup] = None,258) -> torch.Tensor:259    group = group or dist.group.WORLD260    hidden_dim = hidden_states.size(-1)261    num_tokens = hidden_states.reshape(-1, hidden_dim).size(0)262 263    router_logits = torch.nn.functional.linear(264        hidden_states.reshape(-1, hidden_dim), gate_weight, gate_bias265    )266    routing_weights, selected_experts = torch.topk(267        torch.softmax(router_logits, dim=-1), top_k, dim=-1268    )269    expert_mask = torch.nn.functional.one_hot(270        selected_experts, num_classes=num_experts271    ).permute(2, 1, 0)272 273    input_splits, output_splits, num_global_tokens_per_local_expert, _ = _preprocess(274        expert_mask, num_experts, group275    )276 277    (278        global_permuted_hidden_states,279        routing_map,280        local_input_permutation_mapping,281        org_hidden_states_shape,282    ) = token_pre_all2all(283        hidden_states,284        expert_mask,285        num_experts,286        input_splits,287        output_splits,288        num_global_tokens_per_local_expert,289        group,290    )291 292    expert_outputs = expert_forward(293        global_permuted_hidden_states, gate_proj, up_proj, down_proj294    )295 296    out = tokens_post_all2all(297        expert_outputs,298        routing_weights,299        selected_experts,300        num_experts,301        input_splits,302        output_splits,303        num_global_tokens_per_local_expert,304        routing_map,305        local_input_permutation_mapping,306        org_hidden_states_shape,307        group,308    )309    return out310