runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "isempty",
  "category": "array/introspection",
  "keywords": [
    "isempty",
    "empty array",
    "metadata query",
    "gpu",
    "logical"
  ],
  "summary": "Return true when an array has zero elements, matching MATLAB semantics.",
  "references": [],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [],
    "broadcasting": "none",
    "notes": "Reads tensor metadata from handles; falls back to gathering only when provider metadata is absent."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 0,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::array::introspection::isempty::tests",
    "integration": "builtins::array::introspection::isempty::tests::isempty_gpu_tensor_respects_shape"
  },
  "description": "`isempty(A)` returns logical `true` when the MATLAB value `A` contains zero elements. It mirrors MATLAB's behaviour across numeric arrays, logical arrays, character arrays, string arrays, cell arrays, structs, GPU tensors, and handle-like values.",
  "behaviors": [
    "Arrays are empty when any dimension is zero (`prod(size(A)) == 0`).",
    "Character arrays report empty when either dimension is zero. String scalars are never empty (`\"\"` is a `1×1` string array whose content may be empty, but it still counts as one element).",
    "Cell arrays, struct arrays, and tables (future work) follow their MATLAB dimensions; `cell(0, n)` is empty, while `cell(1, 1)` is not.",
    "Scalars, logical values, numeric scalars, function handles, objects, and handle objects always return `false` because they occupy one element.",
    "GPU tensors rely on device-provided shape metadata to avoid unnecessary transfers. If metadata is missing, RunMat gathers once to confirm the shape."
  ],
  "examples": [
    {
      "description": "Checking if a matrix has any elements",
      "input": "A = zeros(0, 3);\ntf = isempty(A)",
      "output": "tf = logical(1)"
    },
    {
      "description": "Detecting an empty cell array",
      "input": "C = cell(0, 4);\ntf = isempty(C)",
      "output": "tf = logical(1)"
    },
    {
      "description": "Using `isempty` on a GPU-resident tensor",
      "input": "G = gpuArray(zeros(5, 0));\ntf = isempty(G)",
      "output": "tf = logical(1)"
    },
    {
      "description": "Distinguishing char arrays from string scalars",
      "input": "chars = '';\ntf_chars = isempty(chars);\nstr = \"\";\ntf_str = isempty(str)",
      "output": "tf_chars = logical(1)\ntf_str = logical(0)"
    },
    {
      "description": "Confirming that scalars are never empty",
      "input": "value = 42;\ntf = isempty(value)",
      "output": "tf = logical(0)"
    },
    {
      "description": "Inspecting empty string arrays",
      "input": "S = strings(0, 2);\ntf = isempty(S)",
      "output": "tf = logical(1)"
    }
  ],
  "faqs": [
    {
      "question": "Does `isempty` gather GPU data?",
      "answer": "Only when the provider fails to populate shape metadata on the GPU handle. Otherwise, it answers using the metadata and avoids transfers."
    },
    {
      "question": "Why is `isempty(\"\")` false but `isempty('')` true?",
      "answer": "String scalars are `1×1` arrays that hold text content, so they are not empty even when the text has length zero. Character arrays store individual characters; the empty char literal `''` has zero columns, so it is empty."
    },
    {
      "question": "How does `isempty` treat structs and objects?",
      "answer": "Structs follow their array dimensions. A scalar struct (`1×1`) is not empty, while a `0×0` struct array is empty. Value objects and handle objects are always treated as scalar values, so `isempty` returns `false`."
    },
    {
      "question": "Can `isempty` be used inside GPU-fused expressions?",
      "answer": "Yes. The builtin returns a host logical scalar and does not allocate GPU buffers, so fusion plans remain valid."
    },
    {
      "question": "Does `isempty` look inside cell arrays?",
      "answer": "No. It only checks the container dimensions. To look at the contents, inspect individual cells."
    },
    {
      "question": "What does `isempty` return for logical or numeric scalars?",
      "answer": "They behave like any other scalar and return `false`."
    }
  ],
  "links": [
    {
      "label": "numel",
      "url": "./numel"
    },
    {
      "label": "size",
      "url": "./size"
    },
    {
      "label": "length",
      "url": "./length"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "gather",
      "url": "./gather"
    },
    {
      "label": "ismatrix",
      "url": "./ismatrix"
    },
    {
      "label": "isscalar",
      "url": "./isscalar"
    },
    {
      "label": "isvector",
      "url": "./isvector"
    },
    {
      "label": "ndims",
      "url": "./ndims"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/array/introspection/isempty.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/array/introspection/isempty.rs"
  },
  "gpu_behavior": [
    "`isempty` does not launch GPU kernels. For GPU-resident tensors (`gpuArray` values), RunMat inspects the shape stored in the `GpuTensorHandle`. When the active provider omits that metadata, the runtime downloads the tensor once to maintain MATLAB-compatible results. The builtin always returns a host logical scalar and does not allocate device memory, so it is safe in fused GPU expressions."
  ]
}