runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "cumsum",
  "category": "math/reduction",
  "keywords": [
    "cumsum",
    "cumulative sum",
    "running total",
    "reverse",
    "omitnan",
    "gpu"
  ],
  "summary": "Cumulative sum of scalars, vectors, matrices, or N-D tensors.",
  "references": [],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [
      "f32",
      "f64"
    ],
    "broadcasting": "matlab",
    "notes": "Falls back to host accumulation when the active provider lacks prefix-sum hooks. Result shape always matches the input."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 1,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::math::reduction::cumsum::tests",
    "integration": "builtins::math::reduction::cumsum::tests::cumsum_gpu_provider_roundtrip"
  },
  "description": "`cumsum(X)` computes the cumulative sum of the elements in `X`. The result has the same size as `X` and each element stores the running total along a chosen dimension.",
  "behaviors": [
    "By default, the running total is taken along the first dimension whose length is greater than 1.",
    "`cumsum(X, dim)` lets you pick the dimension explicitly; if `dim > ndims(X)`, the input is returned unchanged.",
    "Passing `[]` for the dimension argument keeps the default dimension (MATLAB uses this as a placeholder).",
    "`cumsum(..., \"reverse\")` works from the end toward the beginning, whereas `\"forward\"` (default) works from start to finish.",
    "`cumsum(..., \"omitnan\")` treats `NaN` values as missing. Leading `NaN` values yield zeros until a valid number appears.",
    "Synonyms such as `\"omitmissing\"` / `\"includemissing\"` are also accepted for MATLAB compatibility.",
    "The function supports real or complex scalars and dense tensors. Logical inputs are promoted to double precision."
  ],
  "examples": [
    {
      "description": "Running totals down each column (default dimension)",
      "input": "A = [1 2 3; 4 5 6];\ncolumnTotals = cumsum(A)",
      "output": "columnTotals =\n     1     2     3\n     5     7     9"
    },
    {
      "description": "Tracking cumulative sums across rows",
      "input": "A = [1 2 3; 4 5 6];\nrowTotals = cumsum(A, 2)",
      "output": "rowTotals =\n     1     3     6\n     4     9    15"
    },
    {
      "description": "Reversing the direction of accumulation",
      "input": "v = [1 3 5 7];\nreverseTotals = cumsum(v, \"reverse\")",
      "output": "reverseTotals =\n    16    15    12     7"
    },
    {
      "description": "Ignoring NaN values while accumulating",
      "input": "v = [2 NaN 5 NaN 1];\nrunning = cumsum(v, \"omitnan\")",
      "output": "running =\n     2     2     7     7     8"
    },
    {
      "description": "Computing a cumulative sum inside a GPU workflow",
      "input": "G = gpuArray(rand(1, 5));\ntotals = cumsum(G);\nhostResult = gather(totals)"
    }
  ],
  "faqs": [
    {
      "question": "Does `cumsum` change the size of the input?",
      "answer": "No. The output is always the same size as the input tensor."
    },
    {
      "question": "What happens if I request a dimension larger than `ndims(X)`?",
      "answer": "The function returns `X` unchanged, matching MATLAB behaviour."
    },
    {
      "question": "How are complex numbers handled?",
      "answer": "`cumsum` accumulates the real and imaginary parts independently. NaN checks treat a complex number as missing if either part is `NaN`."
    },
    {
      "question": "What does `\"omitnan\"` do for leading `NaN` values?",
      "answer": "Leading `NaN` values contribute zeros so the running total remains 0 until a non-NaN value appears."
    },
    {
      "question": "Does `\"reverse\"` affect which dimension is used?",
      "answer": "No. Direction only decides whether accumulation walks from the start or from the end along the selected dimension."
    },
    {
      "question": "Can I combine `\"reverse\"` and `\"omitnan\"`?",
      "answer": "Yes. You can specify both options (in any order) and RunMat mirrors MATLAB’s results."
    },
    {
      "question": "Does the GPU path respect `\"omitnan\"`?",
      "answer": "If the active provider does not natively handle `\"omitnan\"`, RunMat gathers back to host and computes there to preserve MATLAB semantics."
    }
  ],
  "links": [
    {
      "label": "sum",
      "url": "./sum"
    },
    {
      "label": "cumprod",
      "url": "./cumprod"
    },
    {
      "label": "diff",
      "url": "./diff"
    },
    {
      "label": "mean",
      "url": "./mean"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "gather",
      "url": "./gather"
    },
    {
      "label": "all",
      "url": "./all"
    },
    {
      "label": "any",
      "url": "./any"
    },
    {
      "label": "cummax",
      "url": "./cummax"
    },
    {
      "label": "cummin",
      "url": "./cummin"
    },
    {
      "label": "max",
      "url": "./max"
    },
    {
      "label": "median",
      "url": "./median"
    },
    {
      "label": "min",
      "url": "./min"
    },
    {
      "label": "nnz",
      "url": "./nnz"
    },
    {
      "label": "prod",
      "url": "./prod"
    },
    {
      "label": "std",
      "url": "./std"
    },
    {
      "label": "var",
      "url": "./var"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/math/reduction/cumsum.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/math/reduction/cumsum.rs"
  },
  "gpu_residency": "Manual `gpuArray` calls are optional. RunMat promotes tensors automatically when the planner predicts a benefit, and it keeps fused expressions resident on the device. Explicit `gpuArray` is still supported for MATLAB compatibility or when you want to guarantee GPU residency before entering a critical loop.",
  "gpu_behavior": [
    "When a tensor already lives on the GPU, RunMat asks the active acceleration provider for a device-side prefix-sum implementation. The WGPU provider ships a native scan kernel; other providers may still fall back. If no hook is available, RunMat gathers the data to host memory, performs the cumulative sum on the CPU, and returns a dense tensor value. Residency metadata is cleared so later operations can re-promote the tensor when profitable."
  ]
}