sparse-delta-memory 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. sparse_delta_memory/__init__.py +13 -0
  2. sparse_delta_memory/backward.py +367 -0
  3. sparse_delta_memory/cache.py +70 -0
  4. sparse_delta_memory/cuda/__init__.py +3 -0
  5. sparse_delta_memory/cuda/_build.py +254 -0
  6. sparse_delta_memory/cuda/_device.py +158 -0
  7. sparse_delta_memory/cuda/_devmemo.py +64 -0
  8. sparse_delta_memory/cuda/_image.py +128 -0
  9. sparse_delta_memory/cuda/bwd_steps_cuda.py +111 -0
  10. sparse_delta_memory/cuda/gather_cuda.py +796 -0
  11. sparse_delta_memory/cuda/gather_ns_cuda.py +134 -0
  12. sparse_delta_memory/cuda/gx_gds_cuda.py +1297 -0
  13. sparse_delta_memory/cuda/gx_gemm_cuda.py +857 -0
  14. sparse_delta_memory/cuda/gx_pa2_cuda.py +1320 -0
  15. sparse_delta_memory/cuda/mover_da2_cuda.py +1802 -0
  16. sparse_delta_memory/cuda/mover_fx_cuda.py +2229 -0
  17. sparse_delta_memory/cuda/pa_dc_cuda.py +1500 -0
  18. sparse_delta_memory/cuda/phase1_bwd_cuda.py +852 -0
  19. sparse_delta_memory/cuda/phase1_common.cuh +181 -0
  20. sparse_delta_memory/cuda/phase1_cuda.py +3801 -0
  21. sparse_delta_memory/cuda/product_key_topk_anyf_cuda.py +668 -0
  22. sparse_delta_memory/cuda/product_key_topk_cuda.py +735 -0
  23. sparse_delta_memory/cuda/px_qrec_cuda.py +167 -0
  24. sparse_delta_memory/cuda/sdm_copy.cuh +90 -0
  25. sparse_delta_memory/cuda/sdm_plancap.cuh +150 -0
  26. sparse_delta_memory/cuda_graph.py +605 -0
  27. sparse_delta_memory/decode.py +140 -0
  28. sparse_delta_memory/forward.py +464 -0
  29. sparse_delta_memory/layer.py +663 -0
  30. sparse_delta_memory/memory_ops.py +1069 -0
  31. sparse_delta_memory/memory_stats.py +221 -0
  32. sparse_delta_memory/movers.py +198 -0
  33. sparse_delta_memory/phase2_kernels.py +267 -0
  34. sparse_delta_memory/product_key_topk.py +113 -0
  35. sparse_delta_memory/wy_solve.py +273 -0
  36. sparse_delta_memory-2.0.0.dist-info/METADATA +482 -0
  37. sparse_delta_memory-2.0.0.dist-info/RECORD +40 -0
  38. sparse_delta_memory-2.0.0.dist-info/WHEEL +5 -0
  39. sparse_delta_memory-2.0.0.dist-info/licenses/LICENSE +407 -0
  40. sparse_delta_memory-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,111 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ """bwd_steps_cuda: the deterministic backward's chunk-step loop in ONE C++ call: every launcher planned once per backward
3
+ (sdm_plancap.cuh), then the same kernels, parameters, launch attributes and order on the same stream."""
4
+
5
+ import functools
6
+
7
+ import torch
8
+
9
+ from ._build import load_cuda_extension
10
+
11
+ _CPP = r"""
12
+ void bwd_steps(at::Tensor gwr_plan, int64_t gwr_addr, at::Tensor gemm_plan, int64_t gemm_addr,
13
+ at::Tensor pa_plan, int64_t pa_addr, at::Tensor gds_plan, int64_t gds_addr, int64_t nt,
14
+ int64_t gwr_pdl, int64_t gemm_use, int64_t gds_use, int64_t device,
15
+ at::Tensor d_u4, at::Tensor x_t4, at::Tensor d_dv4);
16
+ """
17
+
18
+ _CUDA = r"""
19
+ #include <torch/extension.h>
20
+ #include <ATen/ATen.h>
21
+ #include <ATen/cuda/CUDAContext.h>
22
+ #include <c10/cuda/CUDAGuard.h>
23
+ #include <cstdint>
24
+ #include <limits>
25
+
26
+ namespace {
27
+ // A planned launcher's step entry point: (plan bytes, plan size, step, pdl, cudaStream_t) -> 0 or an error code.
28
+ using PlanLaunch = int64_t (*)(const void*, int64_t, int64_t, int64_t, void*);
29
+
30
+ void check_plan(const at::Tensor& p, const char* what) {
31
+ TORCH_CHECK(p.device().is_cpu() && p.scalar_type() == at::kByte && p.dim() == 1 && p.is_contiguous() &&
32
+ p.numel() > 0, "bwd_steps: the ", what, " plan must be a contiguous 1-D CPU uint8 tensor");
33
+ }
34
+ } // namespace
35
+
36
+ // For ti = nt - 1 .. 0: gwr(ti) [PDL iff ti < nt - 1 and gwr_pdl], the d_u update (the GEMM plan with gemm_use, or cuBLAS
37
+ // baddbmm_out when gemm_addr == 0), pa(ti) [its mode is fixed by its plan], gds(ti) [gds_use]: the backward loop's calls,
38
+ // in its order, on the current stream of `device` (the stream each per-step call uses). A failing launch raises; the
39
+ // launches already issued stay issued, as with a failing per-step call.
40
+ void bwd_steps(at::Tensor gwr_plan, int64_t gwr_addr, at::Tensor gemm_plan, int64_t gemm_addr,
41
+ at::Tensor pa_plan, int64_t pa_addr, at::Tensor gds_plan, int64_t gds_addr, int64_t nt,
42
+ int64_t gwr_pdl, int64_t gemm_use, int64_t gds_use, int64_t device,
43
+ at::Tensor d_u4, at::Tensor x_t4, at::Tensor d_dv4) {
44
+ check_plan(gwr_plan, "gwr");
45
+ check_plan(pa_plan, "pa");
46
+ check_plan(gds_plan, "gds");
47
+ TORCH_CHECK(gwr_addr != 0 && pa_addr != 0 && gds_addr != 0, "bwd_steps: launcher entry points");
48
+ TORCH_CHECK(nt >= 1 && nt <= std::numeric_limits<int32_t>::max(), "bwd_steps: steps");
49
+ TORCH_CHECK((gwr_pdl == 0 || gwr_pdl == 1) && (gemm_use == 0 || gemm_use == 1) && (gds_use == 0 || gds_use == 1),
50
+ "bwd_steps: pdl flags 0 / 1");
51
+ const bool blas = gemm_addr == 0;
52
+ if (blas) {
53
+ TORCH_CHECK(d_u4.dim() == 4 && x_t4.dim() == 4 && d_dv4.dim() == 4 && d_u4.size(0) >= nt && x_t4.size(0) >= nt &&
54
+ d_dv4.size(0) >= nt, "bwd_steps: cuBLAS step views [Nt, P, *, *]");
55
+ } else {
56
+ check_plan(gemm_plan, "gemm");
57
+ }
58
+ const c10::cuda::CUDAGuard guard(static_cast<c10::DeviceIndex>(device));
59
+ const cudaStream_t stream = at::cuda::getCurrentCUDAStream().stream();
60
+ void* const st = static_cast<void*>(stream);
61
+ const PlanLaunch gwr = reinterpret_cast<PlanLaunch>(gwr_addr);
62
+ const PlanLaunch gemm = blas ? nullptr : reinterpret_cast<PlanLaunch>(gemm_addr);
63
+ const PlanLaunch pa = reinterpret_cast<PlanLaunch>(pa_addr);
64
+ const PlanLaunch gds = reinterpret_cast<PlanLaunch>(gds_addr);
65
+ const void* gwp = gwr_plan.data_ptr();
66
+ const void* gmp = blas ? nullptr : gemm_plan.data_ptr();
67
+ const void* pap = pa_plan.data_ptr();
68
+ const void* gdp = gds_plan.data_ptr();
69
+ const int64_t gwn = gwr_plan.numel(), gmn = blas ? 0 : gemm_plan.numel(), pan = pa_plan.numel(),
70
+ gdn = gds_plan.numel();
71
+ for (int64_t ti = nt - 1; ti >= 0; --ti) {
72
+ int64_t rc = gwr(gwp, gwn, ti, (ti < nt - 1 && gwr_pdl) ? 1 : 0, st);
73
+ TORCH_CHECK(rc == 0, "bwd_steps: dc_gwr step ", ti, " failed (", rc, ")");
74
+ if (blas) {
75
+ at::Tensor u = d_u4.select(0, ti);
76
+ at::baddbmm_out(u, u, x_t4.select(0, ti), d_dv4.select(0, ti));
77
+ } else {
78
+ rc = gemm(gmp, gmn, ti, gemm_use, st);
79
+ TORCH_CHECK(rc == 0, "bwd_steps: gx_gemm step ", ti, " failed (", rc, ")");
80
+ }
81
+ rc = pa(pap, pan, ti, 0, st);
82
+ TORCH_CHECK(rc == 0, "bwd_steps: gx_pa2 step ", ti, " failed (", rc, ")");
83
+ rc = gds(gdp, gdn, ti, gds_use, st);
84
+ TORCH_CHECK(rc == 0, "bwd_steps: gx_gds step ", ti, " failed (", rc, ")");
85
+ }
86
+ }
87
+ """
88
+
89
+
90
+ @functools.cache
91
+ def _module():
92
+ return load_cuda_extension(
93
+ "sdm_bwd_steps",
94
+ cpp_sources=_CPP,
95
+ cuda_sources=_CUDA,
96
+ functions=("bwd_steps",),
97
+ extra_cuda_cflags=("-O3",),
98
+ )
99
+
100
+
101
+ def run(gwr, gemm, pa, gds, *, steps, gwr_pdl, gemm_use, gds_use, device, blas_views=None):
102
+ """Issue steps steps - 1 .. 0 (gwr / pa / gds / gemm: (plan, address); gemm None: cuBLAS on blas_views)."""
103
+ idx = device.index if device.index is not None else torch.cuda.current_device()
104
+ if gemm is None:
105
+ gplan, gaddr = torch.empty(0, dtype=torch.uint8), 0
106
+ d_u4, x_t4, d_dv4 = blas_views
107
+ else:
108
+ gplan, gaddr = gemm
109
+ d_u4 = x_t4 = d_dv4 = torch.empty(0, device=device, dtype=torch.float32)
110
+ _module().bwd_steps(gwr[0], int(gwr[1]), gplan, int(gaddr), pa[0], int(pa[1]), gds[0], int(gds[1]), int(steps),
111
+ int(gwr_pdl), int(gemm_use), int(gds_use), int(idx), d_u4, x_t4, d_dv4)