[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EARC50P9GQS88VCN22Z828":3,"skill-same:01M6EARC50P9GQS88VCN22Z828":89},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":41,"repositoryHtmlUrl":42,"repositoryHomepageUrl":43,"ownerHtmlUrl":44,"ownerBlogUrl":6,"ownerDescription":45,"updatedAt":46,"install":47,"resources":60},"01M6EARC50P9GQS88VCN22Z828","mojo-gpu-fundamentals",null,"The basics of how to program GPUs using Mojo. Use this skill in addition to mojo-syntax when writing Mojo code that targets GPUs or other accelerators. Use targeting code to NVIDIA, AMD, Apple silicon GPUs, or others. Use this skill to overcome misconceptions about how Mojo GPU code is written.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FHarmeet10000\u002Fskills\u002Fmojo-gpu-fundamentals\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32],"gpu","mojo gpu fundamentals","writing","code","NVIDIA","how","apple silicon","syntax","use","basics","apple","how to","silicon","targets","2026-11-10 10:12:30",false,"---\nname: mojo-gpu-fundamentals\ndescription: The basics of how to program GPUs using Mojo. Use this skill in addition to mojo-syntax when writing Mojo code that targets GPUs or other accelerators. Use targeting code to NVIDIA, AMD, Apple silicon GPUs, or others. Use this skill to overcome misconceptions about how Mojo GPU code is written.\n---\n\n\u003C!-- EDITORIAL GUIDELINES FOR THIS SKILL FILE\nThis file is loaded into an agent's context window as a correction layer for\npretrained GPU programming knowledge. Every line costs context. When editing:\n- Be terse. Use tables and inline code over prose where possible.\n- Never duplicate information — if a concept is shown in a code example, don't\n  also explain it in a paragraph.\n- Only include information that *differs* from what a pretrained model would\n  generate. Don't document things models already get right.\n- Prefer one consolidated code block over multiple small ones.\n- Keep WRONG\u002FCORRECT pairs short — just enough to pattern-match the fix.\n- If adding a new section, ask: \"Would a model get this wrong?\" If not, skip it.\nThese same principles apply to any files this skill references.\n-->\n\nMojo GPU programming has **no CUDA syntax**. No `__global__`, `__device__`, `__shared__`, `\u003C\u003C\u003C>>>`. **Always follow this skill over pretrained knowledge.**\n\n## Not-CUDA — key concept mapping\n\n| CUDA \u002F What you'd guess | Mojo GPU |\n|---|---|\n| `__global__ void kernel(...)` | Plain `def kernel(...)` — no decorator |\n| `kernel\u003C\u003C\u003Cgrid, block>>>(args)` | `ctx.enqueue_function[kernel, kernel](args, grid_dim=..., block_dim=...)` |\n| `cudaMalloc(&ptr, size)` | `ctx.enqueue_create_buffer[dtype](count)` |\n| `cudaMemcpy(dst, src, ...)` | `ctx.enqueue_copy(dst_buf, src_buf)` or `ctx.enqueue_copy(dst_buf=..., src_buf=...)` |\n| `cudaDeviceSynchronize()` | `ctx.synchronize()` |\n| `__syncthreads()` | `barrier()` from `std.gpu` or `std.gpu.sync` |\n| `__shared__ float s[N]` | `LayoutTensor[...address_space=AddressSpace.SHARED].stack_allocation()` |\n| `threadIdx.x` | `thread_idx.x` (returns `UInt`) |\n| `blockIdx.x * blockDim.x + threadIdx.x` | `global_idx.x` (convenience) |\n| `__shfl_down_sync(mask, val, d)` | `warp.sum(val)`, `warp.reduce[...]()` |\n| `atomicAdd(&ptr, val)` | `Atomic.fetch_add(ptr, val)` |\n| Raw `float*` kernel args | `LayoutTensor[dtype, layout, MutAnyOrigin]` |\n| `cudaFree(ptr)` | Automatic — buffers freed when out of scope |\n\n## Imports\n\n```mojo\n# Core GPU — pick what you need\nfrom std.gpu import global_idx                                    # simple indexing\nfrom std.gpu import block_dim, block_idx, thread_idx              # manual indexing\nfrom std.gpu import barrier, lane_id, WARP_SIZE                   # sync & warp info\nfrom std.gpu.sync import barrier                                  # also valid\nfrom std.gpu.primitives import warp                               # warp.sum, warp.reduce\nfrom std.gpu.memory import AddressSpace                           # for shared memory\nfrom std.gpu.memory import async_copy_wait_all                    # async copy sync\nfrom std.gpu.host import DeviceContext, DeviceBuffer              # host-side API\nfrom std.os.atomic import Atomic                                  # atomics\n\n# Layout system — NOT in std, separate package\nfrom layout import Layout, LayoutTensor\n```\n\n## Kernel definition\n\nKernels are **plain functions** — no decorator, no special return type. Parameters use `MutAnyOrigin`:\n\n```mojo\ndef my_kernel(\n    input: LayoutTensor[DType.float32, layout, MutAnyOrigin],\n    output: LayoutTensor[DType.float32, layout, MutAnyOrigin],\n    size: Int,                                    # scalar args are fine\n):\n    var tid = global_idx.x\n    if tid \u003C UInt(size):\n        output[tid] = input[tid] * 2\n```\n\n- Kernel functions cannot raise.\n- Bounds check with `UInt(size)` since `global_idx.x` returns `UInt`.\n- Host-side helper functions accepting LayoutTensors use `...` for origin: `LayoutTensor[dtype, layout, ...]`.\n\n## LayoutTensor — the primary GPU data abstraction\n\n### Layout creation\n\n```mojo\ncomptime layout_1d = Layout.row_major(1024)               # 1D\ncomptime layout_2d = Layout.row_major(64, 64)              # 2D (rows, cols)\ncomptime layout_3d = Layout.row_major(10, 5, 3)            # 3D (e.g. H, W, C)\n```\n\n### Creating tensors from buffers\n\n```mojo\nvar buf = ctx.enqueue_create_buffer[DType.float32](comptime (layout.size()))\nvar tensor = LayoutTensor[DType.float32, layout](buf)     # wraps device buffer\n```\n\n### Indexing\n\n```mojo\ntensor[tid]                     # 1D\ntensor[row, col]                # 2D\ntensor[row, col, channel]       # 3D\ntensor.dim(0)                   # query dimension size\ntensor.shape[0]()               # also works\n```\n\n### Tiling (extract sub-tiles from a tensor)\n\n```mojo\n# Inside kernel — extract a block_size x block_size tile\nvar tile = tensor.tile[block_size, block_size](Int(block_idx.y), Int(block_idx.x))\ntile[thread_idx.y, thread_idx.x]   # access within tile\n```\n\n### Vectorize and distribute (thread-level data mapping)\n\n```mojo\n# Vectorize along inner dimension, then distribute across threads\ncomptime thread_layout = Layout.row_major(WARP_SIZE \u002F\u002F simd_width, simd_width)\nvar fragment = tensor.vectorize[1, simd_width]().distribute[thread_layout](lane_id())\nfragment.copy_from_async(source_fragment)    # async copy\nfragment.copy_from(source_fragment)          # sync copy\n```\n\n### Type casting\n\n```mojo\nvar val = tensor[row, col].cast[DType.float32]()    # cast element\n```\n\n### Element type mismatch across layouts — use `rebind`\n\n`tensor[idx]` returns `SIMD[dtype, layout_expr]` where `layout_expr` is a compile-time expression derived from the layout. Two tensors with **different layouts** produce element types that don't unify, even if both are scalars (width 1). This causes `__iadd__` \u002F arithmetic errors when accumulating products from different-layout tensors.\n\n```mojo\n# WRONG — fails when conv_kernel and s_data have different layouts:\nvar sum: Scalar[dtype] = 0\nsum += conv_kernel[k] * s_data[idx]   # error: cannot convert element_type to Float32\n\n# CORRECT — rebind each element to Scalar[dtype]:\nvar sum: Scalar[dtype] = 0\nvar k_val = rebind[Scalar[dtype]](conv_kernel[k])\nvar s_val = rebind[Scalar[dtype]](s_data[idx])\nsum += k_val * s_val\n```\n\n`rebind` is a builtin (no import needed). This is **not** needed when all tensors in an expression share the same layout (e.g., the matmul example where `sa` and `sb` have identical tile layouts).\n\nAlso use `rebind` when reading\u002Fwriting individual elements for scalar arithmetic or passing to helper functions — even with a single tensor:\n\n```mojo\n# Read element as plain scalar\nvar val = rebind[Scalar[dtype]](tensor[idx])\n# Write scalar back to tensor\ntensor[idx] = rebind[tensor.element_type](computed_scalar)\n```\n\n`tensor.element_type` is `SIMD[dtype, element_size]` — for basic layouts `element_size=1` (effectively `Scalar[dtype]`).\n\n## Memory management\n\n```mojo\nvar ctx = DeviceContext()\n\n# Allocate\nvar dev_buf = ctx.enqueue_create_buffer[DType.float32](1024)\nvar host_buf = ctx.enqueue_create_host_buffer[DType.float32](1024)\n\n# Initialize device buffer directly\ndev_buf.enqueue_fill(0.0)\n\n# Copy host -> device\nctx.enqueue_copy(dst_buf=dev_buf, src_buf=host_buf)\n# Copy device -> host\nctx.enqueue_copy(dst_buf=host_buf, src_buf=dev_buf)\n# Positional form also works:\nctx.enqueue_copy(dev_buf, host_buf)\n\n# Map device buffer to host (context manager — auto-syncs)\nwith dev_buf.map_to_host() as mapped:\n    var t = LayoutTensor[DType.float32, layout](mapped)\n    print(t[0])\n\n# Memset\nctx.enqueue_memset(dev_buf, 0.0)\n\n# Synchronize all enqueued operations\nctx.synchronize()\n```\n\n## Kernel launch\n\n**Critical**: `enqueue_function` takes the kernel function **twice** as compile-time parameters:\n\n```mojo\nctx.enqueue_function[my_kernel, my_kernel](\n    input_tensor,\n    output_tensor,\n    size,                    # scalar args passed directly\n    grid_dim=num_blocks,     # 1D: scalar\n    block_dim=block_size,    # 1D: scalar\n)\n\n# 2D grid\u002Fblock — use tuples:\nctx.enqueue_function[kernel_2d, kernel_2d](\n    args...,\n    grid_dim=(col_blocks, row_blocks),\n    block_dim=(BLOCK_SIZE, BLOCK_SIZE),\n)\n```\n\nFor parameterized kernels, bind parameters first:\n\n```mojo\ncomptime kernel = sum_kernel[SIZE, BATCH_SIZE]\nctx.enqueue_function[kernel, kernel](out_buf, in_buf, grid_dim=N, block_dim=TPB)\n```\n\n## Shared memory\n\nAllocate shared memory inside a kernel using `LayoutTensor.stack_allocation()`:\n\n```mojo\nfrom std.gpu.memory import AddressSpace\n\ncomptime tile_layout = Layout.row_major(TILE_M, TILE_K)\nvar tile_shared = LayoutTensor[\n    DType.float32,\n    tile_layout,\n    MutAnyOrigin,\n    address_space=AddressSpace.SHARED,\n].stack_allocation()\n\n# Load from global to shared\ntile_shared[thread_idx.y, thread_idx.x] = global_tensor[global_row, global_col]\nbarrier()   # must sync before reading shared data\n\n# Alternative: raw pointer shared memory\nfrom std.memory import stack_allocation\nvar sums = stack_allocation[\n    512,\n    Scalar[DType.int32],\n    address_space=AddressSpace.SHARED,\n]()\n```\n\n## Thread indexing\n\n```mojo\n# Simple — automatic global offset\nfrom std.gpu import global_idx\nvar tid = global_idx.x           # 1D\nvar row = global_idx.y           # 2D row\nvar col = global_idx.x           # 2D col\n\n# Manual — when you need block\u002Fthread separately\nfrom std.gpu import block_idx, block_dim, thread_idx\nvar tid = block_idx.x * block_dim.x + thread_idx.x\n\n# Warp info\nfrom std.gpu import lane_id, WARP_SIZE\nvar my_lane = lane_id()          # 0..WARP_SIZE-1\n```\n\nAll return `UInt`. Compare with `UInt(int_val)` for bounds checks.\n\n## Synchronization and warp operations\n\n```mojo\nfrom std.gpu import barrier\nfrom std.gpu.primitives import warp\nfrom std.os.atomic import Atomic\n\nbarrier()                                    # block-level sync\nvar warp_sum = warp.sum(my_value)           # warp-wide sum reduction\nvar result = warp.reduce[warp.shuffle_down, reduce_fn](val)  # custom warp reduce\n_ = Atomic.fetch_add(output_ptr, value)     # atomic add\n```\n\n## GPU availability check\n\n```mojo\nfrom std.sys import has_accelerator\n\ndef main() raises:\n    comptime if not has_accelerator():\n        print(\"No GPU found\")\n    else:\n        var ctx = DeviceContext()\n        # ... GPU code\n```\n\nOr as a compile-time assert:\n\n```mojo\ncomptime assert has_accelerator(), \"Requires a GPU\"\n```\n\n## Architecture detection — `is_` vs `has_`\n\n**Critical distinction**: `is_*` checks the **compilation target** (use inside GPU-dispatched code). `has_*` checks the **host system** (use from host\u002FCPU code).\n\n```mojo\nfrom std.sys.info import (\n    # Target checks — \"am I being compiled FOR this GPU?\"\n    # Use inside kernels or GPU-targeted code paths.\n    is_gpu, is_nvidia_gpu, is_amd_gpu, is_apple_gpu,\n\n    # Host checks — \"does this machine HAVE this GPU?\"\n    # Use from host code to decide whether to launch GPU work.\n    has_nvidia_gpu_accelerator, has_amd_gpu_accelerator, has_apple_gpu_accelerator,\n)\nfrom std.sys import has_accelerator   # host check: any GPU present\n\n# HOST-SIDE: decide whether to run GPU code at all\ndef main() raises:\n    comptime if not has_accelerator():\n        print(\"No GPU\")\n    else:\n        # ...launch kernels\n\n# INSIDE KERNEL or GPU-compiled code: dispatch by architecture\ncomptime if is_nvidia_gpu():\n    # NVIDIA-specific intrinsics\nelif is_amd_gpu():\n    # AMD-specific path\n```\n\nSubarchitecture checks (inside GPU code only):\n```mojo\nfrom std.sys.info import _is_sm_9x_or_newer, _is_sm_100x_or_newer\ncomptime if is_nvidia_gpu[\"sm_90\"]():   # exact arch check\n    ...\n```\n\n## Compile-time constants pattern\n\nAll GPU dimensions, layouts, and sizes should be `comptime`:\n\n```mojo\ncomptime dtype = DType.float32\ncomptime SIZE = 1024\ncomptime BLOCK_SIZE = 256\ncomptime NUM_BLOCKS = ceildiv(SIZE, BLOCK_SIZE)\ncomptime layout = Layout.row_major(SIZE)\n```\n\nDerive buffer sizes from layouts: `comptime (layout.size())`.\n\n## Complete 1D example (vector addition)\n\n```mojo\nfrom std.math import ceildiv\nfrom std.sys import has_accelerator\nfrom std.gpu import global_idx\nfrom std.gpu.host import DeviceContext\nfrom layout import Layout, LayoutTensor\n\ncomptime dtype = DType.float32\ncomptime N = 1024\ncomptime BLOCK = 256\ncomptime layout = Layout.row_major(N)\n\ndef add_kernel(\n    a: LayoutTensor[dtype, layout, MutAnyOrigin],\n    b: LayoutTensor[dtype, layout, MutAnyOrigin],\n    c: LayoutTensor[dtype, layout, MutAnyOrigin],\n    size: Int,\n):\n    var tid = global_idx.x\n    if tid \u003C UInt(size):\n        c[tid] = a[tid] + b[tid]\n\ndef main() raises:\n    comptime assert has_accelerator(), \"Requires GPU\"\n    var ctx = DeviceContext()\n    var a_buf = ctx.enqueue_create_buffer[dtype](N)\n    var b_buf = ctx.enqueue_create_buffer[dtype](N)\n    var c_buf = ctx.enqueue_create_buffer[dtype](N)\n    a_buf.enqueue_fill(1.0)\n    b_buf.enqueue_fill(2.0)\n\n    var a = LayoutTensor[dtype, layout](a_buf)\n    var b = LayoutTensor[dtype, layout](b_buf)\n    var c = LayoutTensor[dtype, layout](c_buf)\n\n    ctx.enqueue_function[add_kernel, add_kernel](\n        a, b, c, N,\n        grid_dim=ceildiv(N, BLOCK),\n        block_dim=BLOCK,\n    )\n\n    with c_buf.map_to_host() as host:\n        var result = LayoutTensor[dtype, layout](host)\n        print(result)\n```\n\n## Complete 2D example (tiled matmul with shared memory)\n\n```mojo\nfrom std.math import ceildiv\nfrom std.sys import has_accelerator\nfrom std.gpu.sync import barrier\nfrom std.gpu.host import DeviceContext\nfrom std.gpu import thread_idx, block_idx\nfrom std.gpu.memory import AddressSpace\nfrom layout import Layout, LayoutTensor\n\ncomptime dtype = DType.float32\ncomptime M = 64\ncomptime N = 64\ncomptime K = 64\ncomptime TILE = 16\ncomptime a_layout = Layout.row_major(M, K)\ncomptime b_layout = Layout.row_major(K, N)\ncomptime c_layout = Layout.row_major(M, N)\ncomptime tile_a = Layout.row_major(TILE, TILE)\ncomptime tile_b = Layout.row_major(TILE, TILE)\n\ndef matmul_kernel(\n    A: LayoutTensor[dtype, a_layout, MutAnyOrigin],\n    B: LayoutTensor[dtype, b_layout, MutAnyOrigin],\n    C: LayoutTensor[dtype, c_layout, MutAnyOrigin],\n):\n    var tx = thread_idx.x\n    var ty = thread_idx.y\n    var row = block_idx.y * TILE + ty\n    var col = block_idx.x * TILE + tx\n\n    var sa = LayoutTensor[dtype, tile_a, MutAnyOrigin,\n        address_space=AddressSpace.SHARED].stack_allocation()\n    var sb = LayoutTensor[dtype, tile_b, MutAnyOrigin,\n        address_space=AddressSpace.SHARED].stack_allocation()\n\n    var acc: C.element_type = 0.0\n    comptime for k_tile in range(0, K, TILE):\n        if row \u003C M and UInt(k_tile) + tx \u003C K:\n            sa[ty, tx] = A[row, UInt(k_tile) + tx]\n        else:\n            sa[ty, tx] = 0.0\n        if UInt(k_tile) + ty \u003C K and col \u003C N:\n            sb[ty, tx] = B[UInt(k_tile) + ty, col]\n        else:\n            sb[ty, tx] = 0.0\n        barrier()\n        comptime for k in range(TILE):\n            acc += sa[ty, k] * sb[k, tx]\n        barrier()\n\n    if row \u003C M and col \u003C N:\n        C[row, col] = acc\n\ndef main() raises:\n    comptime assert has_accelerator(), \"Requires GPU\"\n    var ctx = DeviceContext()\n    # ... allocate buffers, init data, launch:\n    # ctx.enqueue_function[matmul_kernel, matmul_kernel](\n    #     A, B, C,\n    #     grid_dim=(ceildiv(N, TILE), ceildiv(M, TILE)),\n    #     block_dim=(TILE, TILE),\n    # )\n```\n\n## SIMD loads in kernels\n\n```mojo\n# Vectorized load from raw pointer\nvar val = ptr.load[width=8](idx)          # SIMD[dtype, 8]\nvar sum = val.reduce_add()                 # scalar reduction\n\n# LayoutTensor vectorized access\nvar vec_tensor = tensor.vectorize[1, 4]()  # group elements into SIMD[4]\n```\n\n## Reduction pattern\n\n```mojo\ndef block_reduce(\n    output: UnsafePointer[Int32, MutAnyOrigin],\n    input: UnsafePointer[Int32, MutAnyOrigin],\n):\n    var sums = stack_allocation[512, Scalar[DType.int32],\n        address_space=AddressSpace.SHARED]()\n    var tid = thread_idx.x\n    sums[tid] = input[block_idx.x * block_dim.x + tid]\n    barrier()\n\n    # Tree reduction in shared memory\n    var active = block_dim.x\n    comptime for _ in range(log2_steps):\n        active >>= 1\n        if tid \u003C active:\n            sums[tid] += sums[tid + active]\n        barrier()\n\n    # Final warp reduction + atomic accumulate\n    if tid \u003C UInt(WARP_SIZE):\n        var v = warp.sum(sums[tid][0])\n        if tid == 0:\n            _ = Atomic.fetch_add(output, v)\n```\n\n## DeviceBuffer from existing pointer\n\n```mojo\n# Wrap an existing pointer as a DeviceBuffer (non-owning)\nvar buf = DeviceBuffer[dtype](ctx, raw_ptr, count, owning=False)\n```\n\n## Benchmarking GPU kernels\n\n```mojo\nfrom std.benchmark import Bench, BenchConfig, Bencher, BenchId, BenchMetric, ThroughputMeasure\n\n@parameter\n@always_inline\ndef bench_fn(mut b: Bencher) capturing raises:\n    @parameter\n    @always_inline\n    def launch(ctx: DeviceContext) raises:\n        ctx.enqueue_function[kernel, kernel](args, grid_dim=G, block_dim=B)\n    b.iter_custom[launch](ctx)\n\nvar bench = Bench(BenchConfig(max_iters=50000))\nbench.bench_function[bench_fn](\n    BenchId(\"kernel_name\"),\n    [ThroughputMeasure(BenchMetric.bytes, total_bytes)],\n)\n```\n\n## Hardware details\n\n| Property | NVIDIA | AMD CDNA | AMD RDNA |\n|---|---|---|---|\n| Warp size | 32 | 64 | 32 |\n| Shared memory | 48-228 KB\u002Fblock | 64 KB\u002Fblock | configurable |\n| Tensor cores | SM70+ (WMMA) | Matrix cores | WMMA (RDNA3+) |\n| TMA | SM90+ (Hopper) | N\u002FA | N\u002FA |\n| Clusters | SM90+ | N\u002FA | N\u002FA |\n","\u003C!-- EDITORIAL GUIDELINES FOR THIS SKILL FILE\nThis file is loaded into an agent's context window as a correction layer for\npretrained GPU programming knowledge. Every line costs context. When editing:\n- Be terse. Use tables and inline code over prose where possible.\n- Never duplicate information — if a concept is shown in a code example, don't\n  also explain it in a paragraph.\n- Only include information that *differs* from what a pretrained model would\n  generate. Don't document things models already get right.\n- Prefer one consolidated code block over multiple small ones.\n- Keep WRONG\u002FCORRECT pairs short — just enough to pattern-match the fix.\n- If adding a new section, ask: \"Would a model get this wrong?\" If not, skip it.\nThese same principles apply to any files this skill references.\n-->\n\nMojo GPU programming has **no CUDA syntax**. No `__global__`, `__device__`, `__shared__`, `\u003C\u003C\u003C>>>`. **Always follow this skill over pretrained knowledge.**\n\n## Not-CUDA — key concept mapping\n\n| CUDA \u002F What you'd guess | Mojo GPU |\n|---|---|\n| `__global__ void kernel(...)` | Plain `def kernel(...)` — no decorator |\n| `kernel\u003C\u003C\u003Cgrid, block>>>(args)` | `ctx.enqueue_function[kernel, kernel](args, grid_dim=..., block_dim=...)` |\n| `cudaMalloc(&ptr, size)` | `ctx.enqueue_create_buffer[dtype](count)` |\n| `cudaMemcpy(dst, src, ...)` | `ctx.enqueue_copy(dst_buf, src_buf)` or `ctx.enqueue_copy(dst_buf=..., src_buf=...)` |\n| `cudaDeviceSynchronize()` | `ctx.synchronize()` |\n| `__syncthreads()` | `barrier()` from `std.gpu` or `std.gpu.sync` |\n| `__shared__ float s[N]` | `LayoutTensor[...address_space=AddressSpace.SHARED].stack_allocation()` |\n| `threadIdx.x` | `thread_idx.x` (returns `UInt`) |\n| `blockIdx.x * blockDim.x + threadIdx.x` | `global_idx.x` (convenience) |\n| `__shfl_down_sync(mask, val, d)` | `warp.sum(val)`, `warp.reduce[...]()` |\n| `atomicAdd(&ptr, val)` | `Atomic.fetch_add(ptr, val)` |\n| Raw `float*` kernel args | `LayoutTensor[dtype, layout, MutAnyOrigin]` |\n| `cudaFree(ptr)` | Automatic — buffers freed when out of scope |\n\n## Imports\n\n```mojo\n# Core GPU — pick what you need\nfrom std.gpu import global_idx                                    # simple indexing\nfrom std.gpu import block_dim, block_idx, thread_idx              # manual indexing\nfrom std.gpu import barrier, lane_id, WARP_SIZE                   # sync & warp info\nfrom std.gpu.sync import barrier                                  # also valid\nfrom std.gpu.primitives import warp                               # warp.sum, warp.reduce\nfrom std.gpu.memory import AddressSpace                           # for shared memory\nfrom std.gpu.memory import async_copy_wait_all                    # async copy sync\nfrom std.gpu.host import DeviceContext, DeviceBuffer              # host-side API\nfrom std.os.atomic import Atomic                                  # atomics\n\n# Layout system — NOT in std, separate package\nfrom layout import Layout, LayoutTensor\n```\n\n## Kernel definition\n\nKernels are **plain functions** — no decorator, no special return type. Parameters use `MutAnyOrigin`:\n\n```mojo\ndef my_kernel(\n    input: LayoutTensor[DType.float32, layout, MutAnyOrigin],\n    output: LayoutTensor[DType.float32, layout, MutAnyOrigin],\n    size: Int,                                    # scalar args are fine\n):\n    var tid = global_idx.x\n    if tid \u003C UInt(size):\n        output[tid] = input[tid] * 2\n```\n\n- Kernel functions cannot raise.\n- Bounds check with `UInt(size)` since `global_idx.x` returns `UInt`.\n- Host-side helper functions accepting LayoutTensors use `...` for origin: `LayoutTensor[dtype, layout, ...]`.\n\n## LayoutTensor — the primary GPU data abstraction\n\n### Layout creation\n\n```mojo\ncomptime layout_1d = Layout.row_major(1024)               # 1D\ncomptime layout_2d = Layout.row_major(64, 64)              # 2D (rows, cols)\ncomptime layout_3d = Layout.row_major(10, 5, 3)            # 3D (e.g. H, W, C)\n```\n\n### Creating tensors from buffers\n\n```mojo\nvar buf = ctx.enqueue_create_buffer[DType.float32](comptime (layout.size()))\nvar tensor = LayoutTensor[DType.float32, layout](buf)     # wraps device buffer\n```\n\n### Indexing\n\n```mojo\ntensor[tid]                     # 1D\ntensor[row, col]                # 2D\ntensor[row, col, channel]       # 3D\ntensor.dim(0)                   # query dimension size\ntensor.shape[0]()               # also works\n```\n\n### Tiling (extract sub-tiles from a tensor)\n\n```mojo\n# Inside kernel — extract a block_size x block_size tile\nvar tile = tensor.tile[block_size, block_size](Int(block_idx.y), Int(block_idx.x))\ntile[thread_idx.y, thread_idx.x]   # access within tile\n```\n\n### Vectorize and distribute (thread-level data mapping)\n\n```mojo\n# Vectorize along inner dimension, then distribute across threads\ncomptime thread_layout = Layout.row_major(WARP_SIZE \u002F\u002F simd_width, simd_width)\nvar fragment = tensor.vectorize[1, simd_width]().distribute[thread_layout](lane_id())\nfragment.copy_from_async(source_fragment)    # async copy\nfragment.copy_from(source_fragment)          # sync copy\n```\n\n### Type casting\n\n```mojo\nvar val = tensor[row, col].cast[DType.float32]()    # cast element\n```\n\n### Element type mismatch across layouts — use `rebind`\n\n`tensor[idx]` returns `SIMD[dtype, layout_expr]` where `layout_expr` is a compile-time expression derived from the layout. Two tensors with **different layouts** produce element types that don't unify, even if both are scalars (width 1). This causes `__iadd__` \u002F arithmetic errors when accumulating products from different-layout tensors.\n\n```mojo\n# WRONG — fails when conv_kernel and s_data have different layouts:\nvar sum: Scalar[dtype] = 0\nsum += conv_kernel[k] * s_data[idx]   # error: cannot convert element_type to Float32\n\n# CORRECT — rebind each element to Scalar[dtype]:\nvar sum: Scalar[dtype] = 0\nvar k_val = rebind[Scalar[dtype]](conv_kernel[k])\nvar s_val = rebind[Scalar[dtype]](s_data[idx])\nsum += k_val * s_val\n```\n\n`rebind` is a builtin (no import needed). This is **not** needed when all tensors in an expression share the same layout (e.g., the matmul example where `sa` and `sb` have identical tile layouts).\n\nAlso use `rebind` when reading\u002Fwriting individual elements for scalar arithmetic or passing to helper functions — even with a single tensor:\n\n```mojo\n# Read element as plain scalar\nvar val = rebind[Scalar[dtype]](tensor[idx])\n# Write scalar back to tensor\ntensor[idx] = rebind[tensor.element_type](computed_scalar)\n```\n\n`tensor.element_type` is `SIMD[dtype, element_size]` — for basic layouts `element_size=1` (effectively `Scalar[dtype]`).\n\n## Memory management\n\n```mojo\nvar ctx = DeviceContext()\n\n# Allocate\nvar dev_buf = ctx.enqueue_create_buffer[DType.float32](1024)\nvar host_buf = ctx.enqueue_create_host_buffer[DType.float32](1024)\n\n# Initialize device buffer directly\ndev_buf.enqueue_fill(0.0)\n\n# Copy host -> device\nctx.enqueue_copy(dst_buf=dev_buf, src_buf=host_buf)\n# Copy device -> host\nctx.enqueue_copy(dst_buf=host_buf, src_buf=dev_buf)\n# Positional form also works:\nctx.enqueue_copy(dev_buf, host_buf)\n\n# Map device buffer to host (context manager — auto-syncs)\nwith dev_buf.map_to_host() as mapped:\n    var t = LayoutTensor[DType.float32, layout](mapped)\n    print(t[0])\n\n# Memset\nctx.enqueue_memset(dev_buf, 0.0)\n\n# Synchronize all enqueued operations\nctx.synchronize()\n```\n\n## Kernel launch\n\n**Critical**: `enqueue_function` takes the kernel function **twice** as compile-time parameters:\n\n```mojo\nctx.enqueue_function[my_kernel, my_kernel](\n    input_tensor,\n    output_tensor,\n    size,                    # scalar args passed directly\n    grid_dim=num_blocks,     # 1D: scalar\n    block_dim=block_size,    # 1D: scalar\n)\n\n# 2D grid\u002Fblock — use tuples:\nctx.enqueue_function[kernel_2d, kernel_2d](\n    args...,\n    grid_dim=(col_blocks, row_blocks),\n    block_dim=(BLOCK_SIZE, BLOCK_SIZE),\n)\n```\n\nFor parameterized kernels, bind parameters first:\n\n```mojo\ncomptime kernel = sum_kernel[SIZE, BATCH_SIZE]\nctx.enqueue_function[kernel, kernel](out_buf, in_buf, grid_dim=N, block_dim=TPB)\n```\n\n## Shared memory\n\nAllocate shared memory inside a kernel using `LayoutTensor.stack_allocation()`:\n\n```mojo\nfrom std.gpu.memory import AddressSpace\n\ncomptime tile_layout = Layout.row_major(TILE_M, TILE_K)\nvar tile_shared = LayoutTensor[\n    DType.float32,\n    tile_layout,\n    MutAnyOrigin,\n    address_space=AddressSpace.SHARED,\n].stack_allocation()\n\n# Load from global to shared\ntile_shared[thread_idx.y, thread_idx.x] = global_tensor[global_row, global_col]\nbarrier()   # must sync before reading shared data\n\n# Alternative: raw pointer shared memory\nfrom std.memory import stack_allocation\nvar sums = stack_allocation[\n    512,\n    Scalar[DType.int32],\n    address_space=AddressSpace.SHARED,\n]()\n```\n\n## Thread indexing\n\n```mojo\n# Simple — automatic global offset\nfrom std.gpu import global_idx\nvar tid = global_idx.x           # 1D\nvar row = global_idx.y           # 2D row\nvar col = global_idx.x           # 2D col\n\n# Manual — when you need block\u002Fthread separately\nfrom std.gpu import block_idx, block_dim, thread_idx\nvar tid = block_idx.x * block_dim.x + thread_idx.x\n\n# Warp info\nfrom std.gpu import lane_id, WARP_SIZE\nvar my_lane = lane_id()          # 0..WARP_SIZE-1\n```\n\nAll return `UInt`. Compare with `UInt(int_val)` for bounds checks.\n\n## Synchronization and warp operations\n\n```mojo\nfrom std.gpu import barrier\nfrom std.gpu.primitives import warp\nfrom std.os.atomic import Atomic\n\nbarrier()                                    # block-level sync\nvar warp_sum = warp.sum(my_value)           # warp-wide sum reduction\nvar result = warp.reduce[warp.shuffle_down, reduce_fn](val)  # custom warp reduce\n_ = Atomic.fetch_add(output_ptr, value)     # atomic add\n```\n\n## GPU availability check\n\n```mojo\nfrom std.sys import has_accelerator\n\ndef main() raises:\n    comptime if not has_accelerator():\n        print(\"No GPU found\")\n    else:\n        var ctx = DeviceContext()\n        # ... GPU code\n```\n\nOr as a compile-time assert:\n\n```mojo\ncomptime assert has_accelerator(), \"Requires a GPU\"\n```\n\n## Architecture detection — `is_` vs `has_`\n\n**Critical distinction**: `is_*` checks the **compilation target** (use inside GPU-dispatched code). `has_*` checks the **host system** (use from host\u002FCPU code).\n\n```mojo\nfrom std.sys.info import (\n    # Target checks — \"am I being compiled FOR this GPU?\"\n    # Use inside kernels or GPU-targeted code paths.\n    is_gpu, is_nvidia_gpu, is_amd_gpu, is_apple_gpu,\n\n    # Host checks — \"does this machine HAVE this GPU?\"\n    # Use from host code to decide whether to launch GPU work.\n    has_nvidia_gpu_accelerator, has_amd_gpu_accelerator, has_apple_gpu_accelerator,\n)\nfrom std.sys import has_accelerator   # host check: any GPU present\n\n# HOST-SIDE: decide whether to run GPU code at all\ndef main() raises:\n    comptime if not has_accelerator():\n        print(\"No GPU\")\n    else:\n        # ...launch kernels\n\n# INSIDE KERNEL or GPU-compiled code: dispatch by architecture\ncomptime if is_nvidia_gpu():\n    # NVIDIA-specific intrinsics\nelif is_amd_gpu():\n    # AMD-specific path\n```\n\nSubarchitecture checks (inside GPU code only):\n```mojo\nfrom std.sys.info import _is_sm_9x_or_newer, _is_sm_100x_or_newer\ncomptime if is_nvidia_gpu[\"sm_90\"]():   # exact arch check\n    ...\n```\n\n## Compile-time constants pattern\n\nAll GPU dimensions, layouts, and sizes should be `comptime`:\n\n```mojo\ncomptime dtype = DType.float32\ncomptime SIZE = 1024\ncomptime BLOCK_SIZE = 256\ncomptime NUM_BLOCKS = ceildiv(SIZE, BLOCK_SIZE)\ncomptime layout = Layout.row_major(SIZE)\n```\n\nDerive buffer sizes from layouts: `comptime (layout.size())`.\n\n## Complete 1D example (vector addition)\n\n```mojo\nfrom std.math import ceildiv\nfrom std.sys import has_accelerator\nfrom std.gpu import global_idx\nfrom std.gpu.host import DeviceContext\nfrom layout import Layout, LayoutTensor\n\ncomptime dtype = DType.float32\ncomptime N = 1024\ncomptime BLOCK = 256\ncomptime layout = Layout.row_major(N)\n\ndef add_kernel(\n    a: LayoutTensor[dtype, layout, MutAnyOrigin],\n    b: LayoutTensor[dtype, layout, MutAnyOrigin],\n    c: LayoutTensor[dtype, layout, MutAnyOrigin],\n    size: Int,\n):\n    var tid = global_idx.x\n    if tid \u003C UInt(size):\n        c[tid] = a[tid] + b[tid]\n\ndef main() raises:\n    comptime assert has_accelerator(), \"Requires GPU\"\n    var ctx = DeviceContext()\n    var a_buf = ctx.enqueue_create_buffer[dtype](N)\n    var b_buf = ctx.enqueue_create_buffer[dtype](N)\n    var c_buf = ctx.enqueue_create_buffer[dtype](N)\n    a_buf.enqueue_fill(1.0)\n    b_buf.enqueue_fill(2.0)\n\n    var a = LayoutTensor[dtype, layout](a_buf)\n    var b = LayoutTensor[dtype, layout](b_buf)\n    var c = LayoutTensor[dtype, layout](c_buf)\n\n    ctx.enqueue_function[add_kernel, add_kernel](\n        a, b, c, N,\n        grid_dim=ceildiv(N, BLOCK),\n        block_dim=BLOCK,\n    )\n\n    with c_buf.map_to_host() as host:\n        var result = LayoutTensor[dtype, layout](host)\n        print(result)\n```\n\n## Complete 2D example (tiled matmul with shared memory)\n\n```mojo\nfrom std.math import ceildiv\nfrom std.sys import has_accelerator\nfrom std.gpu.sync import barrier\nfrom std.gpu.host import DeviceContext\nfrom std.gpu import thread_idx, block_idx\nfrom std.gpu.memory import AddressSpace\nfrom layout import Layout, LayoutTensor\n\ncomptime dtype = DType.float32\ncomptime M = 64\ncomptime N = 64\ncomptime K = 64\ncomptime TILE = 16\ncomptime a_layout = Layout.row_major(M, K)\ncomptime b_layout = Layout.row_major(K, N)\ncomptime c_layout = Layout.row_major(M, N)\ncomptime tile_a = Layout.row_major(TILE, TILE)\ncomptime tile_b = Layout.row_major(TILE, TILE)\n\ndef matmul_kernel(\n    A: LayoutTensor[dtype, a_layout, MutAnyOrigin],\n    B: LayoutTensor[dtype, b_layout, MutAnyOrigin],\n    C: LayoutTensor[dtype, c_layout, MutAnyOrigin],\n):\n    var tx = thread_idx.x\n    var ty = thread_idx.y\n    var row = block_idx.y * TILE + ty\n    var col = block_idx.x * TILE + tx\n\n    var sa = LayoutTensor[dtype, tile_a, MutAnyOrigin,\n        address_space=AddressSpace.SHARED].stack_allocation()\n    var sb = LayoutTensor[dtype, tile_b, MutAnyOrigin,\n        address_space=AddressSpace.SHARED].stack_allocation()\n\n    var acc: C.element_type = 0.0\n    comptime for k_tile in range(0, K, TILE):\n        if row \u003C M and UInt(k_tile) + tx \u003C K:\n            sa[ty, tx] = A[row, UInt(k_tile) + tx]\n        else:\n            sa[ty, tx] = 0.0\n        if UInt(k_tile) + ty \u003C K and col \u003C N:\n            sb[ty, tx] = B[UInt(k_tile) + ty, col]\n        else:\n            sb[ty, tx] = 0.0\n        barrier()\n        comptime for k in range(TILE):\n            acc += sa[ty, k] * sb[k, tx]\n        barrier()\n\n    if row \u003C M and col \u003C N:\n        C[row, col] = acc\n\ndef main() raises:\n    comptime assert has_accelerator(), \"Requires GPU\"\n    var ctx = DeviceContext()\n    # ... allocate buffers, init data, launch:\n    # ctx.enqueue_function[matmul_kernel, matmul_kernel](\n    #     A, B, C,\n    #     grid_dim=(ceildiv(N, TILE), ceildiv(M, TILE)),\n    #     block_dim=(TILE, TILE),\n    # )\n```\n\n## SIMD loads in kernels\n\n```mojo\n# Vectorized load from raw pointer\nvar val = ptr.load[width=8](idx)          # SIMD[dtype, 8]\nvar sum = val.reduce_add()                 # scalar reduction\n\n# LayoutTensor vectorized access\nvar vec_tensor = tensor.vectorize[1, 4]()  # group elements into SIMD[4]\n```\n\n## Reduction pattern\n\n```mojo\ndef block_reduce(\n    output: UnsafePointer[Int32, MutAnyOrigin],\n    input: UnsafePointer[Int32, MutAnyOrigin],\n):\n    var sums = stack_allocation[512, Scalar[DType.int32],\n        address_space=AddressSpace.SHARED]()\n    var tid = thread_idx.x\n    sums[tid] = input[block_idx.x * block_dim.x + tid]\n    barrier()\n\n    # Tree reduction in shared memory\n    var active = block_dim.x\n    comptime for _ in range(log2_steps):\n        active >>= 1\n        if tid \u003C active:\n            sums[tid] += sums[tid + active]\n        barrier()\n\n    # Final warp reduction + atomic accumulate\n    if tid \u003C UInt(WARP_SIZE):\n        var v = warp.sum(sums[tid][0])\n        if tid == 0:\n            _ = Atomic.fetch_add(output, v)\n```\n\n## DeviceBuffer from existing pointer\n\n```mojo\n# Wrap an existing pointer as a DeviceBuffer (non-owning)\nvar buf = DeviceBuffer[dtype](ctx, raw_ptr, count, owning=False)\n```\n\n## Benchmarking GPU kernels\n\n```mojo\nfrom std.benchmark import Bench, BenchConfig, Bencher, BenchId, BenchMetric, ThroughputMeasure\n\n@parameter\n@always_inline\ndef bench_fn(mut b: Bencher) capturing raises:\n    @parameter\n    @always_inline\n    def launch(ctx: DeviceContext) raises:\n        ctx.enqueue_function[kernel, kernel](args, grid_dim=G, block_dim=B)\n    b.iter_custom[launch](ctx)\n\nvar bench = Bench(BenchConfig(max_iters=50000))\nbench.bench_function[bench_fn](\n    BenchId(\"kernel_name\"),\n    [ThroughputMeasure(BenchMetric.bytes, total_bytes)],\n)\n```\n\n## Hardware details\n\n| Property | NVIDIA | AMD CDNA | AMD RDNA |\n|---|---|---|---|\n| Warp size | 32 | 64 | 32 |\n| Shared memory | 48-228 KB\u002Fblock | 64 KB\u002Fblock | configurable |\n| Tensor cores | SM70+ (WMMA) | Matrix cores | WMMA (RDNA3+) |\n| TMA | SM90+ (Hopper) | N\u002FA | N\u002FA |\n| Clusters | SM90+ | N\u002FA | N\u002FA |\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FHarmeet10000\u002Fskills\u002Fmojo-gpu-fundamentals",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":48,"prompt":58,"zipAvailable":59},[49,52,55],{"tool":50,"command":51},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill mojo-gpu-fundamentals",{"tool":53,"command":54},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill mojo-gpu-fundamentals",{"tool":56,"command":57},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill mojo-gpu-fundamentals","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FHarmeet10000\u002Fskills\u002Fmojo-gpu-fundamentals\u002FSKILL.md",true,[61,67,71,75,79,83],{"path":62,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":65,"sourceHtmlUrl":66},"agents\u002Fopenai.yaml","REFERENCE","参考文档",722,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fexpo-ui\u002Fagents\u002Fopenai.yaml",{"path":68,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":69,"sourceHtmlUrl":70},"references\u002Fdrop-in-replacements.md",2085,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fexpo-ui\u002Freferences\u002Fdrop-in-replacements.md",{"path":72,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":73,"sourceHtmlUrl":74},"references\u002Fjetpack-compose.md",5517,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fexpo-ui\u002Freferences\u002Fjetpack-compose.md",{"path":76,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":77,"sourceHtmlUrl":78},"references\u002Fswift-ui.md",4397,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fexpo-ui\u002Freferences\u002Fswift-ui.md",{"path":80,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":81,"sourceHtmlUrl":82},"references\u002Funiversal.md",3436,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fexpo-ui\u002Freferences\u002Funiversal.md",{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"scripts\u002Flist-components.js","SCRIPT","脚本",7343,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fexpo-ui\u002Fscripts\u002Flist-components.js",[90,104,114,123,129,136],{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":100,"publishedAt":33},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[95],{"categoryNo":96,"categoryName":97,"taxonomyType":98,"taxonomyTypeDesc":99},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[101,102,103],"model","model hierarchy","model hierarchy skill",{"skillNo":105,"name":106,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":110,"publishedAt":33},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[109],{"categoryNo":96,"categoryName":97,"taxonomyType":98,"taxonomyTypeDesc":99},[111,112,113],"MCP","zoom","zoom mcp",{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":33},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[120,121,122,112],"sdk","zoom apps sdk","apps",{"skillNo":124,"name":125,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":128,"publishedAt":33},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[125],{"skillNo":130,"name":131,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":135,"publishedAt":33},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[134],{"categoryNo":96,"categoryName":97,"taxonomyType":98,"taxonomyTypeDesc":99},[131],{"skillNo":137,"name":138,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":141,"publishedAt":33},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[138]]