runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "isnan",
  "category": "logical/tests",
  "keywords": [
    "isnan",
    "nan mask",
    "numeric predicate",
    "gpuArray isnan",
    "MATLAB isnan"
  ],
  "summary": "Return a logical mask indicating which elements of the input are NaN.",
  "references": [],
  "gpu_support": {
    "elementwise": true,
    "reduction": false,
    "precisions": [
      "f32",
      "f64"
    ],
    "broadcasting": "matlab",
    "notes": "Runs on the GPU when the provider exposes `logical_isnan`; otherwise data gathers to the host transparently."
  },
  "fusion": {
    "elementwise": true,
    "reduction": false,
    "max_inputs": 1,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::logical::tests::isnan::tests",
    "integration": "builtins::logical::tests::isnan::tests::isnan_gpu_roundtrip",
    "gpu": "builtins::logical::tests::isnan::tests::isnan_wgpu_matches_host_path"
  },
  "description": "`mask = isnan(x)` returns a logical scalar or array indicating which elements of `x` are IEEE NaN (Not-a-Number) values. The output matches MATLAB's semantics for scalars, matrices, higher-dimensional tensors, and gpuArray values.",
  "behaviors": [
    "Numeric scalars return a logical scalar (`true`/`false`).",
    "Numeric arrays return a logical array of the same size, with `true` wherever the corresponding element is `NaN`.",
    "Complex inputs report `true` when either the real or imaginary component is `NaN`.",
    "Logical inputs return `false` because logical values are finite by definition.",
    "Character arrays return logical arrays of zeros (characters map to finite code points).",
    "String arrays return logical arrays of zeros, mirroring MATLAB's behavior.",
    "`string` scalars (string objects) return a logical scalar `false`.",
    "When the input is a `gpuArray`, RunMat keeps the computation on the device if the active acceleration provider implements the `logical_isnan` hook; otherwise the runtime gathers the data back to the host automatically."
  ],
  "examples": [
    {
      "description": "Check if a scalar is NaN",
      "input": "result = isnan(NaN)",
      "output": "result =\n     1"
    },
    {
      "description": "Create a NaN mask for a numeric matrix",
      "input": "A = [1 NaN 2; 3 4 NaN];\nmask = isnan(A)",
      "output": "mask =\n  2×3 logical array\n     0     1     0\n     0     0     1"
    },
    {
      "description": "Identify NaNs inside a complex array",
      "input": "Z = [1+2i NaN+0i 3+NaNi];\nmask = isnan(Z)",
      "output": "mask =\n  1×3 logical array\n     0     1     1"
    },
    {
      "description": "Use `isnan` with character data",
      "input": "chars = ['R' 'u' 'n'];\nmask = isnan(chars)",
      "output": "mask =\n  1×3 logical array\n     0     0     0"
    },
    {
      "description": "Run `isnan` directly on the GPU",
      "input": "G = gpuArray([1 0/0 3]);\nmask_gpu = isnan(G);\nmask = gather(mask_gpu)",
      "output": "mask =\n  1×3 logical array\n     0     1     0"
    }
  ],
  "faqs": [
    {
      "question": "Does `isnan` modify the input array?",
      "answer": "No. It returns a logical mask and leaves the input unchanged, whether the data lives on the host or the GPU."
    },
    {
      "question": "How does `isnan` treat complex numbers?",
      "answer": "It returns `true` when either the real or the imaginary component of the element is `NaN`, matching MATLAB semantics."
    },
    {
      "question": "What does `isnan` return for logical inputs?",
      "answer": "Logical inputs always produce `false` because logical values (0 or 1) are finite."
    },
    {
      "question": "Does `isnan` support string or character arrays?",
      "answer": "Yes. Character arrays return logical zeros with the same shape. String arrays return logical zeros per element."
    },
    {
      "question": "What happens when `isnan` runs on a gpuArray without provider support?",
      "answer": "RunMat gathers the data to the host, computes the mask on the CPU, and returns a host logical array. This guarantees that the builtin never fails even when the GPU backend lacks the specialised kernel."
    },
    {
      "question": "Can I fuse `isnan` with other elementwise operations?",
      "answer": "Yes. The fusion planner treats `isnan` as an elementwise operation, so expressions like `isnan(A ./ B)` remain eligible for GPU fusion when the provider advertises support."
    },
    {
      "question": "Are there performance differences between `isnan` and `isfinite`/`isinf`?",
      "answer": "Each predicate performs a single elementwise test. Performance is dominated by memory bandwidth; all three functions have comparable cost on both CPU and GPU."
    },
    {
      "question": "How does `isnan` behave on empty arrays?",
      "answer": "It returns an empty logical array with the same size metadata as the input, matching MATLAB behavior."
    },
    {
      "question": "What does isnan do in MATLAB?",
      "answer": "`isnan(A)` returns a logical array the same size as `A`, with `true` where elements are `NaN` and `false` elsewhere. It works on real and complex arrays."
    },
    {
      "question": "How do I remove NaN values from an array in MATLAB?",
      "answer": "Use `A(isnan(A)) = []` to delete NaN elements from a vector, or `A(~isnan(A))` to select only non-NaN values. For matrices, use `any(isnan(A), 2)` to find rows containing NaN."
    },
    {
      "question": "Does isnan support GPU acceleration in RunMat?",
      "answer": "Yes. `isnan` runs on the GPU with elementwise fusion, meaning it can be combined with other operations without extra memory round-trips."
    }
  ],
  "links": [
    {
      "label": "isfinite",
      "url": "./isfinite"
    },
    {
      "label": "isinf",
      "url": "./isinf"
    },
    {
      "label": "isreal",
      "url": "./isreal"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "gather",
      "url": "./gather"
    },
    {
      "label": "isgpuarray",
      "url": "./isgpuarray"
    },
    {
      "label": "islogical",
      "url": "./islogical"
    },
    {
      "label": "isnumeric",
      "url": "./isnumeric"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/logical/tests/isnan.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/logical/tests/isnan.rs"
  },
  "gpu_residency": "You usually do **not** need to call `gpuArray` explicitly. RunMat's auto-offload planner keeps tensors on the GPU across fused expressions when that improves performance. You can still seed residency manually with `gpuArray` for compatibility with MATLAB scripts or when you want fine-grained control over data movement.",
  "gpu_behavior": [
    "When RunMat Accelerate is active, `isnan` looks for the provider hook `logical_isnan`. Providers that implement the hook execute the NaN test entirely on the GPU, producing a logical gpuArray result without any host transfers. If the hook is absent, RunMat gathers the input tensor back to the CPU, computes the mask on the host, and returns a regular logical array so the builtin always succeeds."
  ]
}